Looking for technical details on profile photos

Hello, for a while now i've been trying to figure out how a user can choose a profile photo. The functionality is there, but its not designed to be changed by the user whenever they choose, but more of a side-effect.

I've spent many hours diving through code of dolphin and trying to compare to the database, and I cannot for the life of me find out what determines which of a user's picture is the profile picture!

I've found the code that automatically crops the thumbnail image, but that happens on upload.

I would be able to work in a method of changing the profile picture, but I just need to know either where in code, or what in the database needs to change to equally achieve that functionality.

Thanks for any input and your time.

Quote · 28 Jan 2013

What version of Dolphin are you using?

Geeks, making the world a better place
Quote · 28 Jan 2013

There is no specific profile photo. There are profile photos. More than one. Which one is displayed first as the large photo depends on what order they are in. They have to be in the default photo album.

You rearrange them by going into the photo album and clicking the organize link. From there it shows you all the photos in that album and you drag to change the order.



https://www.deanbassett.com
Quote · 28 Jan 2013

The reason I asked about version is that 7.1 has the profile switcher thingy as well.

Geeks, making the world a better place
Quote · 28 Jan 2013

Running 7.1

The profile switcher is just client side.

Yes that is what I observed as well deano, and is something I feel is not ok to assume users will be able to figure out. Actually have pointed people to the organize section who have multiple albums and they could not figure it out.

So first entry in the default album is the profile photo displayed. I am looking for the code that either determines which entry to use, or sets it. 

I've had no hesitations to modify base scripts. Worked out great for adding sound to the messenger :] 

I know you do some coding deano, any ideas on where to look? 

Quote · 28 Jan 2013

Seems to me, the profile switcher thingy worked in 6.1 to set the default profile photo.  I don't think it was intended to be 'just client side'.... that would be useless. The aftershocks of the avatar module from hell are still being felt. 

We still don't have a way to choose the default profile photo that makes sense.

My opinions expressed on this site, in no way represent those of Boonex or Boonex employees.
Quote · 28 Jan 2013

Seems to me, the profile switcher thingy worked in 6.1 to set the default profile photo.  I don't think it was intended to be 'just client side'.... that would be useless. The aftershocks of the avatar module from hell are still being felt. 

We still don't have a way to choose the default profile photo that makes sense.

 

Right... It is my intention to build one.

Quote · 28 Jan 2013

I can give you a clue.

The order in which the photos appear on the profile page is determined by the order in which they are pulled from the database table sys_albums_objects

the obj order field determines the order of the photos in a given album.

However unless the member reordered the photos then all of the numbers in the order field will be 0.

To make a photo in a album the first one then that photos order has to have the lowest order number while all the rest are higher.

How to do it is another issue. I don't have time for something this complex right now.


https://www.deanbassett.com
Quote · 29 Jan 2013

I've finally gotten around to this. Pretty simple to see it work when tweaking the database values.

Despite not having the avatar module installed, all user-owned photo's have a "set as avatar" button.
I plan on recycling that to run my code, and realized that the avatar module uninstall was supposed to delete that.. haha.

So, I create a new action in mysql (in sys_objects_actions), simple enough.

ID Caption Icon Url Script Eval Order Type bDisplayInSubMenuHeader
120 sys_display_picture user   getHtmlData('ajaxy_popup_result_div_{ID}', '{moduleUrl}profilePicture/{ID}/{AlbumUri}/{OwnerName}', false, 'post', true); return false;   15 bx_photos 0

So here is where it gets rather interesting.

The url comes out to:

http://mysite.com/modules/?r=photos/profilePicture/97/Profile-Photos/username

What this does, is tracing all the way back to the files module it disects the url.

function: profilePicture

parameters: 97, Profile-Photos (album name), username

This allows me to create a function inside the photos module.

function actionProfilePicture( $id, $album, $owner )

{

$sJQueryJS = genAjaxyPopupJS($iFileId); echo MsgBox(_t('YES')) . $sJQueryJS;

}

This simple bit of code allowed me to verify this function does run within the photos module.

Edit time is limited, so will post again.

Quote · 13 Mar 2013

Finally got this working, going to share, but use at your own risk.

It is worth noting, if an image is not within the default album it is moved to it before the album is re-ordered.

 

