<?php
/*
 Based on contributions from: Beau Lebens - http://www.dentedreality.com.au/
 Modified for BuddyPress by: Andy Peatling - http://apeatling.wordpress.com/
*/

/***
 * Set up the constants we need for avatar support
 */
function bp_core_set_avatar_constants() {
	global $bp;

	if ( !defined( 'BP_AVATAR_UPLOAD_PATH' ) )
		define( 'BP_AVATAR_UPLOAD_PATH', bp_core_avatar_upload_path() );

	if ( !defined( 'BP_AVATAR_URL' ) )
		define( 'BP_AVATAR_URL', bp_core_avatar_url() );

	if ( !defined( 'BP_AVATAR_THUMB_WIDTH' ) )
		define( 'BP_AVATAR_THUMB_WIDTH', 50 );

	if ( !defined( 'BP_AVATAR_THUMB_HEIGHT' ) )
		define( 'BP_AVATAR_THUMB_HEIGHT', 50 );

	if ( !defined( 'BP_AVATAR_FULL_WIDTH' ) )
		define( 'BP_AVATAR_FULL_WIDTH', 150 );

	if ( !defined( 'BP_AVATAR_FULL_HEIGHT' ) )
		define( 'BP_AVATAR_FULL_HEIGHT', 150 );

	if ( !defined( 'BP_AVATAR_ORIGINAL_MAX_WIDTH' ) )
		define( 'BP_AVATAR_ORIGINAL_MAX_WIDTH', 450 );

	if ( !defined( 'BP_AVATAR_ORIGINAL_MAX_FILESIZE' ) ) {
		if ( !$bp->site_options['fileupload_maxk'] )
			define( 'BP_AVATAR_ORIGINAL_MAX_FILESIZE', 5120000 ); /* 5mb */
		else
			define( 'BP_AVATAR_ORIGINAL_MAX_FILESIZE', $bp->site_options['fileupload_maxk'] * 1024 );
	}

	if ( !defined( 'BP_AVATAR_DEFAULT' ) )
		define( 'BP_AVATAR_DEFAULT', BP_PLUGIN_URL . '/bp-core/images/mystery-man.jpg' );

	if ( !defined( 'BP_AVATAR_DEFAULT_THUMB' ) )
		define( 'BP_AVATAR_DEFAULT_THUMB', BP_PLUGIN_URL . '/bp-core/images/mystery-man-50.jpg' );
}
add_action( 'bp_loaded', 'bp_core_set_avatar_constants', 8 );

/**
 * bp_core_fetch_avatar()
 *
 * Fetches an avatar from a BuddyPress object. Supports user/group/blog as
 * default, but can be extended to include your own custom components too.
 *
 * @global object $bp
 * @global object $current_blog
 * @param array $args Determine the output of this function
 * @return string Formatted HTML <img> element, or raw avatar URL based on $html arg
 */
function bp_core_fetch_avatar( $args = '' ) {
	global $bp, $current_blog;

	// Set a few default variables
	$def_object		= 'user';
	$def_type		= 'thumb';
	$def_class		= 'avatar';
	$def_alt		= __( 'Avatar Image', 'buddypress' );

	// Set the default variables array
	$defaults = array(
		'item_id'		=> false,
		'object'		=> $def_object,	// user/group/blog/custom type (if you use filters)
		'type'			=> $def_type,	// thumb or full
		'avatar_dir'	=> false,		// Specify a custom avatar directory for your object
		'width'			=> false,		// Custom width (int)
		'height'		=> false,		// Custom height (int)
		'class'			=> $def_class,	// Custom <img> class (string)
		'css_id'		=> false,		// Custom <img> ID (string)
		'alt'			=> $def_alt,	// Custom <img> alt (string)
		'email'			=> false,		// Pass the user email (for gravatar) to prevent querying the DB for it
		'no_grav'		=> false,		// If there is no avatar found, return false instead of a grav?
		'html'			=> true			// Wrap the return img URL in <img />
	);

	// Compare defaults to passed and extract
	$params = wp_parse_args( $args, $defaults );
	extract( $params, EXTR_SKIP );

	// Set item_id if not passed
	if ( !$item_id ) {
		if ( 'user' == $object )
			$item_id = $bp->displayed_user->id;
		else if ( 'group' == $object )
			$item_id = $bp->groups->current_group->id;
		else if ( 'blog' == $object )
			$item_id = $current_blog->id;

		$item_id = apply_filters( 'bp_core_avatar_item_id', $item_id, $object );

		// if ( !$item_id ) return false;
	}

    return get_avatar($item_id, '50');
}

