Add vendor profile image to WooCommerce Product Vendors

September 25, 2015 . by Aaron B #Product Vendors#WooCommerce

For a recent client project I was tasked with adding a ‘profile picture upload’ function to the WooCommerce Product Vendors plugin. A simple task. The first thing I thought of was just to add an image upload the user profile page in the WordPress dashboard, which would provide the base for the rest of the project, as the client wanted the image to be shown on the vendor’s profile page on the front end and also on the product page for the vendor.

First things first, I needed to add the image upload to the WordPress user settings in the dashboard. Now, for this I used some code provided by flyinghippo.com. I only needed an image upload for the profile page, so I stripped it down to just what I needed.

// Lets add the file upload to the urser profile pages
add_action( 'show_user_profile', 'custom_profile_image' );
add_action( 'edit_user_profile', 'custom_profile_image' );

function custom_profile_image( $user )
{
?>

<h3>Profile Image</h3>

<style type="text/css">
	.fh-profile-upload-options th,
	.fh-profile-upload-options td,
	.fh-profile-upload-options input {
		vertical-align: top;
	}

	.user-preview-image {
		display: block;
		height: auto;
		width: 300px;
	}

</style>

<table class="form-table fh-profile-upload-options">
	<tr>
		<th>
			<label for="image">Profile Image</label>
		</th>

		<td>
			<!-- If we have the image then show it -->
			<?php if (get_the_author_meta( 'image', $user->ID )) { ?>
			<img class="user-preview-image" src="<?php echo esc_attr( get_the_author_meta( 'image', $user->ID ) ); ?>">
			<?php } ?>
			<!-- END -->
			<input type="text" name="image" id="image" value="<?php echo esc_attr( get_the_author_meta( 'image', $user->ID ) ); ?>" class="regular-text" />
			<input type='button' class="button-primary" value="Upload Image" id="uploadimage"/><br />

			<span class="description">Please upload an image for your profile.</span>
		</td>
	</tr>
</table>

<script type="text/javascript">
	(function( $ ) {
		$( '#uploadimage' ).on( 'click', function() {
			tb_show('Profile image upload', 'media-upload.php?type=image&TB_iframe=1');

			window.send_to_editor = function( html )
			{
				imgurl = $( 'img',html ).attr( 'src' );
				$( '#image' ).val(imgurl);
				tb_remove();
			}

			return false;
		});

		$( 'input#sidebarUploadimage' ).on('click', function() {
			tb_show('', 'media-upload.php?type=image&TB_iframe=true');

			window.send_to_editor = function( html )
			{
				imgurl = $( 'img', html ).attr( 'src' );
				$( '#sidebarimage' ).val(imgurl);
				tb_remove();
			}

			return false;
		});
	})(jQuery);
</script>

<?php
}
// END

// add script
add_action( 'admin_enqueue_scripts', 'enqueue_script' );

function enqueue_script()
{
	wp_enqueue_script( 'thickbox' );
	wp_enqueue_style('thickbox');
	wp_enqueue_script('media-upload');
}
// END

// Save the uploaded image to profile
add_action( 'personal_options_update', 'save_upload' );
add_action( 'edit_user_profile_update', 'save_upload' );

function save_upload( $user_id ) {

	if ( !current_user_can( 'edit_user', $user_id ) )
	{
		return false;
	}

	update_user_meta( $user_id, 'image', $_POST[ 'image' ] );
	update_user_meta( $user_id, 'sidebarimage', $_POST[ 'sidebarimage' ] );
}
// END

Now that was in place I could upload an image so I had something to work from. Below is the end result achieved with the code above.

With this in place it was time to start work on getting it to display on the front end. Now, I work with WooCommerce day in, day out, and I thought that this plugin would have been done before in the same style with loads of hooks that I could use – this was not the case. After reading through the plugin code I found a hook that I could use to achieve the end result I was after. I needed to add the new profile image to the products page on the vendors tab “product_vendors_tab_content_before”. This would allow me to add the image just before the main content for this section. The client was using the ‘Flatsome’ theme, so I had a look to see how this was laying out the page HTML, thinking it would be Bootstrap – not the case. Below is the new function I created, which hooked into the plugin to display the profile image.

// show image on single product tab
add_action( 'product_vendors_tab_content_before', 'our_vendor_tab_content' );
function our_vendor_tab_content( ) {

	echo '<div class="large-3 columns venimg">';
		if (get_the_author_meta( 'image', $user->ID )) {
			echo '<img src="'. esc_attr( get_the_author_meta( 'image', $user->ID ) ) .'">';
		} else {
			echo '<img src="/wp-content/plugins/woocommerce/assets/images/placeholder.png">';
		}
	echo '</div>';

}
// END

You will see that I also check to see if the image is in place. If it’s not, we use a default image. This was quite straightforward; nothing too complex. Getting the profile image to display on the front end profile page, however, was a bit tricky. I will show you how I did this, and then discuss why and what was done.

// Show image on vendor profile
add_action( 'product_vendors_page_description_before', 'our_vendor_info' );
function our_vendor_info() {

	if( is_tax( 'shop_vendor' ) ) {
		// Get vendor ID
		$vendor_id = get_queried_object()->term_id;

		// Get vendor info
		$vendor = get_vendor( $vendor_id );
		$user_title = $vendor->title;
		// Now get user id from title
		$user = get_userdatabylogin($user_title);

		echo '<div class="large-3 columns venprofileimg">';
		if (get_the_author_meta( 'image', $user->ID )) {
			echo '<img src="'. esc_attr( get_the_author_meta( 'image', $user->ID ) ) .'">';
		} else {
			echo '<img src="/wp-content/plugins/woocommerce/assets/images/placeholder.png">';
		}
	}
	echo '</div>';
}

First of all, you will notice that I am using a different hook for this – “product_vendors_page_description_before”. Comparing both of the functions, you will notice that I have had to go around the houses to get the user ID number, The way this plugin works is by setting a vendor ID number, and not using the user ID. Therefore I used the “get_userdatabylogin()” which allowed me to use the vendor title to get the user ID. I had to try a few different things first, before I came up with this. It might not be the perfect method, but it fits the purpose and allowed me to get this function to work correctly.

To finish off, I added a bit of CSS to the child theme, just to align the images

.product-vendor h2 {
	margin-left: 15px;
}
.venprofileimg {
	margin-bottom: 15px;
	margin-left: -15px;
}

I hope that you find this helpful, if you do let me know. Or, if you have a better solution than mine, leave a comment below.