First you need to create a language key called "sys_display_picture". I have mine saying "Set display picture".

Next, you need to add the button to the action block of images, like so, insert it into the actions table:

INSERT INTO `sys_objects_actions` ( `ID`, `Caption`, `Icon`, `Url`, `Script`, `Eval`, `Order`, `Type`, `bDisplayInSubMenuHeader` ) VALUES ( null, '{evalResult}', 'user', null, 'getHtmlData('ajaxy_popup_result_div_{ID}', '{moduleUrl}profilePicture/{ID}/{AlbumUri}/{OwnerName}/{Owner}', false, 'post', true); return false;', '$sTitle = _t('sys_display_picture');
if ({Owner} == {iViewer})
return $sTitle;
$mixedCheck = BxDolService::call('photos', 'check_action', array('profilePicture','{ID}'));
if ($mixedCheck !== false)
return $sTitle;
else
 return null;', 15, 'bx_photos', 0 );

Next, you need the code itself. Inside of the class, add these functions.

/your/document/root/modules/boonex/photos/classes/bxPhotosModule.php

/** Additions by Nocare **/
/** Sets a given picture as the profile picture for a user **/
function actionProfilePicture ($iFileId, $sAlbumUri = '', $sOwnerNick = '', $sOwnerId = '')
{
	$sJQueryJS = genAjaxyPopupJS($iFileId); // Get whatever ajax is needed for response
	
	$sqli = $this->dbConnect( 'databaseName', 'databaseUsername',  'DatabaseUserPassword' ); // Get a db handle
	
	if ( is_object ( $sqli ) ) // Is an object
	{
		if ( $sqli instanceof mysqli ) // Verify it is a mysqli object before attempting to use it as such
		{
			// Soft verify parameters
			if ( strlen( $sAlbumUri ) < 1)
			{
				echo MsgBox( _t( 'Photo Album invalid' ) ) . $sJQueryJS;
				exit;
			}
			
			if ( strlen( $sOwnerNick ) < 1 )
			{
				echo MsgBox( _t( 'User invalid' ) ) . $sJQueryJS;
				exit;
			}
			
			if ( strlen( $sOwnerId ) < 1 )
			{
				echo MsgBox( _t( 'User invalid' ) ) . $sJQueryJS;
				exit;
			}
			
			if ( $iFileId setPictureOrder( $sqli, $iFileId, $sAlbumUri, $sOwnerNick, $sOwnerId) ) ) . $sJQueryJS;
				exit;
			}
			else
			{
				if ( $this->placeInAlbum( $sqli, $iFileId, $sOwnerNick, $sOwnerId, $sAlbumUri, $defaultAlbum) )
				{
					echo MsgBox( _t( $this->setPictureOrder( $sqli, $iFileId, $sAlbumUri, $sOwnerNick, $sOwnerId) ) ) . $sJQueryJS;
					exit;
				}
				else
				{
					echo MsgBox( _t( 'Could not move image' ) ) . $sJQueryJS;
					exit;
				}
			}
		} 
		else 
		{
			echo MsgBox( _t( 'Wrong object type!' ) ) . $sJQueryJS;
			exit;
		}
	}
	else if ( is_string ( $sqli ) ) // Is an error string
	{
		echo MsgBox( _t( $sqli ) ) . $sJQueryJS;
		exit;
	}
	else // Not sure what happened...
	{
		echo MsgBox( _t( 'Unkown Error Occured' ) ) . $sJQueryJS;
		exit;
	}
}

