* @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( '
', esc_html__( 'Your options have been saved.', 'metronet-profile-picture' ) );
		}
		// Get options and defaults.
		$options = $this->get_options();
		?>
		
		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( '%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( '%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( '%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( '%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( '%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'] ) :
		?>
			
		
		
		
		
			
			
				
				
				
				
					
						' . 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' );
}