function bp_core_delete_existing_avatar( $args = '' ) {
	global $bp;

	$defaults = array(
		'item_id' => false,
		'object' => 'user', // user OR group OR blog OR custom type (if you use filters)
		'avatar_dir' => false
	);

	$args = wp_parse_args( $args, $defaults );
	extract( $args, EXTR_SKIP );

	if ( !$item_id ) {
		if ( 'user' == $object )
			$item_id = $bp->displayed_user->id;
		else if ( 'group' == $object )
			$item_id = $bp->groups->current_group->id;
		else if ( 'blog' == $object )
			$item_id = $current_blog->id;

		$item_id = apply_filters( 'bp_core_avatar_item_id', $item_id, $object );

		if ( !$item_id ) return false;
	}

	if ( !$avatar_dir ) {
		if ( 'user' == $object )
			$avatar_dir = 'avatars';
		else if ( 'group' == $object )
			$avatar_dir = 'group-avatars';
		else if ( 'blog' == $object )
			$avatar_dir = 'blog-avatars';

		$avatar_dir = apply_filters( 'bp_core_avatar_dir', $avatar_dir, $object );

		if ( !$avatar_dir ) return false;
	}

	$avatar_folder_dir = apply_filters( 'bp_core_avatar_folder_dir', BP_AVATAR_UPLOAD_PATH . '/' . $avatar_dir . '/' . $item_id, $item_id, $object, $avatar_dir );

	if ( !file_exists( $avatar_folder_dir ) )
		return false;

	if ( $av_dir = opendir( $avatar_folder_dir ) ) {
		while ( false !== ( $avatar_file = readdir($av_dir) ) ) {
			if ( ( preg_match( "/-bpfull/", $avatar_file ) || preg_match( "/-bpthumb/", $avatar_file ) ) && '.' != $avatar_file && '..' != $avatar_file )
				@unlink( $avatar_folder_dir . '/' . $avatar_file );
		}
	}
	closedir($av_dir);

	@rmdir( $avatar_folder_dir );

	do_action( 'bp_core_delete_existing_avatar', $args );

	return true;
}

function bp_core_avatar_handle_upload( $file, $upload_dir_filter ) {
	global $bp;

	/***
	 * You may want to hook into this filter if you want to override this function.
	 * Make sure you return false.
	 */
	if ( !apply_filters( 'bp_core_pre_avatar_handle_upload', true, $file, $upload_dir_filter ) )
		return true;

	require_once( ABSPATH . '/wp-admin/includes/image.php' );
	require_once( ABSPATH . '/wp-admin/includes/file.php' );

	$uploadErrors = array(
		0 => __("There is no error, the file uploaded with success", 'buddypress'),
		1 => __("Your image was bigger than the maximum allowed file size of: ", 'buddypress') . size_format(BP_AVATAR_ORIGINAL_MAX_FILESIZE),
		2 => __("Your image was bigger than the maximum allowed file size of: ", 'buddypress') . size_format(BP_AVATAR_ORIGINAL_MAX_FILESIZE),
		3 => __("The uploaded file was only partially uploaded", 'buddypress'),
		4 => __("No file was uploaded", 'buddypress'),
		6 => __("Missing a temporary folder", 'buddypress')
	);

	if ( !bp_core_check_avatar_upload( $file ) ) {
		bp_core_add_message( sprintf( __( 'Your upload failed, please try again. Error was: %s', 'buddypress' ), $uploadErrors[$file['file']['error']] ), 'error' );
		return false;
	}

	if ( !bp_core_check_avatar_size( $file ) ) {
		bp_core_add_message( sprintf( __( 'The file you uploaded is too big. Please upload a file under %s', 'buddypress'), size_format(BP_AVATAR_ORIGINAL_MAX_FILESIZE) ), 'error' );
		return false;
	}

	if ( !bp_core_check_avatar_type( $file ) ) {
		bp_core_add_message( __( 'Please upload only JPG, GIF or PNG photos.', 'buddypress' ), 'error' );
		return false;
	}

	/* Filter the upload location */
	add_filter( 'upload_dir', $upload_dir_filter, 10, 0 );

	$bp->avatar_admin->original = wp_handle_upload( $file['file'], array( 'action'=> 'bp_avatar_upload' ) );

	/* Move the file to the correct upload location. */
	if ( !empty( $bp->avatar_admin->original['error'] ) ) {
		bp_core_add_message( sprintf( __( 'Upload Failed! Error was: %s', 'buddypress' ), $bp->avatar_admin->original['error'] ), 'error' );
		return false;
	}

	/* Get image size */
	$size = @getimagesize( $bp->avatar_admin->original['file'] );

	/* Check image size and shrink if too large */
	if ( $size[0] > BP_AVATAR_ORIGINAL_MAX_WIDTH ) {
		$thumb = wp_create_thumbnail( $bp->avatar_admin->original['file'], BP_AVATAR_ORIGINAL_MAX_WIDTH );

		/* Check for thumbnail creation errors */
		if ( is_wp_error( $thumb ) ) {
			bp_core_add_message( sprintf( __( 'Upload Failed! Error was: %s', 'buddypress' ), $thumb->get_error_message() ), 'error' );
			return false;
		}

		/* Thumbnail is good so proceed */
		$bp->avatar_admin->resized = $thumb;
	}

	/* We only want to handle one image after resize. */
	if ( empty( $bp->avatar_admin->resized ) )
		$bp->avatar_admin->image->dir = str_replace( BP_AVATAR_UPLOAD_PATH, '', $bp->avatar_admin->original['file'] );
	else {
		$bp->avatar_admin->image->dir = str_replace( BP_AVATAR_UPLOAD_PATH, '', $bp->avatar_admin->resized );
		@unlink( $bp->avatar_admin->original['file'] );
	}

	/* Set the url value for the image */
	$bp->avatar_admin->image->url = BP_AVATAR_URL . $bp->avatar_admin->image->dir;

	return true;
}