/** Re-orders given album, placing image id at 0 **/
function setPictureOrder( $sqli, $iFileId, $sAlbumUri, $sOwnerNick, $sOwnerId )
{
	if ( $sqli == null )
	{
		return null;
	}

	$albumID = $this->getAlbumIdFromName( $sqli, $sOwnerId, $sAlbumUri ); // Get album id
	
	if ( $albumID == null )
	{
		return "Could not get album id";
	}	
	
	// First off, we need a count of the images and the specific album data for images
	$sql = "SELECT * FROM `sys_albums_objects` WHERE `id_album`='" . $sqli->escape_string( $albumID ) . "';";
	
	$table = null;
	$row = null;
	$tableArray = null;
	
	if ( $table = $sqli->query( $sql ) )
	{
		while( $row = $table->fetch_array() )
		{
			$tableArray[] = $row;
		}
	}
	else
	{
		$sqli->close();
		return "couldn't retrieve album";
	}
	
	$albumSize = count( $tableArray );
	$targetImage = -1;
	
	foreach ( $tableArray as $key=>$value ) // Get array index we need to work with
	{
		if ( $value['id_object'] == $iFileId )
		{
			$targetImage = $key;
		}
	}
	
	if ( $targetImage == -1 )
	{
		return "Could not target image";
	}
	
	$index = 1;
	for ( $i = 0; $i < $albumSize; $i++ ) // Re-order array items
	{
		if ( $tableArray[$i] != $tableArray[$targetImage] )
		{
			$tableArray[$i]['obj_order'] = $index;
			$index++;
		}
	}
	
	$tableArray[$targetImage]['obj_order'] = 0;
	
	// Now what's left is to update the table with the re-ordered images. Take note, there is no "order preservation" during this whole operation. A users default album order will be reset in this sense.
	
	$failCount = 0;
	for ( $i = 0; $i < $albumSize; $i++ )
	{
		$sql = "UPDATE `sys_albums_objects` SET `obj_order`='" . $sqli->escape_string( $tableArray[$i]['obj_order'] ) . "' WHERE `id_album`='" . $sqli->escape_string( $albumID ) . "' AND `id_object`='" . $sqli->escape_string( $tableArray[$i]['id_object'] ). "';";
		if ( ! $sqli->query ( $sql ) )
		{
			$failCount ++;
		}
	}
	
	if ( $failCount > 0 )
	{
		return "Image re-order failed... ";
	}
	
	$sqli->close();
	return "Success";
}

/** Places image from given album, into given album **/
function placeInAlbum( $sqli, $iFileId, $sOwnerNick, $sOwnerId, $source, $destination )
{
	if ( $sqli == null )
	{
		return false;
	}

	$destID = $this->getAlbumIdFromName( $sqli, $sOwnerId, $destination );
	$sourceID = $this->getAlbumIdFromName( $sqli, $sOwnerId, $source );
	
	if ( $destID == null || $sourceID == null )
	{
		return false;
	}
	
	// update the specific picture object so it is in the album.
	$sql = "UPDATE `sys_albums_objects` SET `id_album`='" . $sqli->escape_string( $destID ) . "' WHERE `id_object`='" . $sqli->escape_string( $iFileId ) . "' AND `id_album`='" .$sqli->escape_string( $sourceID ). "';";
	
	if ( ! $sqli->query( $sql ) )
	{
		$sqli->close();
		return false;
	}
	
	// Finally, since we removed one item from the album, we need to decriment the count of the album
	$sql = "UPDATE `sys_albums` SET `ObjCount`=`ObjCount`-1 WHERE `ID`='" . $sqli->escape_string( $sourceID ) . "';";
	
	if ( $sqli->query( $sql ) )
	{
		$sqli->close();
		return true;
	}
	
	$sqli->close();
	return false;
}

function getAlbumIdFromName( $sqli, $sOwnerId, $albumName )
{
	if ( $sqli == null )
	{
		return null;
	}
	
	$sql = "SELECT `ID` FROM `sys_albums` WHERE `Owner`='" . $sqli->escape_string( $sOwnerId ) . "' AND `Uri`='" . $sqli->escape_string( $albumName ) . "';";
	
	$table = null;
	$row = null;
	$tableArray = null;
	
	if ( $table = $sqli->query( $sql ) )
	{
		while( $row = $table->fetch_array() )
		{
			$tableArray[] = $row;
		}
	}
	else
	{
		$sqli->close();
		return null;
	}
	
	foreach ( $tableArray as $value )
	{
		$id = $value['ID']; 
	}

	return $id;
}

/** Connects to database and returns mysqli object **/
function dbConnect( $database, $user, $pass )
{
	$db = new mysqli( 'localhost',  $user, $pass, $database );
	
	if ( $db -> connect_error )
	{
		$s =  'Connect Error (' . $db->connect_errno . ') '. $db->connect_error ;
		return $s;
	}
	else
		return $db;
}
/** End additions **/
Quote · 14 Mar 2013

