[Date Prev][Date Next] [Chronological] [Thread] [Top]

Re: A little bit off topic question about jpegPhoto



jpegPhotos are actually *not* stored base64 encoded in OpenLDAP. They are stored in raw binary form. Simply fetching their contents (with the binary safe ldap_get_values_len() functoin) and echoing the jpeg data directly to the browser with the proper headers will get the job done. Using the following PHP function and supporting file you can easily display them:

  draw_jpeg_photos( 'cn=Name,dc=example,dc=com' );

You can see this in a working example here:
http://cannons.dsl.xmission.com/~dsmith/phpldapadmin/edit.php?server_id=0&dn=cn%3Dadmin%2Co%3DDaveDAP%2Cc%3DUSA


Which comes from:
  http://cannons.dsl.xmission.com/~dsmith/phpldapadmin/

<snip>

/*
* Given a DN this fetches the jpegPhoto binary data and echo's the
* HTML necesary to draw it. This function supports multiple jpegPhotos.
*
* I've removed the deletion code as it relies on some other supporting
* code. Mail me if interested.
*/
function draw_jpeg_photos( $dn )
{
	global $jpeg_temp_dir;
	global $jpeg_tmp_keep_time;

	// fill in the "..." with your LDAP server's info
	$conn = ldap_connect( ... );
	ldap_bind( ... ) or die( "No can do, bud" );

	$search_result = ldap_search( $conn, $dn, 'objectClass=*', array( 'jpegPhoto' ) );
	$entry = ldap_first_entry( $conn, $search_result );

echo "<table align=\"right\"><td><center>\n\n";
// for each jpegPhoto in the entry, draw it (there may be only one, and that's okay)
$jpeg_data = ldap_get_values_len( $conn, $entry, "jpegphoto");
for( $i=0; $i<$jpeg_data['count']; $i++ ) {
$jpeg_filename = '/tmp/' . basename( tempnam ('.', 'djp') );
$outjpeg = fopen($jpeg_filename, "wb");
fwrite($outjpeg, $jpeg_data[$i]);
fclose ($outjpeg);
$jpeg_data_size = filesize( $jpeg_filename );
if( $jpeg_data_size < 6 ) {
echo "jpegPhoto contains errors<br />";
echo '<a href="javascript:deleteJpegPhoto();" style="color:red; font-size: 75%">Delete Photo</a>';
continue;
}


$jpeg_dimensions = getimagesize ($jpeg_filename);
$width = $jpeg_dimensions[0];
$height = $jpeg_dimensions[1];
if( $width > 300 ) {
$scale_factor = 300 / $width;
$img_width = 300;
$img_height = $height * $scale_factor; } else {
$img_width = $width;
$img_height = $height;
}
echo "<img width=\"$img_width\" height=\"$img_height\"
src=\"view_jpeg_photo.php?file=" . basename($jpeg_filename) . "\" /><br />\n";
echo "<small>" . number_format($jpeg_data_size) . " bytes. ";
echo "$width x $height pixels.<br /></small>\n\n";
}
echo "</center></td></table>\n\n";
}
</snip>



Here's the contents of view_jpeg_photo.php:

<?php

$file = $_GET['file'];

$file = '/tmp/' . $file;
file_exists( $file ) or
	die( "No such file: " . htmlspecialchars( $file ) );

// little security measure here (prevents users from accessing
// files, like /etc/passwd for example)
$file = basename( $file );
$file = addcslashes( $file, '/\\' );
$f = fopen( "$jpeg_temp_dir/$file", 'r' );
$jpeg = fread( $f, filesize( "$jpeg_temp_dir/$file" ) );
fclose( $f );

Header( "Content-type: image/jpeg" );
Header( "Content-disposition: inline; filename=jpeg_photo.jpg" );
echo $jpeg;

?>

Deleting is a little more difficult since OpenLDAP does not provide a matching rule for jpegPhoto. You cannot delete a single photo if there are multiple in the entry. You can, however, delete all jpegPhotos for an entry by doing an ldap_modify with the update array set like this:

Array (
   'jpegPhoto' => Array()
)

This code came from phpLDAPadmin:
  http://phpldapadmin.sourceforge.net/

Hope this helps!

--Dave

Bruno Biedermann wrote:

Hello!

I'm storing a photo for each user in the attribute jpegPhoto (oc : inetOrgPerson) and it displays well in LDAP Browser and GQ.
My problem is that i want users to be able to see and change their photo through a web interface designed in PHP.
I would like to know how this attribute is stored in the directory. Is the file stored in BASE64 or in hex? The desc field only told me "JPEG Photo"...


Thanks for your answers, bruno.