function bp_core_avatar_handle_crop( $args = '' ) {
	global $bp;

	$defaults = array(
		'object' => 'user',
		'avatar_dir' => 'avatars',
		'item_id' => false,
		'original_file' => false,
		'crop_w' => BP_AVATAR_FULL_WIDTH,
		'crop_h' => BP_AVATAR_FULL_HEIGHT,
		'crop_x' => 0,
		'crop_y' => 0
	);

	$r = wp_parse_args( $args, $defaults );

	/***
	 * You may want to hook into this filter if you want to override this function.
	 * Make sure you return false.
	 */
	if ( !apply_filters( 'bp_core_pre_avatar_handle_crop', true, $r ) )
		return true;

	extract( $r, EXTR_SKIP );

	if ( !$original_file )
		return false;

	$original_file = BP_AVATAR_UPLOAD_PATH . $original_file;

	if ( !file_exists( $original_file ) )
		return false;

	if ( !$item_id )
		$avatar_folder_dir = apply_filters( 'bp_core_avatar_folder_dir', dirname( $original_file ), $item_id, $object, $avatar_dir );
	else
		$avatar_folder_dir = apply_filters( 'bp_core_avatar_folder_dir', BP_AVATAR_UPLOAD_PATH . '/' . $avatar_dir . '/' . $item_id, $item_id, $object, $avatar_dir );

	if ( !file_exists( $avatar_folder_dir ) )
		return false;

	require_once( ABSPATH . '/wp-admin/includes/image.php' );
	require_once( ABSPATH . '/wp-admin/includes/file.php' );

	/* Delete the existing avatar files for the object */
	bp_core_delete_existing_avatar( array( 'object' => $object, 'avatar_path' => $avatar_folder_dir ) );

	/* Make sure we at least have a width and height for cropping */
	if ( !(int)$crop_w )
		$crop_w = BP_AVATAR_FULL_WIDTH;

	if ( !(int)$crop_h )
		$crop_h = BP_AVATAR_FULL_HEIGHT;

	/* Set the full and thumb filenames */
	$full_filename = wp_hash( $original_file . time() ) . '-bpfull.jpg';
	$thumb_filename = wp_hash( $original_file . time() ) . '-bpthumb.jpg';

	/* Crop the image */
	$full_cropped = wp_crop_image( $original_file, (int)$crop_x, (int)$crop_y, (int)$crop_w, (int)$crop_h, BP_AVATAR_FULL_WIDTH, BP_AVATAR_FULL_HEIGHT, false, $avatar_folder_dir . '/' . $full_filename );
	$thumb_cropped = wp_crop_image( $original_file, (int)$crop_x, (int)$crop_y, (int)$crop_w, (int)$crop_h, BP_AVATAR_THUMB_WIDTH, BP_AVATAR_THUMB_HEIGHT, false, $avatar_folder_dir . '/' . $thumb_filename );

	/* Remove the original */
	@unlink( $original_file );

	return true;
}