This is excellent, thank you!  I'll attempt this in a week or so and will likely ask you several questions as I'm attempting it.

Quote · 24 Mar 2013

I really don't understand what this is all about.

Geeks, making the world a better place
Quote · 24 Mar 2013

 

I really don't understand what this is all about.

 It allows a person to change their profile photo more easily.  Changing it now is not intuitive.

Quote · 25 Mar 2013

Is it working with D7.1.1?

Diddy is not greedy and has time. Dolphin is cool and its not just mine :-)
Quote · 25 Mar 2013

 You absolutely right and this solution here makes it a lot easier for now :-)

Seems to me, the profile switcher thingy worked in 6.1 to set the default profile photo.  I don't think it was intended to be 'just client side'.... that would be useless. The aftershocks of the avatar module from hell are still being felt. 

We still don't have a way to choose the default profile photo that makes sense.

 

Diddy is not greedy and has time. Dolphin is cool and its not just mine :-)
Quote · 25 Mar 2013

im scared!

MY SITES http://viptopia.net general social networking | http://www.rangerschat.com/ niche site
Quote · 25 Mar 2013

I hope people find this useful. I put a lot of time into it, haha.

Quote · 31 Mar 2013

My turn to bump an old post but at least I have a good reason.  Looking at the code presented here I am having a bit of problem with it.  First of all this bit of code gets rejected:

if ( $iFileId setPictureOrder( $sqli, $iFileId, $sAlbumUri, $sOwnerNick, $sOwnerId) ) ) . $sJQueryJS; exit; }

A look at the other code structure I guessed something along the lines of :

if ( $iFileId)
      {
      echo MsgBox( _t( $this->setPictureOrder( $sqli, $iFileId, $sAlbumUri, $sOwnerNick, $sOwnerId) ) ) . $sJQueryJS;
      exit;
      }

However, I am guessing but because the former code block is doing a string catenation....

The other thing is that the SQL insert throws an error if I try it in the database tool I use.  I am thinking it is the single quotes marks inside the php code; sql needs to know that they are not indicating additional values to be inserted?  Anyway, I am not getting things to work with the code presented.

Geeks, making the world a better place
Quote · 1 Mar 2014

Can somebody else give some additional input here please.

Ultra Newb reporting for duty.
Quote · 1 Mar 2014

x2

Ultra Newb reporting for duty.
Quote · 2 Mar 2014

x3

Ultra Newb reporting for duty.
Quote · 3 Mar 2014

 

My turn to bump an old post but at least I have a good reason.  Looking at the code presented here I am having a bit of problem with it.  First of all this bit of code gets rejected:

if ( $iFileId setPictureOrder( $sqli, $iFileId, $sAlbumUri, $sOwnerNick, $sOwnerId) ) ) . $sJQueryJS; exit; }

A look at the other code structure I guessed something along the lines of :

if ( $iFileId)
      {
      echo MsgBox( _t( $this->setPictureOrder( $sqli, $iFileId, $sAlbumUri, $sOwnerNick, $sOwnerId) ) ) . $sJQueryJS;
      exit;
      }

However, I am guessing but because the former code block is doing a string catenation....

The other thing is that the SQL insert throws an error if I try it in the database tool I use.  I am thinking it is the single quotes marks inside the php code; sql needs to know that they are not indicating additional values to be inserted?  Anyway, I am not getting things to work with the code presented.

 Yes GG same here in regards to the sql query. I get the following error

You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'ajaxy_popup_result_div_{ID}', '{moduleUrl}profilePicture/{ID}/{AlbumUri}/{OwnerN' at line 1

Quote · 3 Mar 2014

any resolution to this?

 

I'm relly looking for a solution so that my members can have a static profile pic/avatar/whatever you want to call it that is member chosen and stays the same until & unless they decide to change it.  I HATE that any new photo uploaded becomes the new profile pic.

yes, I searched before asking....
Quote · 24 Apr 2014

You can use the Avatar module and set the display thumbnail as avatar instead of profile photo. This will allow your user5s to keep a static pic that wont change unless they change it.

caredesign.net
Quote · 24 Apr 2014

