* @license GPL-2.0+ * @link https://github.com/madalinungureanu/user-profile-picture * * @since 1.0.0 */ class Metronet_Profile_Picture { /** * Defines the plugin URL * * @since 1.0.0 * @access private * @var string $plugin_url */ private $plugin_url = ''; /** * Defines the plugin absolute directory * * @since 1.0.0 * @access private * @var string $plugin_dir */ private $plugin_dir = ''; /** * Defines the plugin path * * @since 1.0.0 * @access private * @var string $plugin_path */ private $plugin_path = ''; /** * __construct() * * Class constructor */ public function __construct() { load_plugin_textdomain( 'metronet-profile-picture', false, dirname( plugin_basename( __FILE__ ) ) . '/languages/' ); $this->plugin_path = plugin_basename( __FILE__ ); $this->plugin_url = rtrim( plugin_dir_url( __FILE__ ), '/' ); $this->plugin_dir = rtrim( plugin_dir_path( __FILE__ ), '/' ); add_action( 'init', array( $this, 'init' ) ); add_action( 'personal_options', array( $this, 'insert_upload_form' ) ); // Scripts. add_action( 'admin_print_scripts-user-edit.php', array( $this, 'print_media_scripts' ) ); add_action( 'admin_print_scripts-profile.php', array( $this, 'print_media_scripts' ) ); add_action( 'wp_enqueue_scripts', array( $this, 'profile_print_media_scripts' ), 9 ); add_action( 'acf/input/admin_enqueue_scripts', array( $this, 'profile_print_media_scripts' ), 9 ); // Advanced Custom Field compatibility. // Styles. add_action( 'admin_print_styles-user-edit.php', array( $this, 'print_media_styles' ) ); add_action( 'admin_print_styles-profile.php', array( $this, 'print_media_styles' ) ); // Ajax. add_action( 'wp_ajax_metronet_add_thumbnail', array( $this, 'ajax_add_thumbnail' ) ); add_action( 'wp_ajax_metronet_get_thumbnail', array( $this, 'ajax_get_thumbnail' ) ); add_action( 'wp_ajax_metronet_remove_thumbnail', array( $this, 'ajax_remove_thumbnail' ) ); // User update action. add_action( 'edit_user_profile_update', array( $this, 'save_user_profile' ) ); add_action( 'personal_options_update', array( $this, 'save_user_profile' ) ); // User Avatar override. add_filter( 'get_avatar', array( $this, 'avatar_override' ), 10, 6 ); add_filter( 'pre_get_avatar_data', array( $this, 'pre_avatar_override' ), 10, 2 ); // Rest API. add_action( 'rest_api_init', array( $this, 'rest_api_register' ) ); // Avatar check overridden - Can be overridden using a higher priority. add_filter( 'mpp_hide_avatar_override', '__return_true', 5 ); // Determine if to load Gutenberg or not. $options = $this->get_options(); if ( 'on' === $options['load_gutenberg'] ) { // Include Gutenberg. add_filter( 'block_categories', array( $this, 'add_block_category' ), 10, 2 ); include_once self::get_plugin_dir( '/gutenberg/class-gutenberg.php' ); new Metronet_Profile_Picture_Gutenberg(); } } //end constructor /** * Add a User Profile Picture category for block creation. * * @since 2.3.0 * * @param array $categories Array of available categories. * @param object $post Post to attach it to. * * @return array New Categories */ public function add_block_category( $categories, $post ) { return array_merge( $categories, array( array( 'slug' => 'mpp', 'title' => __( 'User Profile Picture', 'metronet-profile-picture' ), 'icon' => 'groups', ), ) ); } /** * Register the settings menu for User Profile Picture * * @since 2.3.0 */ public function register_settings_menu() { if ( defined( 'USER_PROFILE_PICTURE_ENHANCED' ) ) { $hook = add_menu_page( __( 'User Profile Picture', 'metronet-profile-picture' ), __( 'User Profile Picture', 'metronet-profile-picture' ), 'manage_options', 'mpp', array( $this, 'admin_page' ), 'dashicons-groups', 100 ); } else { $hook = add_options_page( __( 'User Profile Picture', 'metronet-profile-picture' ), __( 'User Profile Picture', 'metronet-profile-picture' ), 'manage_options', 'mpp', array( $this, 'admin_page' ) ); } } /** * Admin page for User Profile Picture * * @since 2.3.0 */ public function admin_page() { if ( isset( $_POST['submit'] ) && isset( $_POST['options'] ) ) { check_admin_referer( 'save_mpp_options' ); $options = wp_unslash( $_POST['options'] ); // phpcs:ignore $this->update_options( $options ); printf( '

%s

', esc_html__( 'Your options have been saved.', 'metronet-profile-picture' ) ); } // Get options and defaults. $options = $this->get_options(); ?>

upp

/>

/>

