Source for file FisheyeImage.php
Documentation is available at FisheyeImage.php
require_once( FISHEYE_PKG_PATH. 'FisheyeBase.php' );
// Needed for getting event_time and possible image title and data
require_once( LIBERTY_PKG_PATH. 'plugins/mime.image.php' );
define('FISHEYEIMAGE_CONTENT_TYPE_GUID', 'fisheyeimage');
function FisheyeImage($pImageId = NULL, $pContentId = NULL) {
'content_name' => 'Image',
'handler_class' => 'FisheyeImage',
'handler_package' => 'fisheye',
'handler_file' => 'FisheyeImage.php',
'maintainer_url' => 'http://www.bitweaver.org'
public static function lookup( $pLookupHash ) {
if (!empty($pLookupHash['image_id']) && is_numeric($pLookupHash['image_id'])) {
if( $lookup = $gBitDb->getRow( "SELECT lc.`content_id`, lc.`content_type_guid` FROM `". BIT_DB_PREFIX. "fisheye_image` fi INNER JOIN `". BIT_DB_PREFIX. "liberty_content` lc ON(lc.`content_id`=fi.`content_id`) WHERE `image_id`=?", array( $pLookupHash['image_id'] ) ) ) {
$lookupContentId = $lookup['content_id'];
$lookupContentGuid = $lookup['content_type_guid'];
} elseif (!empty($pLookupHash['content_id']) && is_numeric($pLookupHash['content_id'])) {
$lookupContentId = $pLookupHash['content_id'];
$lookupContentGuid = NULL;
if( BitBase::verifyId( $lookupContentId ) ) {
function load( $pContentId = NULL, $pPluginParams = NULL ) {
$selectSql = $joinSql = $whereSql = '';
$whereSql = " WHERE fi.`image_id` = ?";
$whereSql = " WHERE fi.`content_id` = ?";
$this->getServicesSql( 'content_load_sql_function', $selectSql, $joinSql, $whereSql, $bindVars );
$sql = "SELECT fi.*, lc.* $gateSql $selectSql
, uue.`login` AS `modifier_user`, uue.`real_name` AS `modifier_real_name`
, uuc.`login` AS `creator_user`, uuc.`real_name` AS `creator_real_name`, ufm.`favorite_content_id` AS `is_favorite`
INNER JOIN `". BIT_DB_PREFIX. "liberty_content` lc ON (lc.`content_id` = fi.`content_id`)
LEFT JOIN `". BIT_DB_PREFIX. "users_users` uue ON (uue.`user_id` = lc.`modifier_user_id`)
LEFT JOIN `". BIT_DB_PREFIX. "users_users` uuc ON (uuc.`user_id` = lc.`user_id`)
LEFT JOIN `". BIT_DB_PREFIX. "users_favorites_map` ufm ON (ufm.`favorite_content_id`=lc.`content_id` AND ufm.`user_id`=uuc.`user_id`)
LEFT OUTER JOIN `". BIT_DB_PREFIX. "liberty_content_hits` lch ON ( lch.`content_id` = lc.`content_id` ) $joinSql
if( $this->mInfo = $this->mDb->getRow( $sql, $bindVars ) ) {
$this->mInfo['creator'] = (isset ( $this->mInfo['creator_real_name'] ) ? $this->mInfo['creator_real_name'] : $this->mInfo['creator_user'] );
$this->mInfo['editor'] = (isset ( $this->mInfo['modifier_real_name'] ) ? $this->mInfo['modifier_real_name'] : $this->mInfo['modifier_user'] );
if( $gBitSystem->isPackageActive( 'gatekeeper' ) && !@$this->verifyId( $this->mInfo['security_id'] ) ) {
// check to see if this image is in a protected gallery
// this burns an extra select but avoids an big and gnarly LEFT JOIN sequence that may be hard to optimize on all DB's
$query = "SELECT ls.* FROM `". BIT_DB_PREFIX. "fisheye_gallery_image_map` fgim
INNER JOIN `". BIT_DB_PREFIX. "gatekeeper_security_map` tsm ON(fgim.`gallery_content_id`=tsm.`content_id` )
INNER JOIN `". BIT_DB_PREFIX. "gatekeeper_security` ls ON(tsm.`security_id`=ls.`security_id` )
WHERE fgim.`item_content_id`=?";
if( $grs && $grs->RecordCount() ) {
// LibertyMime will load the attachment details in $this->mStorage
// parse the data after parent load so we have our html prefs
// Copy mStorage to mInfo['image_file'] for easy access
if( !empty( $this->mStorage ) && count( $this->mStorage ) > 0 ) {
// it seems that this is not necessary and causes confusing copies of the same stuff all over the place
// copy the image data by reference to reduce memory
reset( $this->mStorage );
// override original display_url that mime knows where we keep the image
$this->mInfo['image_file'] = NULL;
if( empty( $this->mInfo['width'] ) || empty( $this->mInfo['height'] ) ) {
// bounds checking on the width and height - corrupt photos can be ridiculously huge or negative
if( !empty($details) AND $details['width'] > 0 AND $details['width'] < 9999 AND $details['height'] > 0 AND $details['height'] < 9999 ) {
$this->mInfo['width'] = $details['width'];
$this->mInfo['height'] = $details['height'];
$this->mDb->query( "UPDATE `". BIT_DB_PREFIX. "fisheye_image` SET `width`=?, `height`=? WHERE `content_id`=?", array( $this->mInfo['width'], $this->mInfo['height'], $this->mContentId ) );
// We don't have an image_id or a content_id so there is no way to know what to load
if( $this->isValid() && $this->mInfo['width'] != $pDetails['width'] || $this->mInfo['height'] != $pDetails['height'] ) {
// if our data got out of sync with the database, force an update
$query = "UPDATE `". BIT_DB_PREFIX. "fisheye_image` SET `width`=?, `height`=? WHERE `content_id`=?";
$this->mDb->query( $query, array( $pDetails['width'], $pDetails['height'], $this->mContentId ) );
$this->mInfo['width'] = $pDetails['width'];
$this->mInfo['height'] = $pDetails['height'];
// make sure we have a valid image file.
if( ($ret = parent::exportHash()) && ($details = $this->getImageDetails() ) ) {
'has_description' => !empty( $this->mInfo['data'] ),
'is_favorite' => $this->getField('is_favorite'),
return( !empty( $this->mInfo['width'] ) && !empty( $this->mInfo['height'] ) && ($this->mInfo['width'] > $this->mInfo['height']) );
if ( empty($pParamHash['purge_from_galleries']) ) {
$pParamHash['purge_from_galleries'] = FALSE;
if( !empty( $pParamHash['resize'] ) ) {
$pParamHash['_files_override'][0]['max_height'] = $pParamHash['_files_override'][0]['max_width'] = $pParamHash['resize'];
// Make sure we know what to update
// these 2 entries will inform LibertyContent and LibertyMime that this is an update
if( !empty( $this->mInfo['attachment_id'] ) ) {
$pParamHash['_files_override'][0]['attachment_id'] = $this->mInfo['attachment_id'];
if( function_exists( 'mime_image_get_exif_data' ) && !empty( $pParamHash['_files_override'][0]['tmp_name'] ) ) {
$exifFile['source_file'] = $pParamHash['_files_override'][0]['tmp_name'];
$exifFile['type'] = $pParamHash['_files_override'][0]['type'];
// Set some default values based on the Exif data
if( !empty( $exifHash['IFD0']['ImageDescription'] ) ) {
if( empty( $pParamHash['title'] ) ) {
$exifTitle = trim( $exifHash['IFD0']['ImageDescription'] );
if( !empty( $exifTitle ) ) {
$pParamHash['title'] = $exifTitle;
} elseif( empty( $pParamHash['edit'] ) && !$this->getField( 'data' ) && $pParamHash['title'] != $exifHash['IFD0']['ImageDescription'] ) {
$pParamHash['edit'] = $exifHash['IFD0']['ImageDescription'];
// These come from Photoshop
if( !empty( $exifHash['headline'] ) ) {
if( empty( $pParamHash['title'] ) ) {
$pParamHash['title'] = $exifHash['headline'];
} elseif( empty( $pParamHash['edit'] ) && !$this->getField( 'data' ) && $pParamHash['title'] != $exifHash['headline'] ) {
$pParamHash['edit'] = $exifHash['headline'];
if( !empty( $exifFile['caption'] ) ) {
if( empty( $pParamHash['title'] ) ) {
$pParamHash['title'] = $exifFile['caption'];
} elseif( empty( $pParamHash['edit'] ) && !$this->getField( 'data' ) && $pParamHash['title'] != $exifFile['caption'] ) {
$pParamHash['edit'] = $exifFile['caption'];
if( empty( $pParamHash['event_time'] ) && !$this->getField( 'event_time' ) && !empty( $exifHash['EXIF']['DateTimeOriginal'] ) ) {
$pParamHash['event_time'] = strtotime( $exifHash['EXIF']['DateTimeOriginal'] );
// let's add a default title if we still don't have one or the user has chosen to use filename over exif data
if( (empty( $pParamHash['title'] ) || !empty($_REQUEST['use_filenames'])) && !empty( $pParamHash['_files_override'][0]['name'] ) ) {
if( preg_match( '/^[A-Z]:\\\/', $pParamHash['_files_override'][0]['name'] ) ) {
// MSIE shit file names if passthrough via gigaupload, etc.
// basename will not work - see http://us3.php.net/manual/en/function.basename.php
$tmp = preg_split("[\\\]", $pParamHash['_files_override'][0]['name'] );
$defaultName = $tmp[count($tmp) - 1];
$pParamHash['_files_override'][0]['name'] = $defaultName;
$defaultName = $pParamHash['_files_override'][0]['name'];
if( strpos( $pParamHash['_files_override'][0]['name'], '.' ) ) {
list ( $defaultName, $ext ) = explode( '.', $pParamHash['_files_override'][0]['name'] );
$pParamHash['title'] = str_replace( '_', ' ', $defaultName );
parent::verify( $pParamHash );
function store(&$pParamHash) {
global $gBitSystem, $gLibertySystem;
// Save the current attachment ID for the image attached to this FisheyeImage so we can
// delete it after saving the new one
if (!empty($this->mInfo['attachment_id']) && !empty($pParamHash['_files_override'][0])) {
$currentImageAttachmentId = $this->mInfo['attachment_id'];
$pParamHash['attachment_id'] = $currentImageAttachmentId;
$currentImageAttachmentId = NULL;
// we have already done all the permission checking needed for this user to upload an image
$pParamHash['no_perm_check'] = TRUE;
$this->mDb->StartTrans();
$pParamHash['thumbnail'] = !$gBitSystem->isFeatureActive( 'liberty_offline_thumbnailer' );
if( $currentImageAttachmentId && $currentImageAttachmentId != $this->mInfo['attachment_id'] ) {
// get storage format back from LibertyMime
$imageDetails['width'] = (!empty($this->mInfo['width']) ? $this->mInfo['width'] : NULL);
$imageDetails['height'] = (!empty($this->mInfo['height']) ? $this->mInfo['height'] : NULL);
SET `content_id` = ?, `width` = ?, `height` = ?
$bindVars = array($this->mContentId, $imageDetails['width'], $imageDetails['height'], $this->mImageId);
$sql = "INSERT INTO `". BIT_DB_PREFIX. "fisheye_image` (`image_id`, `content_id`, `width`, `height`) VALUES (?,?,?,?)";
$bindVars = array($this->mImageId, $this->mContentId, $imageDetails['width'], $imageDetails['height']);
$rs = $this->mDb->query($sql, $bindVars);
// check to see if we need offline thumbnailing
if( $gBitSystem->isFeatureActive( 'liberty_offline_thumbnailer' ) ) {
$resize = !empty( $pParamHash['resize'] ) ? (int) $pParamHash['resize'] : NULL;
if( !empty( $pParamHash['resize'] ) && is_numeric( $pParamHash['resize'] ) ) {
$this->mDb->CompleteTrans();
$this->mDb->RollbackTrans();
$this->mErrors[] = "There were errors while attempting to save this gallery image";
// only attempt to get exif data from jpg or tiff files - chokes otherwise
if( empty( $this->mExif ) && preg_match( "!\.(jpe?g|tif{1,2})$!", $file ) ) {
if( $exif = @exif_read_data( $file ) ) {
if( !empty( $this->mExif[$pExifField] ) ) {
$ret = $this->mExif[$pExifField];
function rotateImage( $pDegrees, $pImmediateRender = FALSE ) {
$fileHash['dest_base_name'] = preg_replace('/(.+)\..*$/', '$1', basename( $fileHash['source_file'] ) );
$fileHash['type'] = $gBitSystem->verifyMimeType( $fileHash['source_file'] );
$fileHash['size'] = filesize( $fileHash['source_file'] );
$fileHash['name'] = $this->getField( 'file_name' );
if( $pDegrees == 'auto' ) {
if( $exifOrientation = $this->getExifField( 'orientation' ) ) {
switch( $exifOrientation ) {
case 1: //) transform="";;
case 2: //) transform="-flip horizontal";;
case 3: //) transform="-rotate 180";;
case 4: //) transform="-flip vertical";;
case 5: //) transform="-transpose";;
case 6: //) transform="-rotate 90";;
// make sure image has not already been rotated
case 7: //) transform="-transverse";;
case 8: //) transform="-rotate 270";;
// make sure image has not already been rotated
$fileHash['degrees'] = $pDegrees;
if( $rotateFunc( $fileHash ) ) {
$this->mDb->query( "UPDATE `". BIT_DB_PREFIX. "fisheye_image` SET `width`=`height`, `height`=`width` WHERE `content_id`=?", array( $this->mContentId ) );
$this->mErrors['rotate'] = $fileHash['error'];
} elseif( $pDegrees == 'auto' ) {
$this->mErrors['rotate'] = "Image was not auto-rotated.";
* @param string $pColorSpace - target color space, only 'grayscale' is currently supported, and only when using the MagickWand image processor
* @return TRUE on success, FALSE on failure - mErrors will contain reason for failure
$fileHash['dest_base_name'] = preg_replace('/(.+)\..*$/', '$1', basename( $fileHash['source_file'] ) );
$fileHash['type'] = $gBitSystem->verifyMimeType( $fileHash['source_file'] );
$fileHash['size'] = filesize( $fileHash['source_file'] );
$fileHash['name'] = $this->getField( 'file_name' );
if( $ret = $convertFunc( $fileHash, $pColorSpace ) ) {
$sql = "UPDATE `". BIT_DB_PREFIX. "liberty_files SET `file_size`=? WHERE `file_id` = ?";
$this->mDb->query( $sql, array( filesize( $fileHash['dest_file'] ), $this->mInfo['file_id'] ) );
$fileHash['dest_base_name'] = preg_replace('/(.+)\..*$/', '$1', basename( $fileHash['source_file'] ) );
$fileHash['type'] = $gBitSystem->verifyMimeType( $fileHash['source_file'] );
$fileHash['size'] = filesize( $fileHash['source_file'] );
$fileHash['name'] = $this->getField( 'file_name' );
$fileHash['max_height'] = $fileHash['max_width'] = $pResizeOriginal;
// make a copy of the fileHash that we can compare output after processing
if( $resizeFile = $resizeFunc( $fileHash ) ) {
// Ack this is evil direct bashing of the liberty tables! XOXO spiderr
// should be a cleaner way eventually
// we need to update the souce_file in case it's changed from a non jpg to a jpg
if( $fileHash['name'] != $preResize['name'] ) {
$fileHash['source_file'] = dirname( $fileHash['source_file'] ). '/'. $fileHash['name'];
// make absolutely certain that we have 2 image files and that they are different, then remove the original
if( $fileHash['source_file'] != $preResize['source_file'] && is_file( $fileHash['source_file'] ) && is_file( $preResize['source_file'] ) ) {
@unlink( $preResize['source_file'] );
// store all the values that might have changed due to the resize
'mime_type' => $details['mime'],
$this->mDb->associateUpdate( BIT_DB_PREFIX. "liberty_files", $storeHash, array( 'file_id' => $this->mInfo['file_id'] ) );
//$query = "UPDATE `".BIT_DB_PREFIX."liberty_files` SET `file_size`=? WHERE `file_id`=?";
//$this->mDb->query( $query, array( $details['size'], $this->mInfo['file_id'] ) );
$query = "UPDATE `". BIT_DB_PREFIX. "fisheye_image` SET `width`=?, `height`=? WHERE `content_id`=?";
$this->mDb->query( $query, array( $details['width'], $details['height'], $this->mContentId ) );
// if we've come this far, we can try removing the original if it's different to the resized image
// make absolutely certain that we have 2 image files and that they are different, then remove the original
if( $fileHash['source_file'] != $preResize['source_file'] && is_file( $fileHash['source_file'] ) && is_file( $preResize['source_file'] ) ) {
@unlink( $preResize['source_file'] );
$this->mErrors['resize'] = $fileHash['error'];
// LibertyMime will take care of thumbnail generation of the offline thumbnailer is not active
if( $gBitSystem->isFeatureActive( 'liberty_offline_thumbnailer' ) && !$pImmediateRender ) {
(`content_id`, `queue_date`, `processor_parameters`) VALUES (?,?,?)";
$this->mDb->query( $query, array( $this->mContentId, $gBitSystem->getUTCTime(), serialize( array( 'resize_original' => $pResizeOriginal ) ) ) );
$fileHash['type'] = $gBitSystem->verifyMimeType( $fileHash['source_file'] );
$fileHash['size'] = filesize( $fileHash['source_file'] );
$fileHash['name'] = $this->getField( 'file_name' );
$fileHash['thumbnail_sizes'] = $pThumbSizes;
// just generate thumbnails
if( !empty( $fileHash['error'] ) ) {
$this->mErrors['thumbnail'] = $fileHash['error'];
function getStorageUrl( $pParamHash = array() ) {
$pParamHash['sub_dir'] = $this->getParameter( $pParamHash, 'sub_dir', liberty_mime_get_storage_sub_dir_name( array( 'type'=>$this->getField( 'mime_type' ), 'name'=>$this->getField('file_name') ) ) );
$pParamHash['user_id'] = $this->getParameter( $pParamHash, 'user_id', $this->getField('user_id') );
return parent::getStorageUrl( $pParamHash ).$this->getParameter( $pParamHash, 'attachment_id', $this->getField('attachment_id') ).'/';
function getStorageBranch( $pParamHash = array() ) {
$pParamHash['sub_dir'] = $this->getParameter( $pParamHash, 'sub_dir', liberty_mime_get_storage_sub_dir_name( array( 'type'=>$this->getField( 'mime_type' ), 'name'=>$this->getField('file_name') ) ) );
$pParamHash['user_id'] = $this->getParameter( $pParamHash, 'user_id', $this->getField('user_id') );
return parent::getStorageBranch( $pParamHash ).$this->getParameter( $pParamHash, 'attachment_id', $this->getField('attachment_id') ).'/';
function getStoragePath( $pParamHash, $pRootDir=NULL ) {
$pParamHash['sub_dir'] = liberty_mime_get_storage_sub_dir_name( array( 'type'=>BitBase::getParameter( $pParamHash, 'mime_type', $this->getField( 'mime_type' ) ), 'name'=>BitBase::getParameter( $pParamHash, 'file_name', $this->getField('file_name') ) ) );
$pParamHash['user_id'] = $this->getParameter( $pParamHash, 'user_id', $this->getField('user_id') );
return parent::getStoragePath( $pParamHash ).$this->getParameter( $pParamHash, 'attachment_id', $this->getField('attachment_id') ).'/';
$checkFiles = array( $pFilePath, dirname( $pFilePath ). '/original.jpg' );
$checkFiles = array( $sourceFile );
// was an original file created?
$originalFile = dirname( $sourceFile ). '/original.jpg';
$checkFiles[] = $originalFile;
foreach( $checkFiles as $cf ) {
$info['width'] = $info[0];
$info['height'] = $info[1];
if( !isset ( $this->mInfo['width'] ) ) {
if( !isset ( $this->mInfo['width'] ) ) {
* Returns include file that will setup vars for display
* @return the fully specified path to file to be included
return FISHEYE_PKG_PATH. "display_fisheye_image_inc.php";
* Returns template file used for display
* @return the fully specified path to file to be included
return 'bitpackage:fisheye/view_image.tpl';
* Function that returns link to display a piece of content
* @param pImageId id of gallery to link
* @param pMixed if a string, it is assumed to be the size, if an array, it is assumed to be a mInfo hash
* @return the url to display the gallery.
$size = (!empty( $pParamHash['size'] ) && is_string( $pParamHash['size'] ) && isset ( $pParamHash['thumbnail_url'][$pParamHash['size']] ) ) ? $pParamHash['size'] : NULL ;
if( @BitBase::verifyId( $pParamHash['image_id'] ) ) {
if( $gBitSystem->isFeatureActive( 'pretty_urls' ) ) {
$ret = FISHEYE_PKG_URL. 'image/'. $pParamHash['image_id'];
if( !empty( $pParamHash['gallery_path'] ) ) {
$ret .= $pParamHash['gallery_path'];
$ret = FISHEYE_PKG_URL. 'view_image.php?image_id='. $pParamHash['image_id'];
if( !empty( $this ) && !empty( $pParamHash['gallery_path'] ) ) {
$ret .= '&gallery_path='. $pParamHash['gallery_path'];
} elseif( @BitBase::verifyId( $pParamHash['content_id'] ) ) {
$ret = FISHEYE_PKG_URL. 'view_image.php?content_id='. $pParamHash['content_id'];
* Function that returns link to display an image
* @return the url to display the gallery.
return static::getDisplayUrlFromHash( $info );
* Function that returns link to display an image
* Used to display thumbnails for navigation bar
* @param pImageId id of image to link
* @return the url to display the image.
$info = array( 'image_id' => $pImageId );
return static::getDisplayUrlFromHash( $info );
* Generate a valid display link for the Blog
* @param object PostId of the item to use
* @return object Fully formatted html link for use by Liberty
function getDisplayLink( $pTitle= NULL, $pMixed= NULL, $pAnchor= NULL ) {
$pTitle = trim( $pTitle );
if( empty( $pMixed ) && !empty( $this ) ) {
if( $gBitSystem->isPackageActive( 'fisheye' ) ) {
$ret = trim( parent::getTitleFromHash( $pHash, $pDefault ) );
if( empty( $ret ) && $pDefault ) {
$storage = (!empty( $this ) && !empty( $this->mStorage ) ? current( $this->mStorage ) : NULL);
if( !empty( $storage['file_name'] ) ) {
$ret = $storage['file_name'];
$ret = $gLibertySystem->getContentTypeName( $pHash['content_type_guid'] );
if( !empty( $pHash['image_id'] ) ) {
$ret .= " ". $pHash['image_id'];
$ret = self::getTitleFromHash( $this->mInfo );
function getThumbnailUrl( $pSize = 'small', $pSecondaryId = NULL, $pDefault= TRUE ) {
if( $this->isValid() && isset ( $this->mInfo['thumbnail_url'][$pSize] ) ) {
$ret = $this->mInfo['thumbnail_url'][$pSize];
public static function getThumbnailUrlFromHash( &$pMixed, $pSize = 'small', $pSecondaryId = NULL, $pDefault= TRUE ) {
if( isset ( $pMixed['thumbnail_url'][$pSize] ) ) {
$ret = $pMixed['thumbnail_url'][$pSize];
function expunge($pExpungeAttachment = TRUE) {
$this->mDb->StartTrans();
$query = "DELETE FROM `". BIT_DB_PREFIX. "fisheye_gallery_image_map` WHERE `item_content_id` = ?";
$query = "UPDATE `". BIT_DB_PREFIX. "fisheye_gallery` SET `preview_content_id`=NULL WHERE `preview_content_id` = ?";
$query = "DELETE FROM `". BIT_DB_PREFIX. "fisheye_image` WHERE `content_id` = ?";
$this->mDb->CompleteTrans();
$this->mDb->RollbackTrans();
foreach ($pContentIdArray as $id) {
// Vital that we call LibertyMime::expunge with false since the attachment is already being deleted.
$query = "SELECT COUNT(`image_id`)
if($this->mDb->getOne($query, $bindVars) > 0){
global $gBitUser,$gBitSystem;
$ret = $bindVars = array();
if( @$this->verifyId( $pListHash['user_id'] ) ) {
$whereSql .= " AND lc.`user_id` = ? ";
$bindVars[] = $pListHash['user_id'];
} elseif( !empty( $pListHash['recent_users'] )) {
$distinct = " DISTINCT ON ( lc.created/86400, uu.`user_id` ) ";
$pListHash['sort_mode'] = 'uu.user_id_desc';
if( @$this->verifyId( $pListHash['gallery_id'] ) ) {
$whereSql .= " AND fg.`gallery_id` = ? ";
$bindVars[] = $pListHash['gallery_id'];
if( !empty( $pListHash['search'] ) ) {
$whereSql .= " AND UPPER(lc.`title`) LIKE ? ";
$bindVars[] = '%'. strtoupper( $pListHash['search'] ). '%';
if( !empty( $pListHash['max_age'] ) && is_numeric( $pListHash['max_age'] ) ) {
$whereSql .= " AND lc.`created` > ? ";
$bindVars[] = $pListHash['max_age'];
$this->getServicesSql( 'content_user_collection_function', $selectSql, $joinSql, $whereSql, $bindVars, $this, $pListHash );
if( !empty( $pListHash['recent_images'] )) {
// get images from recent user truncated by day. This is necessary because DISTINCT ON expressions must match initial ORDER BY expressions
$distinct = " DISTINCT ON ( lc.`created`/86400, uu.`user_id` ) ";
$orderby = " ORDER BY lc.`created`/86400 DESC, uu.`user_id`";
} elseif ( !empty( $pListHash['sort_mode'] ) ) {
//converted in prepGetList()
$orderby = " ORDER BY ". $this->mDb->convertSortmode( $pListHash['sort_mode'] ). " ";
$this->getServicesSql( 'content_list_sql_function', $selectSql, $joinSql, $whereSql, $bindVars );
if( !empty( $whereSql ) ) {
$thumbSize = (!empty( $pListHash['size'] ) ? $pListHash['size'] : 'avatar' );
$query = "SELECT $distinct fi.`image_id` AS `hash_key`, fi.*, lf.*, la.attachment_id, lc.*, fg.`gallery_id`, uu.`login`, uu.`real_name` $select $selectSql
INNER JOIN `". BIT_DB_PREFIX. "liberty_attachments` la ON(la.`content_id`=fi.`content_id`)
INNER JOIN `". BIT_DB_PREFIX. "liberty_files` lf ON(la.`foreign_id`=lf.`file_id`)
INNER JOIN `". BIT_DB_PREFIX. "liberty_content` lc ON(fi.`content_id` = lc.`content_id`)
INNER JOIN `". BIT_DB_PREFIX. "users_users` uu ON(uu.`user_id` = lc.`user_id`) $joinSql
LEFT OUTER JOIN `". BIT_DB_PREFIX. "fisheye_gallery_image_map` tfgim2 ON(tfgim2.`item_content_id`=lc.`content_id`)
LEFT OUTER JOIN `". BIT_DB_PREFIX. "fisheye_gallery` fg ON(fg.`content_id`=tfgim2.`gallery_content_id`)
if( $rs = $this->mDb->query( $query, $bindVars, $pListHash['max_records'], $pListHash['offset'], $pListHash['query_cache_time'] ) ) {
while( $row = $rs->fetchRow() ) {
// legacy table data was named storage_path and included a partial path. strip out any path just in case
$row['file_name'] = basename( $row['file_name'] );
$ret[$row['hash_key']] = $row;
$imageId = $row['image_id'];
if( empty( $pListHash['no_thumbnails'] ) ) {
$ret[$imageId]['display_url'] = static::getDisplayUrlFromHash( $row );
$ret[$imageId]['has_machine_name'] = $this->isMachineName( $ret[$imageId]['title'] );
$ret[$imageId]['source_url'] = $this->getStorageUrl( $row ). $row['file_name'];
'default_image' => FISHEYE_PKG_URL. 'image/generating_thumbnails.png',
'type' => $row['mime_type'],
* @return TRUE on success, FALSE on failure
// if we have a loaded gallery, we just use that to work out if we can add comments to this image
return $gGallery->isCommentable();
// @TODO: No idea how to work out if you can add a comment to this image
// for now we'll take the mGalleryPath and use that gallery
$query = "SELECT `pref_value` FROM `". BIT_DB_PREFIX. "liberty_content_prefs` WHERE `content_id` = ? AND `pref_name` = ?";
$ret = ( $this->mDb->getOne( $query, array( $gal['content_id'], 'allow_comments' )) == 'y' );
|