Sorry to be dense, but where would the "set the display thumbnail as avatar instead of profile photo." be?  The only options I see in the Avatar mod is jpeg quality and the enable checkbox and I can't easily find it in Settings either

You can use the Avatar module and set the display thumbnail as avatar instead of profile photo. This will allow your user5s to keep a static pic that wont change unless they change it.

 

yes, I searched before asking....
Quote · 24 Apr 2014

that would be in Admin - Settings - Advanced Settings -> Profiles -> Member thumb & Member thumb icon

 

I hate the way the profile photo block is, so I incorporated the avatar into the description block.

I ran this sql query in phpMyadmin:

UPDATE `sys_page_compose` SET `Func` = 'PHP', `Content` = 'include_once (BX_DIRECTORY_PATH_MODULES . \\''boonex/avatar/include.php\\''); $profileID = getID( $_GET[\\''ID\\''] ); $rProfile = mysql_query("SELECT * FROM Profiles WHERE ID = \\''$profileID\\''"); while ($row_profile = mysql_fetch_array($rProfile)) { $Avatar = $row_profile["Avatar"]; $DescriptionMe = $row_profile["DescriptionMe"]; } ?> <table style="margin-top: 10px; margin-right: 10px; margin-left: 10px; font-size: 16px; font-family: chapparral pro;"> <tr> <td><table width="80" border="0" align="left"> <tr> <td align="center" valign="top"> <img src="<?php echo BX_AVA_URL_USER_AVATARS . $Avatar . BX_AVA_EXT; // avatar image ?>" width="64" height="64"></td> </tr> </table><?php echo $DescriptionMe ?></td> </tr> </table> <?php { }' WHERE `sys_page_compose`.`Caption` = '_Description';

profile.png · 674.4K · 416 views
caredesign.net
Quote · 24 Apr 2014

 Thx Prof.  While I like what you did, I took your easier fix.

 

For future readers the correct config is:

Member Thumb = Avatar

Member Thumb Icon = Profile Photo Icon

 

with this fix the "Set as Avatar" action button works as it should.  I had to swap out the Profile Picture block I had on the profile page because it may not show the same pic as the avatar, but I put in the Profile Pictures block instead and it actually looks better this way,

 

Big thanks again!!

that would be in Admin - Settings - Advanced Settings -> Profiles -> Member thumb & Member thumb icon

 

I hate the way the profile photo block is, so I incorporated the avatar into the description block.

I ran this sql query in phpMyadmin:

UPDATE `sys_page_compose` SET `Func` = 'PHP', `Content` = 'include_once (BX_DIRECTORY_PATH_MODULES . \\''boonex/avatar/include.php\\''); $profileID = getID( $_GET[\\''ID\\''] ); $rProfile = mysql_query("SELECT * FROM Profiles WHERE ID = \\''$profileID\\''"); while ($row_profile = mysql_fetch_array($rProfile)) { $Avatar = $row_profile["Avatar"]; $DescriptionMe = $row_profile["DescriptionMe"]; } ?> <table style="margin-top: 10px; margin-right: 10px; margin-left: 10px; font-size: 16px; font-family: chapparral pro;"> <tr> <td><table width="80" border="0" align="left"> <tr> <td align="center" valign="top"> <img src="<?php echo BX_AVA_URL_USER_AVATARS . $Avatar . BX_AVA_EXT; // avatar image ?>" width="64" height="64"></td> </tr> </table><?php echo $DescriptionMe ?></td> </tr> </table> <?php { }' WHERE `sys_page_compose`.`Caption` = '_Description';

 

yes, I searched before asking....
Quote · 24 Apr 2014

However, it is not a fix if one does not want to use the avatar module.  I have worked on several sites where they did not want avatars To use avatars for a profile photo, you will have to go in and make a lot of code changes so that you have a nice size profile photo that has not been scaled up from the 64X64 size of avatars.

An easy way to set the profile photo would be nice.  And when you add photos to the profile photo album, then the last uploaded photo will become the profile photo, meaning the user has to go back and slide the photos around again.

Geeks, making the world a better place
Quote · 24 Apr 2014
 
 
Below is the legacy version of the Boonex site, maintained for Dolphin.Pro 7.x support.
The new Dolphin solution is powered by UNA Community Management System.