/**
 * bp_core_fetch_avatar_filter()
 *
 * Attempts to filter get_avatar function and let BuddyPress have a go
 * at finding an avatar that may have been uploaded locally.
 *
 * @global array $authordata
 * @param string $avatar The result of get_avatar from before-filter
 * @param int|string|object $user A user ID, email address, or comment object
 * @param int $size Size of the avatar image (thumb/full)
 * @param string $default URL to a default image to use if no avatar is available
 * @param string $alt Alternate text to use in image tag. Defaults to blank
 * @return <type>
 */
function bp_core_fetch_avatar_filter( $avatar, $user, $size, $default, $alt ) {
	global $pagenow;
	
	// Do not filter if inside WordPress options page
	if ( 'options-discussion.php' == $pagenow )
		return $avatar;
	
	// If passed an object, assume $user->user_id
	if ( is_object( $user ) )
		$id = $user->user_id;

	// If passed a number, assume it was a $user_id
	else if ( is_numeric( $user ) )
		$id = $user;

	// If passed a string and that string returns a user, get the $id
	else if ( is_string( $user ) && ( $user_by_email = get_user_by_email( $user ) ) )
		$id = $user_by_email->ID;

	// If somehow $id hasn't been assigned, return the result of get_avatar
	if ( empty( $id ) )
		return !empty( $avatar ) ? $avatar : $default;

	// Let BuddyPress handle the fetching of the avatar
	$bp_avatar = bp_core_fetch_avatar( array( 'item_id' => $id, 'width' => $size, 'height' => $size, 'alt' => $alt ) );

	// If BuddyPress found an avatar, use it. If not, use the result of get_avatar
	return ( !$bp_avatar ) ? $avatar : $bp_avatar;
}
add_filter( 'get_avatar', 'bp_core_fetch_avatar_filter', 10, 5 );

function bp_core_check_avatar_upload($file) {
	if ( $file['error'] )
		return false;

	return true;
}

function bp_core_check_avatar_size($file) {
	if ( $file['file']['size'] > BP_AVATAR_ORIGINAL_MAX_FILESIZE )
		return false;

	return true;
}

function bp_core_check_avatar_type($file) {
	if ( ( !empty( $file['file']['type'] ) && !preg_match('/(jpe?g|gif|png)$/', $file['file']['type'] ) ) || !preg_match( '/(jpe?g|gif|png)$/', $file['file']['name'] ) )
		return false;

	return true;
}

/**
 * bp_core_avatar_upload_path()
 *
 * Returns the absolute upload path for the WP installation
 *
 * @global object $current_blog Current blog information
 * @uses wp_upload_dir To get upload directory info
 * @return string Absolute path to WP upload directory
 */
function bp_core_avatar_upload_path() {
	global $current_blog;

	// Get upload directory information from current site
	$upload_dir = wp_upload_dir();

	// If multisite, and current blog does not match root blog, make adjustments
	if ( bp_core_is_multisite() && BP_ROOT_BLOG != $current_blog->blog_id )
		$upload_dir['basedir'] = get_blog_option( BP_ROOT_BLOG, 'upload_path' );

	return apply_filters( 'bp_core_avatar_upload_path', $upload_dir['basedir'] );
}

/**
 * bp_core_avatar_url()
 *
 * Returns the raw base URL for root site upload location
 *
 * @global object $current_blog Current blog information
 * @uses wp_upload_dir To get upload directory info
 * @return string Full URL to current upload location
 */
function bp_core_avatar_url() {
	global $current_blog;

	// Get upload directory information from current site
	$upload_dir = wp_upload_dir();

	// If multisite, and current blog does not match root blog, make adjustments
	if ( bp_core_is_multisite() && BP_ROOT_BLOG != $current_blog->blog_id )
		$upload_dir['baseurl'] = trailingslashit( get_blog_option( BP_ROOT_BLOG, 'home' ) ) . get_blog_option( BP_ROOT_BLOG, 'upload_path' );

	return apply_filters( 'bp_core_avatar_url', $upload_dir['baseurl'] );
}

?>