get_defaults(); } elseif ( is_array( $options ) ) { $options = wp_parse_args( $options, $this->get_defaults() ); } else { $options = $this->get_defaults(); } return $options; } /** * Update options via sanitization * * @since 2.3.0 * @access public * @param array $options array of options to save. * @return void */ public function update_options( $options ) { foreach ( $options as $key => &$option ) { switch ( $key ) { default: $option = sanitize_text_field( $options[ $key ] ); break; } } /** * Allow other plugins to perform their own sanitization functions. * * @since 2.3.0 * * @param array $options An array of sanitized POST options */ $options = apply_filters( 'mpp_options_sanitized', $options ); update_option( 'mpp_options', $options ); } /** * Get the default options for User Profile Picture * * @access private * * @since 2.3.0 */ private function get_defaults() { $defaults = array( 'load_gutenberg' => 'on', 'disable_image_sizes' => 'off', ); /** * Allow other plugins to add to the defaults. * * @since 2.3.1 * * @param array $defaults An array of option defaults. */ $defaults = apply_filters( 'mpp_options_defaults', $defaults ); return $defaults; } /** * Add a thumbnail via Ajax. * * Adds a thumbnail to user meta and returns thumbnail html. */ public function ajax_add_thumbnail() { if ( ! current_user_can( 'upload_files' ) ) { die( '' ); } $post_id = isset( $_POST['post_id'] ) ? absint( $_POST['post_id'] ) : 0; $user_id = isset( $_POST['user_id'] ) ? absint( $_POST['user_id'] ) : 0; $thumbnail_id = isset( $_POST['thumbnail_id'] ) ? absint( $_POST['thumbnail_id'] ) : 0; if ( 0 === $post_id || 0 === $user_id || 0 === $thumbnail_id || 'mt_pp' !== get_post_type( $post_id ) ) { die( '' ); } check_ajax_referer( "mt-update-post_$user_id" ); // Save user meta. update_user_option( $user_id, 'metronet_post_id', $post_id ); update_user_option( $user_id, 'metronet_image_id', $thumbnail_id ); // Added via this thread (Props Solinx) - https://wordpress.org/support/topic/storing-image-id-directly-as-user-meta-data. set_post_thumbnail( $post_id, $thumbnail_id ); if ( has_post_thumbnail( $post_id ) ) { $thumb_src = wp_get_attachment_image_src( get_post_thumbnail_id( $post_id ), 'thumbnail', false, '' ); $post_thumbnail = sprintf( '', esc_url( $thumb_src[0] ), esc_attr__( 'Upload or Change Profile Picture', 'metronet-profile-picture' ) ); $crop_html = $this->get_post_thumbnail_editor_link( $post_id ); $thumb_html = sprintf( '%s%s', $post_thumbnail, sprintf( '
%s
', esc_html__( 'Click to Edit', 'metronet-profile-picture' ) ) ); $thumb_html .= sprintf( '%s', esc_attr__( 'Remove profile image', 'metronet-profile-picture' ), esc_html__( 'Remove profile image', 'metronet-profile-picture' ) ); wp_send_json( array( 'thumb_html' => $thumb_html, 'crop_html' => $crop_html, 'has_thumb' => true, 'avatar' => get_avatar( $user_id, 96 ), 'avatar_admin_small' => get_avatar( $user_id, 26 ), 'avatar_admin_medium' => get_avatar( $user_id, 64 ), 'user_id' => $user_id, 'logged_in_user_id' => get_current_user_id(), ) ); } wp_send_json( array( 'thumb_html' => '', 'crop_html' => '', 'has_thumb' => false, 'avatar' => get_avatar( $user_id, 96 ), 'avatar_admin_small' => get_avatar( $user_id, 26 ), 'avatar_admin_medium' => get_avatar( $user_id, 64 ), 'user_id' => $user_id, 'logged_in_user_id' => get_current_user_id(), ) ); } //end ajax_add_thumbnail /** * Retrieve a thumbnail via Ajax. * * Retrieves a thumbnail based on a passed post id ($_POST) */ public function ajax_get_thumbnail() { if ( ! current_user_can( 'upload_files' ) ) { die( '' ); } $user_id = isset( $_POST['user_id'] ) ? absint( $_POST['user_id'] ) : 0; $post_id = isset( $_POST['post_id'] ) ? absint( $_POST['post_id'] ) : 0; check_ajax_referer( "mt-update-post_$user_id" ); $post = get_post( $post_id ); $user_id = 0; if ( $post ) { $user_id = $post->post_author; } if ( has_post_thumbnail( $post_id ) ) { $thumb_src = wp_get_attachment_image_src( get_post_thumbnail_id( $post_id ), 'thumbnail', false, '' ); $post_thumbnail = sprintf( '', esc_url( $thumb_src[0] ), esc_attr__( 'Upload or Change Profile Picture', 'metronet-profile-picture' ) ); $crop_html = $this->get_post_thumbnail_editor_link( $post_id ); $thumb_html = sprintf( '%s%s', $post_thumbnail, sprintf( '
%s
', esc_html__( 'Click to Edit', 'metronet-profile-picture' ) ) ); $thumb_html .= sprintf( '%s', esc_attr__( 'Remove profile image', 'metronet-profile-picture' ), esc_html__( 'Remove profile image', 'metronet-profile-picture' ) ); wp_send_json( array( 'thumb_html' => $thumb_html, 'crop_html' => $crop_html, 'has_thumb' => true, 'avatar' => get_avatar( $user_id, 96 ), 'avatar_admin_small' => get_avatar( $user_id, 26 ), 'avatar_admin_medium' => get_avatar( $user_id, 64 ), 'user_id' => $user_id, 'logged_in_user_id' => get_current_user_id(), ) ); } else { $thumb_html = ''; $thumb_html .= sprintf( '', self::get_plugin_url( 'img/mystery.png' ), esc_attr__( 'Upload or Change Profile Picture', 'metronet-profile-picture' ) ); $thumb_html .= sprintf( '
%s
', esc_html__( 'Click to Edit', 'metronet-profile-picture' ) ); $thumb_html .= '
'; } wp_send_json( array( 'thumb_html' => $thumb_html, 'crop_html' => '', 'has_thumb' => false, 'avatar' => get_avatar( $user_id, 96 ), 'avatar_admin_small' => get_avatar( $user_id, 26 ), 'avatar_admin_medium' => get_avatar( $user_id, 64 ), 'user_id' => $user_id, 'logged_in_user_id' => get_current_user_id(), ) ); } /** * Remove a thumbnail via Ajax. * * Removes a featured thumbnail. */ public function ajax_remove_thumbnail() { if ( ! current_user_can( 'upload_files' ) ) { die( '' ); } $post_id = isset( $_POST['post_id'] ) ? absint( $_POST['post_id'] ) : 0; $user_id = isset( $_POST['user_id'] ) ? absint( $_POST['user_id'] ) : 0; if ( 0 === $post_id || 0 === $user_id ) { die( '' ); } check_ajax_referer( "mt-update-post_$user_id" ); $thumb_html = ''; $thumb_html .= sprintf( '', self::get_plugin_url( 'img/mystery.png' ), esc_attr__( 'Upload or Change Profile Picture', 'metronet-profile-picture' ) ); $thumb_html .= sprintf( '
%s
', esc_html__( 'Click to Edit', 'metronet-profile-picture' ) ); $thumb_html .= '
'; // Save user meta and update thumbnail. update_user_option( $user_id, 'metronet_image_id', 0 ); delete_post_meta( $post_id, '_thumbnail_id' ); wp_send_json( array( 'thumb_html' => $thumb_html, 'crop_html' => '', 'has_thumb' => false, 'avatar' => get_avatar( $user_id, 96 ), 'avatar_admin_small' => get_avatar( $user_id, 26 ), 'avatar_admin_medium' => get_avatar( $user_id, 64 ), 'user_id' => $user_id, 'logged_in_user_id' => get_current_user_id(), ) ); } /** * Override an Avatar with a User Profile Picture. * * Overrides an avatar with a profile image * * @param string $avatar SRC to the avatar. * @param mixed $id_or_email The ID or email address. * @param int $size Size of the image. * @param string $default URL to the default image. * @param string $alt Alternative text. * @param array $args Misc. args for the avatar. * * @return string Avatar. */ public function avatar_override( $avatar, $id_or_email, $size, $default, $alt, $args = array() ) { global $pagenow; if ( 'options-discussion.php' === $pagenow ) { return $avatar; // Stop overriding gravatars on options-discussion page. } // Get user data. if ( is_numeric( $id_or_email ) ) { $user = get_user_by( 'id', (int) $id_or_email ); } elseif ( is_object( $id_or_email ) ) { $comment = $id_or_email; if ( empty( $comment->user_id ) ) { $user = get_user_by( 'id', $comment->user_id ); } else { $user = get_user_by( 'email', $comment->comment_author_email ); } if ( ! $user ) { return $avatar; } } elseif ( is_string( $id_or_email ) ) { $user = get_user_by( 'email', $id_or_email ); } else { return $avatar; } if ( ! $user ) { return $avatar; } $user_id = $user->ID; // Determine if user has an avatar override. $avatar_override = get_user_option( 'metronet_avatar_override', $user_id ); if ( ! $avatar_override || 'on' !== $avatar_override ) { return $avatar; } // Build classes array based on passed in args, else set defaults - see get_avatar in /wp-includes/pluggable.php. $classes = array( 'avatar', sprintf( 'avatar-%s', esc_attr( $size ) ), 'photo', ); if ( isset( $args['class'] ) ) { if ( is_array( $args['class'] ) ) { $classes = array_merge( $classes, $args['class'] ); } else { $args['class'] = explode( ' ', $args['class'] ); $classes = array_merge( $classes, $args['class'] ); } } // Get custom filter classes. $classes = (array) apply_filters( 'mpp_avatar_classes', $classes ); // Determine if the user has a profile image. $custom_avatar = mt_profile_img( $user_id, array( 'size' => array( $size, $size ), 'attr' => array( 'alt' => $alt, 'class' => implode( ' ', $classes ), ), 'echo' => false, ) ); if ( ! $custom_avatar ) { return $avatar; } return $custom_avatar; } /** * Overrides an avatar with a profile image * * @param array $args Arguments to determine the avatar dimensions. * @param mixed $id_or_email The ID or email address. * * @return array $args Overridden URL or default if none can be found **/ public function pre_avatar_override( $args, $id_or_email ) { // Get user data. if ( is_numeric( $id_or_email ) ) { $user = get_user_by( 'id', (int) $id_or_email ); } elseif ( is_object( $id_or_email ) ) { $comment = $id_or_email; if ( empty( $comment->user_id ) ) { $user = get_user_by( 'id', $comment->user_id ); } else { $user = get_user_by( 'email', $comment->comment_author_email ); } if ( ! $user ) { return $args; } } elseif ( is_string( $id_or_email ) ) { $user = get_user_by( 'email', $id_or_email ); } else { return $args; } if ( ! $user ) { return $args; } $user_id = $user->ID; // Get the post the user is attached to. $size = $args['size']; $profile_post_id = absint( get_user_option( 'metronet_post_id', $user_id ) ); if ( 0 === $profile_post_id ) { return $args; } $post_thumbnail_id = get_post_thumbnail_id( $profile_post_id ); // Attempt to get the image in the right size. $avatar_image = get_the_post_thumbnail_url( $profile_post_id, array( $size, $size ) ); if ( empty( $avatar_image ) ) { return $args; } $args['url'] = $avatar_image; return $args; } /** * Returns an absolute path to a plugin item * * @param string $path Relative path to make absolute (e.g., /css/image.png). * * @return string An absolute path (e.g., /htdocs/ithemes/wp-content/.../css/image.png) */ public static function get_plugin_dir( $path = '' ) { $dir = rtrim( plugin_dir_path( __FILE__ ), '/' ); if ( ! empty( $path ) && is_string( $path ) ) { $dir .= '/' . ltrim( $path, '/' ); } return $dir; } /** * Returns an absolute url to a plugin item * * @param string $path Relative path to plugin (e.g., /css/image.png). * @return string An absolute url (e.g., http://www.domain.com/plugin_url/.../css/image.png) */ public static function get_plugin_url( $path = '' ) { $dir = rtrim( plugin_dir_url( __FILE__ ), '/' ); if ( ! empty( $path ) && is_string( $path ) ) { $dir .= '/' . ltrim( $path, '/' ); } return $dir; } /** * Gets a post id for the user - Creates a post if a post doesn't exist * * @param int $user_id User ID of the user. * @return int post_id */ private function get_post_id( $user_id = 0 ) { $user = get_user_by( 'id', $user_id ); // Get/Create Profile Picture Post. $post_args = array( 'post_type' => 'mt_pp', 'author' => $user_id, 'post_status' => 'publish', ); $posts = get_posts( $post_args ); if ( ! $posts ) { $post_id = wp_insert_post( array( 'post_author' => $user_id, 'post_type' => 'mt_pp', 'post_status' => 'publish', 'post_title' => $user->data->display_name, ) ); } else { $post = end( $posts ); $post_id = $post->ID; } return $post_id; } /** * Retrieve a crop-image link (HTML) based on the passed post_id * * @param int $post_id Post ID to find the featured image for. * @return string html */ private function get_post_thumbnail_editor_link( $post_id ) { ob_start(); if ( has_post_thumbnail( $post_id ) && defined( 'PTE_VERSION' ) ) { // Post Thumbnail Editor compatibility - http://wordpress.org/extend/plugins/post-thumbnail-editor/. $post_thumbnail_id = get_post_meta( $post_id, '_thumbnail_id', true ); $pte_url = add_query_arg( array( 'page' => 'pte-edit', 'pte-id' => $post_thumbnail_id, ), admin_url( 'upload.php' ) ); printf( ' - %s', esc_url( $pte_url ), esc_html__( 'Crop Thumbnail', 'metronet-profile-picture' ) ); } return ob_get_clean(); } /** * Gets a user ID for the user. * * @return int user_id */ public function get_user_id() { // Get user ID. $user_id = isset( $_GET['user_id'] ) ? absint( $_GET['user_id'] ) : 0; // phpcs:ignore if ( 0 === $user_id && IS_PROFILE_PAGE ) { $current_user = wp_get_current_user(); $user_id = $current_user->ID; } return $user_id; } /** * Initializes plugin localization, post types, updaters, plugin info, and adds actions/filters */ public function init() { // For the admin interface. add_action( 'admin_menu', array( $this, 'register_settings_menu' ) ); add_action( 'plugin_action_links_' . METRONET_PROFILE_PICTURE_SLUG, array( $this, 'plugin_settings_link' ) ); add_theme_support( 'post-thumbnails' ); // This should be part of the theme, but the plugin registers it just in case. // Register post types. $post_type_args = array( 'public' => false, 'publicly_queryable' => false, 'show_ui' => false, 'show_in_menu' => false, 'query_var' => true, 'rewrite' => false, 'has_archive' => false, 'hierarchical' => false, 'supports' => array( 'thumbnail' ), ); /** * Allow other plugins to modify the post type creation arguments. * * @since 2.3.0 * * @param array Post type arguments prior to registering the post type. */ $post_type_args = apply_filters( 'mpp_post_type_args', $post_type_args ); register_post_type( 'mt_pp', $post_type_args ); // Determine if to load image sizes or not. $options = $this->get_options(); $display_image_sizes = true; if ( 'on' === $options['disable_image_sizes'] ) { $display_image_sizes = false; } /** * Filter the the creation of image sizes. * * @since 2.2.5 * * @param bool Whether to allow image size creation or not */ if ( apply_filters( 'mpp_add_image_sizes', $display_image_sizes ) ) { add_image_size( 'profile_24', 24, 24, true ); add_image_size( 'profile_48', 48, 48, true ); add_image_size( 'profile_96', 96, 96, true ); add_image_size( 'profile_150', 150, 150, true ); add_image_size( 'profile_300', 300, 300, true ); } } /** * Adds a plugin settings link. * * Adds a plugin settings link. * * @param array $settings The settings array for the plugin. * * @return array Settings array. */ public function plugin_settings_link( $settings ) { if ( defined( 'USER_PROFILE_PICTURE_ENHANCED' ) ) { $admin_anchor = sprintf( '%s', esc_url( admin_url( 'admin.php?page=mpp' ) ), esc_html__( 'Settings', 'metronet-profile-picture' ) ); } else { $admin_anchor = sprintf( '%s', esc_url( admin_url( 'options-general.php?page=mpp' ) ), esc_html__( 'Settings', 'metronet-profile-picture' ) ); } if ( ! is_array( $settings ) ) { return array( $admin_anchor ); } else { return array_merge( $settings, array( $admin_anchor ) ); } } /** * Adds an upload form to the user profile page and outputs profile image if there is one */ public function insert_upload_form() { if ( ! current_user_can( 'upload_files' ) ) { return; // Users must be author or greater. } $user_id = $this->get_user_id(); $post_id = $this->get_post_id( $user_id ); ?>
'; $thumb_src = wp_get_attachment_image_src( get_post_thumbnail_id( $post_id ), 'thumbnail', false, '' ); $post_thumbnail = sprintf( '', esc_url( $thumb_src[0] ), esc_attr__( 'Upload or Change Profile Picture', 'metronet-profile-picture' ) ); echo wp_kses_post( $post_thumbnail ); echo sprintf( '
%s
', esc_html__( 'Click to Edit', 'metronet-profile-picture' ) ); echo ''; } else { echo ''; $post_thumbnail = sprintf( '', self::get_plugin_url( 'img/mystery.png' ), esc_attr__( 'Upload or Change Profile Picture', 'metronet-profile-picture' ) ); echo wp_kses_post( $post_thumbnail ); echo sprintf( '
%s
', esc_html__( 'Click to Edit', 'metronet-profile-picture' ) ); echo '
'; } $remove_classes = array( 'dashicons', 'dashicons-trash' ); if ( ! $has_profile_image ) { $remove_classes[] = 'mpp-no-profile-image'; } ?>
', esc_url( self::get_plugin_url( '/img/loading.gif' ) ) ); ?>

/>
print_media_scripts(); } } /** * Output media scripts for thickbox and media uploader **/ public function print_media_scripts() { $post_id = $this->get_post_id( $this->get_user_id() ); $user_id = $this->get_user_id(); wp_enqueue_media( array( 'post' => $post_id ) ); $script_deps = array( 'media-editor' ); wp_enqueue_script( 'mt-pp', self::get_plugin_url( '/js/mpp.js' ), $script_deps, METRONET_PROFILE_PICTURE_VERSION, true ); wp_localize_script( 'mt-pp', 'metronet_profile_image', array( 'set_profile_text' => __( 'Set Profile Image', 'metronet-profile-picture' ), 'remove_profile_text' => __( 'Remove Profile Image', 'metronet-profile-picture' ), 'crop' => __( 'Crop Thumbnail', 'metronet-profile-picture' ), 'ajax_url' => esc_url( admin_url( 'admin-ajax.php' ) ), 'user_post_id' => absint( $post_id ), 'nonce' => wp_create_nonce( 'mt-update-post_' . absint( $user_id ) ), 'loading_gif' => esc_url( self::get_plugin_url( '/img/loading.gif' ) ), ) ); ?> array( $this, 'rest_api_get_profile_for_user' ), ) ); register_rest_route( 'mpp/v2', '/profile-image/me', array( 'methods' => 'POST', 'callback' => array( $this, 'rest_api_put_profile' ), 'permission_callback' => '__return_true', ) ); register_rest_route( 'mpp/v2', '/profile-image/change', array( 'methods' => 'POST', 'callback' => array( $this, 'rest_api_change_profile_image' ), 'permission_callback' => '__return_true', ) ); register_rest_route( 'mpp/v2', '/get_users', array( 'methods' => 'POST', 'callback' => array( $this, 'rest_api_get_users' ), 'permission_callback' => array( $this, 'rest_get_users_permissions_callback' ), ) ); register_rest_route( 'mpp/v2', '/get_posts', array( 'methods' => 'POST', 'callback' => array( $this, 'rest_api_get_posts_for_user' ), 'permission_callback' => array( $this, 'rest_get_users_permissions_callback' ), ) ); // keep it for backward compatibility. register_rest_route( 'mpp/v1', '/user/(?P\d+)', array( 'methods' => 'GET', 'callback' => array( $this, 'rest_api_get_profile' ), 'permission_callback' => '__return_true', 'args' => array( 'id' => array( 'validate_callback' => array( $this, 'rest_api_validate' ), 'sanitize_callback' => array( $this, 'rest_api_sanitize' ), ), ), ) ); } /** * Gets users for the Gutenberg block * * @param array $request WP REST API array. * * @return array A list of users. **/ public function rest_api_get_users( $request ) { /** * Filter the capability types of users. * * @since 2.1.3 * * @param string User role for users */ $capabilities = apply_filters( 'mpp_gutenberg_user_role', 'authors' ); $user_query = new WP_User_Query( array( 'who' => $capabilities, 'orderby' => 'display_name', ) ); $user_results = $user_query->get_results(); $return = array(); foreach ( $user_results as $result ) { // Get attachment ID. $profile_post_id = absint( get_user_option( 'metronet_post_id', $result->data->ID ) ); $post_thumbnail_id = get_post_thumbnail_id( $profile_post_id ); if ( ! $post_thumbnail_id ) { $user_data = new stdClass(); $user_data->ID = $result->data->ID; $user_data->display_name = $result->data->display_name; $user_data->has_profile_picture = false; $user_data->profile_picture_id = 0; $user_data->default_image = self::get_plugin_url( 'img/mystery.png' ); $user_data->profile_pictures = array( 'avatar' => get_avatar( $result->data->ID ), ); $user_data->is_user_logged_in = ( get_current_user_id() == $result->data->ID ) ? true : false; // phpcs:ignore $return[ $result->data->ID ] = $user_data; continue; } $user_data->ID = $result->data->ID; $user_data->description = get_user_meta( $result->data->ID, 'description', true ); $user_data->display_name = $result->data->display_name; $user_data->has_profile_picture = true; $user_data->is_user_logged_in = ( get_current_user_id() == $result->data->ID ) ? true : false; // phpcs:ignore $user_data->description = get_user_meta( $result->data->ID, 'description', true ); // Get attachment URL. $attachment_url = wp_get_attachment_url( $post_thumbnail_id ); $user_data->profile_picture_id = $post_thumbnail_id; $user_data->default_image = self::get_plugin_url( 'img/mystery.png' ); $user_data->profile_pictures = array( '24' => wp_get_attachment_image_url( $post_thumbnail_id, 'profile_24', false, '' ), '48' => wp_get_attachment_image_url( $post_thumbnail_id, 'profile_48', false, '' ), '96' => wp_get_attachment_image_url( $post_thumbnail_id, 'profile_96', false, '' ), '150' => wp_get_attachment_image_url( $post_thumbnail_id, 'profile_150', false, '' ), '300' => wp_get_attachment_image_url( $post_thumbnail_id, 'profile_300', false, '' ), 'thumbnail' => wp_get_attachment_image_url( $post_thumbnail_id, 'thumbnail', false, '' ), 'avatar' => get_avatar( $result->data->ID ), 'full' => $attachment_url, ); $user_data->permalink = get_author_posts_url( $result->data->ID ); $return[ $result->data->ID ] = $user_data; } return $return; } /** * Changes a profile image for a user. * * @param array $request WP REST API array. * * @return array image URLs matched to sizes **/ public function rest_api_change_profile_image( $request ) { $user_id = (int) $request['user_id']; $media_id = (int) $request['media_id']; if ( ! $user_id ) { return new WP_Error( 'mpp_no_user', __( 'User not found.', 'metronet-profile-picture' ), array( 'status' => 403 ) ); } if ( ! current_user_can( 'upload_files', $user_id ) ) { return new WP_Error( 'mpp_insufficient_privs', __( 'You must be able to upload files.', 'metronet-profile-picture' ), array( 'status' => 403 ) ); } $post_id = $this->get_post_id( $user_id ); // Save user meta. update_user_option( $user_id, 'metronet_post_id', $post_id ); update_user_option( $user_id, 'metronet_image_id', $media_id ); // Added via this thread (Props Solinx) - https://wordpress.org/support/topic/storing-image-id-directly-as-user-meta-data. set_post_thumbnail( $post_id, $media_id ); $attachment_url = wp_get_attachment_url( $media_id ); return array( '24' => wp_get_attachment_image_url( $media_id, 'profile_24', false, '' ), '48' => wp_get_attachment_image_url( $media_id, 'profile_48', false, '' ), '96' => wp_get_attachment_image_url( $media_id, 'profile_96', false, '' ), '150' => wp_get_attachment_image_url( $media_id, 'profile_150', false, '' ), '300' => wp_get_attachment_image_url( $media_id, 'profile_300', false, '' ), 'thumbnail' => wp_get_attachment_image_url( $media_id, 'thumbnail', false, '' ), 'full' => $attachment_url, ); } /** * Adds a profile picture to a user * * @param array $request WP REST API array. * * @return array image URLs matched to sizes **/ public function rest_api_put_profile( $request ) { $user_id = get_current_user_id(); $media_id = (int) $request['media_id']; if ( ! current_user_can( 'upload_files' ) ) { return new WP_Error( 'mpp_insufficient_privs', __( 'You must be able to upload files.', 'metronet-profile-picture' ), array( 'status' => 403 ) ); } if ( ! $user_id ) { return new WP_Error( 'mpp_no_user', __( 'User not found.', 'metronet-profile-picture' ), array( 'status' => 403 ) ); } if ( ! current_user_can( 'edit_others_posts', $user_id ) ) { return new WP_Error( 'mpp_not_privs', __( 'You must have a role of editor or above to set a new profile image.', 'metronet-profile-picture' ), array( 'status' => 403 ) ); } $is_post_owner = ( get_post( $media_id )->post_author === $user_id ) ? true : false; if ( ! $is_post_owner && ! current_user_can( 'edit_others_posts', $user_id ) ) { return new WP_Error( 'mpp_not_owner', __( 'User not owner.', 'metronet-profile-picture' ), array( 'status' => 403 ) ); } $post_id = $this->get_post_id( $user_id ); // Save user meta. update_user_option( $user_id, 'metronet_post_id', $post_id ); update_user_option( $user_id, 'metronet_image_id', $media_id ); // Added via this thread (Props Solinx) - https://wordpress.org/support/topic/storing-image-id-directly-as-user-meta-data. set_post_thumbnail( $post_id, $media_id ); $attachment_url = wp_get_attachment_url( $media_id ); return array( '24' => wp_get_attachment_image_url( $media_id, 'profile_24', false, '' ), '48' => wp_get_attachment_image_url( $media_id, 'profile_48', false, '' ), '96' => wp_get_attachment_image_url( $media_id, 'profile_96', false, '' ), '150' => wp_get_attachment_image_url( $media_id, 'profile_150', false, '' ), '300' => wp_get_attachment_image_url( $media_id, 'profile_300', false, '' ), 'thumbnail' => wp_get_attachment_image_url( $media_id, 'thumbnail', false, '' ), 'full' => $attachment_url, ); } /** * Returns the 5 most recent posts for the user * * @param array $request The REST Request data. **/ public function rest_api_get_posts_for_user( $request ) { $user_id = absint( $request['user_id'] ); $user = get_user_by( 'id', $user_id ); if ( ! $user ) { return new WP_Error( 'mpp_no_user', __( 'User not found.', 'metronet-profile-picture' ), array( 'status' => 404 ) ); } $args = array( 'post_type' => 'post', 'post_status' => 'publish', 'author' => $user_id, 'orderby' => 'date', 'order' => 'DESC', 'posts_per_page' => 5, ); $posts = get_posts( $args ); foreach ( $posts as &$post ) { $post->permalink = get_permalink( $post->ID ); } wp_send_json( $posts ); } /** * Returns an attachment image ID and profile image if available * * @param array $object REST object. * @param string $field_name The field to update. * @param array $request The request made. **/ public function rest_api_get_profile_for_user( $object, $field_name, $request ) { $user_id = $object['id']; $user = get_user_by( 'id', $user_id ); if ( ! $user ) { return new WP_Error( 'mpp_no_user', __( 'User not found.', 'metronet-profile-picture' ), array( 'status' => 404 ) ); } // No capability check here because we're just returning user profile data. // Get attachment ID. $profile_post_id = absint( get_user_option( 'metronet_post_id', $user_id ) ); $post_thumbnail_id = get_post_thumbnail_id( $profile_post_id ); if ( ! $post_thumbnail_id ) { return new WP_Error( 'mpp_no_profile_picture', __( 'Profile picture not found.', 'metronet-profile-picture' ), array( 'status' => 404 ) ); } // Get attachment URL. $attachment_url = wp_get_attachment_url( $post_thumbnail_id ); return array( '24' => wp_get_attachment_image_url( $post_thumbnail_id, 'profile_24', false, '' ), '48' => wp_get_attachment_image_url( $post_thumbnail_id, 'profile_48', false, '' ), '96' => wp_get_attachment_image_url( $post_thumbnail_id, 'profile_96', false, '' ), '150' => wp_get_attachment_image_url( $post_thumbnail_id, 'profile_150', false, '' ), '300' => wp_get_attachment_image_url( $post_thumbnail_id, 'profile_300', false, '' ), 'full' => $attachment_url, ); } /** * Returns a profile for the user * * @param array $data WP REST API array. * * @return json image URLs matched to sizes **/ public function rest_api_get_profile( $data ) { $user_id = $data['id']; $user = get_user_by( 'id', $user_id ); if ( ! $user ) { return new WP_Error( 'mpp_no_user', __( 'User not found.', 'metronet-profile-picture' ), array( 'status' => 404 ) ); } // Get attachment ID. $profile_post_id = absint( get_user_option( 'metronet_post_id', $user_id ) ); $post_thumbnail_id = get_post_thumbnail_id( $profile_post_id ); if ( ! $post_thumbnail_id ) { return new WP_Error( 'mpp_no_profile_picture', __( 'Profile picture not found.', 'metronet-profile-picture' ), array( 'status' => 404 ) ); } // Get attachment URL. $attachment_url = wp_get_attachment_url( $post_thumbnail_id ); return array( 'attachment_id' => $post_thumbnail_id, 'attachment_url' => $attachment_url, ); } /** * Makes sure the ID we are passed is numeric * * @param mixed $param The paramater to validate. * @param array $request The REST request. * @param mixed $key The key to check. * * @return bool Whether to the parameter is numeric or not. **/ public function rest_api_validate( $param, $request, $key ) { return is_numeric( $param ); } /** * Sanitizes user ID * * @param mixed $param The paramater to validate. * @param array $request The REST request. * @param mixed $key The key to check. * * @return int Sanitized user ID. **/ public function rest_api_sanitize( $param, $request, $key ) { return absint( $param ); } /** * Saves user profile fields * * @param int $user_id The User ID to save. **/ public function save_user_profile( $user_id ) { if ( ! isset( $_POST['metronet-user-avatar'] ) ) { return; } check_admin_referer( 'update-user_' . $user_id ); flush_rewrite_rules( true ); $user_avatar = filter_input( INPUT_POST, 'metronet-user-avatar' ); if ( 'on' === $user_avatar ) { update_user_option( $user_id, 'metronet_avatar_override', 'on' ); } else { update_user_option( $user_id, 'metronet_avatar_override', 'off' ); } } //end save_user_profile } // instantiate the class. global $mt_pp; if ( class_exists( 'Metronet_Profile_Picture' ) ) { if ( get_bloginfo( 'version' ) >= '3.5' ) { add_action( 'plugins_loaded', 'mt_mpp_instantiate', 10 ); } } /** * Instantiate User Profile Picture. */ function mt_mpp_instantiate() { global $mt_pp; $mt_pp = new Metronet_Profile_Picture(); do_action( 'user_profile_picture_loaded' ); } /** * Template tag for outputting a profile image. * * @param int $user_id The user ID for the user to retrieve the image for. * @param mixed $args Arguments for custom output. * size - string || array (see get_the_post_thumbnail). * attr - string || array (see get_the_post_thumbnail). * echo - bool (true or false) - whether to echo the image or return it. */ function mt_profile_img( $user_id, $args = array() ) { $profile_post_id = absint( get_user_option( 'metronet_post_id', $user_id ) ); if ( 0 === $profile_post_id || 'mt_pp' !== get_post_type( $profile_post_id ) ) { return false; } $defaults = array( 'size' => 'thumbnail', 'attr' => '', 'echo' => true, ); $args = wp_parse_args( $args, $defaults ); extract( $args ); // phpcs:ignore $post_thumbnail_id = get_post_thumbnail_id( $profile_post_id ); // Return false or echo nothing if there is no post thumbnail. if ( ! $post_thumbnail_id ) { if ( $echo ) { echo ''; } else { return false; } return; } // Implode Classes if set and array - dev note: edge case. if ( is_array( $attr ) && isset( $attr['class'] ) ) { if ( is_array( $attr['class'] ) ) { $attr['class'] = implode( ' ', $attr['class'] ); } } $post_thumbnail = wp_get_attachment_image( $post_thumbnail_id, $size, false, $attr ); /** * Filter outputted HTML. * * Filter outputted HTML. * * @param string $post_thumbnail img tag with formed HTML. * @param int $profile_post_id The profile in which the image is attached. * @param int $profile_thumbnail_id The thumbnail ID for the attached image. * @param int $user_id The user id for which the image is attached. */ $post_thumbnail = apply_filters( 'mpp_thumbnail_html', $post_thumbnail, $profile_post_id, $post_thumbnail_id, $user_id ); if ( $echo ) { echo wp_kses_post( $post_thumbnail ); } else { return $post_thumbnail; } } //end mt_profile_img /** * Adds a profile author box * * @since 2.2.0 * * @param int $user_id The user ID for the user to retrieve the profile for. * @param array $attributes See defaults in function for all attributes. * * @return string User profile box if user exists */ function mt_author_box( $user_id = 0, $attributes = array() ) { $user = get_user_by( 'id', $user_id ); if ( false === $user ) { return ''; } $defaults = array( 'theme' => 'regular', /* Can be regular, compact, profile, or tabbed */ 'profileAvatarShape' => 'square', /* Can be 'square' or 'rounded' */ 'padding' => 10, 'border' => 1, 'borderRounded' => 5, 'borderColor' => '#000000', 'profileBackgroundColor' => '#FFFFFF', 'profileTextColor' => '#000000', 'showName' => true, 'showTitle' => false, 'fontSize' => 18, 'profileName' => $user->data->display_name, 'profileTitle' => '', 'avatarSize' => 150, 'profileImgURL' => get_avatar_url( $user_id, isset( $attributes['avatarSize'] ) ? $attributes['avatarSize'] : 150 ), 'headerFontSize' => 24, 'showDescription' => true, 'showSocialMedia' => true, 'profileContent' => get_user_meta( $user_id, 'description', true ), 'profileFontSize' => 18, 'showViewPosts' => true, 'profileURL' => get_author_posts_url( $user_id ), 'website' => '', /* Needs to be a URl */ 'showWebsite' => false, 'showPostsWidth' => '100%', /* ignored if website is not empty and true */ 'profileViewPostsBackgroundColor' => '#cf6d38', 'profileViewPostsTextColor' => '#FFFFFF', 'buttonFontSize' => 16, 'profileWebsiteBackgroundColor' => '#333333', 'profileWebsiteTextColor' => '#FFFFFF', 'profileLinkColor' => '#000000', 'showSocialMedia' => false, 'socialWordPress' => '', 'socialFacebook' => '', 'socialTwitter' => '', 'socialInstagram' => '', 'socialPinterest' => '', 'socialLinkedIn' => '', 'socialYouTube' => '', 'socialGitHub' => '', 'socialMediaOptions' => 'brand', /* can be brand or custom */ 'socialMediaColors' => '#000000', /* Only applicable if socialMediaOptions is custom */ 'profileCompactAlignment' => 'center', // Can be left, center, or right. /* Tabbed Attributes */ 'tabbedAuthorProfileTitle' => '', 'tabbedAuthorSubHeading' => '', 'tabbedAuthorProfile' => __( 'Author', 'metronet-profile-picture' ), 'tabbedAuthorLatestPosts' => __( 'Latest Posts', 'metronet-profile-picture' ), 'tabbedAuthorProfileHeading' => __( 'Author Information', 'metronet-profile-picture' ), 'profileLatestPostsOptionsValue' => 'white', /* can be none, white, light, black, magenta, blue, green */ 'profileTabColor' => '#333333', 'profileTabPostsColor' => '#333333', 'profileTabHeadlineColor' => '#333333', 'profileTabHeadlineTextColor' => '#FFFFFF', 'profileTabTextColor' => '#FFFFFF', 'profileTabPostsTextColor' => '#FFFFFF', ); $attributes = wp_parse_args( $attributes, $defaults ); $min_or_not = ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ) ? '' : '.min'; if ( 'regular' === $attributes['theme'] || 'compact' === $attributes['theme'] || 'profile' === $attributes['theme'] ) : ?>
avatar

0 ) : ?>

avatar

avatar
avatar
' . wp_kses_post( $attributes['tabbedAuthorProfileTitle'] ) . '
'; ?>

'post', 'post_status' => 'publish', 'author' => $user_id, 'orderby' => 'date', 'order' => 'DESC', 'posts_per_page' => 5, ); $posts = get_posts( $args ); ?>
    %s", esc_url( get_permalink( $post->ID ) ), esc_html( $post->post_title ) ); } ?>
'; require $svg_icons; echo ''; } } /** * Allow other plugins to run code from inside this SVG block at the end. * * @since 2.3.0 */ do_action( 'mpp_svg_end' ); }