Source for file FisheyeGallery.php
Documentation is available at FisheyeGallery.php
require_once( FISHEYE_PKG_PATH. 'FisheyeImage.php' ); // A gallery is composed of FisheyeImages
define('FISHEYEGALLERY_CONTENT_TYPE_GUID', 'fisheyegallery' );
define( 'FISHEYE_PAGINATION_FIXED_GRID', 'fixed_grid' );
define( 'FISHEYE_PAGINATION_AUTO_FLOW', 'auto_flow' );
define( 'FISHEYE_PAGINATION_POSITION_NUMBER', 'position_number' );
define( 'FISHEYE_PAGINATION_SIMPLE_LIST', 'simple_list' );
define( 'FISHEYE_PAGINATION_MATTEO', 'matteo' );
define( 'FISHEYE_PAGINATION_GALLERIFFIC', 'galleriffic' );
* FisheyeBase extends LibertyMime, which this class doesn't need, but we need a common base class
var $mItems; // Array of FisheyeImage class instances which belong to this gallery
function __construct($pGalleryId = NULL, $pContentId = NULL) {
$this->mGalleryId = (int) $pGalleryId; // Set member variables according to the parameters we were passed
$this->mContentId = (int) $pContentId; // liberty_content.content_id which this gallery references
$this->mItems = array(); // Assume no images (if $pAutoLoad is TRUE we will populate this array later)
// This registers the content type for FishEye galleries
// FYI: Any class which uses a table which inherits from liberty_content should create their own content type(s)
'content_name' => 'Image Gallery',
'content_name_plural' => 'Image Galleries',
'handler_class' => 'FisheyeGallery',
'handler_package' => 'fisheye',
'handler_file' => 'FisheyeGallery.php',
'maintainer_url' => 'http://www.bitweaver.org'
public static function lookup( $pLookupHash ) {
if (!empty($pLookupHash['gallery_id']) && is_numeric($pLookupHash['gallery_id'])) {
if( $lookup = $gBitDb->getRow( "SELECT lc.`content_id`, lc.`content_type_guid` FROM `". BIT_DB_PREFIX. "fisheye_gallery` fg INNER JOIN `". BIT_DB_PREFIX. "liberty_content` lc ON(lc.`content_id`=fg.`content_id`) WHERE `gallery_id`=?", array( $pLookupHash['gallery_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 fg.`gallery_id` = ?";
$whereSql = " WHERE fg.`content_id` = ?";
if ($whereSql) { // If we have some way to know what fisheye_gallery row to load...
$this->getServicesSql( 'content_load_sql_function', $selectSql, $joinSql, $whereSql, $bindVars );
$query = "SELECT fg.*, lc.* $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`
INNER JOIN `". BIT_DB_PREFIX. "liberty_content` lc ON (fg.`content_id` = lc.`content_id`) $joinSql
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`)
if( $rs = $this->mDb->query($query, $bindVars) ) {
$this->mInfo = $rs->fields;
$this->mInfo['creator'] = (isset ( $rs->fields['creator_real_name'] ) ? $rs->fields['creator_real_name'] : $rs->fields['creator_user'] );
$this->mInfo['editor'] = (isset ( $rs->fields['modifier_real_name'] ) ? $rs->fields['modifier_real_name'] : $rs->fields['modifier_user'] );
// Set some basic defaults for how to display a gallery if they're not already set
if (empty($this->mInfo['thumbnail_size'])) {
$this->mInfo['thumbnail_size'] = $this->getPreference( 'fisheye_gallery_default_thumbnail_size', NULL );
if (empty($this->mInfo['rows_per_page'])) {
$this->mInfo['rows_per_page'] = $this->getPreference('fisheye_gallery_default_rows_per_page', FISHEYE_DEFAULT_ROWS_PER_PAGE);
if (empty($this->mInfo['cols_per_page'])) {
$this->mInfo['cols_per_page'] = $this->getPreference('fisheye_gallery_default_cols_per_page', FISHEYE_DEFAULT_COLS_PER_PAGE);
if (empty($this->mInfo['access_answer'])) {
$this->mInfo['access_answer'] = '';
$this->mInfo['num_pages'] = $this->mDb->getOne( "SELECT COUNT( distinct( floor(`item_position`) ) ) FROM `". BIT_DB_PREFIX. "fisheye_gallery_image_map` WHERE gallery_content_id=?", array( $this->mContentId ) );
$this->mInfo['images_per_page'] = ($this->mInfo['cols_per_page'] * $this->mInfo['rows_per_page']);
$this->mInfo['num_pages'] = (int) ($this->mInfo['num_images'] / $this->mInfo['images_per_page'] + ($this->mInfo['num_images'] % $this->mInfo['images_per_page'] == 0 ? 0 : 1));
// this code sucks but works - XOXO spiderr
$query = "SELECT fgim.*, fi.`image_id`, lf.`file_name`, lf.`user_id`, lf.`mime_type`, la.`attachment_id`
INNER JOIN `". BIT_DB_PREFIX. "fisheye_image` fi ON ( fi.`content_id`=fgim.`item_content_id` )
INNER JOIN `". BIT_DB_PREFIX. "liberty_attachments` la ON ( fi.`content_id`=la.`content_id` )
INNER JOIN `". BIT_DB_PREFIX. "liberty_files` lf ON ( lf.`file_id`=la.`foreign_id` )
WHERE fgim.`gallery_content_id` = ?
ORDER BY fgim.`item_position`, fi.`content_id` ";
if( $rs = $this->mDb->query($query, array( $this->mContentId ) ) ) {
for( $i = 0; $i < count( $rows ); $i++ ) {
if( $rows[$i]['image_id'] == $pCurrentImageId ) {
$this->mInfo['previous_image_id'] = $rows[$i- 1]['image_id'];
'file_name' => $rows[$i- 1]['file_name'],
'source_file' => $tempImage->getSourceFile( $rows[$i- 1] ),
if( $i + 1 < count( $rows ) ) {
$this->mInfo['next_image_id'] = $rows[$i+ 1]['image_id'];
'file_name' => $rows[$i+ 1]['file_name'],
'source_file' => $tempImage->getSourceFile( $rows[$i+ 1] ),
function loadImages( $pPage=- 1, $pImagesPerPage=- 1) {
global $gLibertySystem, $gBitSystem, $gBitUser;
$whereSql = $selectSql = $joinSql = $orderSql = '';
$rowCount = $offset = NULL;
$this->getServicesSql( 'content_list_sql_function', $selectSql, $joinSql, $whereSql, $bindVars );
if( $gBitSystem->isFeatureActive( 'fisheye_gallery_default_sort_mode' ) ) {
$orderSql = ", ". $this->mDb->convertSortmode( $gBitSystem->getConfig( 'fisheye_gallery_default_sort_mode' ) );
$orderSql = ", fgim.`item_content_id`";
// load for just a single page
$query = "SELECT DISTINCT(FLOOR(`item_position`))
WHERE gallery_content_id=?
ORDER BY floor(item_position)";
$mantissa = $this->mDb->getOne( $query, array( $this->mContentId ), 1, ($pPage - 1) );
// gallery image order with no positions set will have NULL mantissa, and all images will be shown
$whereSql .= " AND floor(item_position)=? ";
$rowCount = $this->getField( 'rows_per_page' ) * $this->getField( 'cols_per_page' );
$offset = $rowCount * ($pPage - 1);
$rowCount = $pImagesPerPage;
$offset = $rowCount * ($pPage - 1);
$query = "SELECT fgim.*, lc.`user_id`, lct.*, ufm.`favorite_content_id` AS is_favorite $selectSql
INNER JOIN `". BIT_DB_PREFIX. "liberty_content` lc ON ( lc.`content_id`=fgim.`item_content_id` )
INNER JOIN `". BIT_DB_PREFIX. "liberty_content_types` lct ON ( lct.`content_type_guid`=lc.`content_type_guid` )
LEFT OUTER JOIN `". BIT_DB_PREFIX. "users_favorites_map` ufm ON ( ufm.`favorite_content_id`=lc.`content_id` AND lc.`user_id`=ufm.`user_id` )
WHERE fgim.`gallery_content_id` = ? $whereSql
ORDER BY fgim.`item_position` $orderSql";
$rs = $this->mDb->query($query, $bindVars, $rowCount, $offset);
foreach ($rows as $row) {
if( $gBitSystem->isPackageActive( 'gatekeeper' ) ) {
$pass = $gBitUser->hasPermission( 'p_fisheye_admin' ) || !@$this->verifyId( $row['security_id'] ) || ( $row['user_id'] == $gBitUser->mUserId ) || @$this->verifyId( $_SESSION['gatekeeper_security'][$row['security_id']] );
$type = $gLibertySystem->mContentTypes[$row['content_type_guid']];
require_once( constant( strtoupper( $type['handler_package'] ). '_PKG_PATH' ). $type['handler_file'] );
$item = new $type['handler_class']( NULL, $row['item_content_id'] );
$item->loadThumbnail( $this->mInfo['thumbnail_size'] );
$item->mInfo['item_position'] = $row['item_position'];
$this->mItems[$row['item_content_id']] = $item;
global $gLibertySystem, $gBitSystem, $gBitUser;
$whereSql = $selectSql = $joinSql = $orderSql = '';
$this->getServicesSql( 'content_list_sql_function', $selectSql, $joinSql, $whereSql, $bindVars );
if( $gBitSystem->isFeatureActive( 'fisheye_gallery_default_sort_mode' ) ) {
$orderSql = ", ". $this->mDb->convertSortmode( $gBitSystem->getConfig( 'fisheye_gallery_default_sort_mode' ) );
$orderSql = ", fgim.`item_content_id`";
$query = "SELECT lc.`content_id` AS `has_key`, fgim.*, lc.*, lct.*, fi.`image_id`, ufm.`favorite_content_id` AS is_favorite $selectSql
INNER JOIN `". BIT_DB_PREFIX. "liberty_content` lc ON ( lc.`content_id`=fgim.`item_content_id` )
INNER JOIN `". BIT_DB_PREFIX. "liberty_content_types` lct ON ( lct.`content_type_guid`=lc.`content_type_guid` )
LEFT OUTER JOIN `". BIT_DB_PREFIX. "fisheye_image` fi ON ( fgim.`item_content_id`=fi.`content_id` )
LEFT OUTER JOIN `". BIT_DB_PREFIX. "users_favorites_map` ufm ON ( ufm.`favorite_content_id`=lc.`content_id` AND lc.`user_id`=ufm.`user_id` )
WHERE fgim.`gallery_content_id` = ? $whereSql
ORDER BY fgim.`item_position` $orderSql";
$ret = $this->mDb->getAssoc($query, $bindVars, $rows, $offset);
if( $ret = parent::exportHash() ) {
if( $exp = $this->mItems[$key]->exportHash( $pPaginate ) ) {
$ret['content']['page'][$this->getItemPage($key)][] = $exp;
$ret['content'][] = $this->mItems[$key]->exportHash( $pPaginate );
if( empty( $this->mPaginationLookup ) ) {
$this->mPaginationLookup = $this->mDb->getAssoc( "SELECT `item_content_id`, floor(`item_position`) FROM `". BIT_DB_PREFIX. "fisheye_gallery_image_map` WHERE `gallery_content_id`=?", array( $this->mContentId ) );
if( !empty( $this->mPaginationLookup[$pItemContentId] ) ) {
$ret = $this->mPaginationLookup[$pItemContentId];
if( !empty( $this->mInfo['preview_content'] ) ) {
$ret = $this->mInfo['preview_content']->mInfo;
// override $this->mInfo['preview_content']->mInfo['display_url'] so we don't drive directly to the image
$whereSql = $selectSql = $joinSql = $orderSql = '';
$paramHash['no_fatal'] = TRUE;
$this->getServicesSql( 'content_list_sql_function', $selectSql, $joinSql, $whereSql, $bindVars, NULL, $paramHash );
$query = 'SELECT COUNT(*) AS "count"
INNER JOIN `". BIT_DB_PREFIX. "liberty_content` lc ON ( lc.`content_id`=fgim.`item_content_id` )
$joinSql WHERE `gallery_content_id` = ? $whereSql";
$rs = $this->mDb->query($query, $bindVars);
$ret = $rs->fields['count'];
if (empty($pStorageHash['rows_per_page'])) {
$pStorageHash['rows_per_page'] = $gBitSystem->getConfig('fisheye_gallery_default_rows_per_page', (!empty($this->mInfo['rows_per_page']) ? $this->mInfo['rows_per_page'] : FISHEYE_DEFAULT_ROWS_PER_PAGE));
if (empty($pStorageHash['cols_per_page'])) {
$pStorageHash['cols_per_page'] = $gBitSystem->getConfig('fisheye_gallery_default_cols_per_page', (!empty($this->mInfo['cols_per_page']) ? $this->mInfo['cols_per_page'] : FISHEYE_DEFAULT_COLS_PER_PAGE));
if (empty($pStorageHash['thumbnail_size'])) {
$pStorageHash['thumbnail_size'] = $gBitSystem->getConfig('fisheye_gallery_default_thumbnail_size', (!empty($this->mInfo['thumbnail_size']) ? $this->mInfo['thumbnail_size'] : NULL ));
if (empty($pStorageHash['title'])) {
$this->mErrors[] = "You must specify a title for this image gallery";
$this->mItems[$key]->generateThumbnails();
if( !$this->getField( 'thumbnail_content_id' ) ) {
return( $this->getField( 'thumbnail_content_id' ) );
if( empty( $this->mInfo['preview_content'] ) ) {
return $this->mInfo['preview_content']->getThumbnailUri( $pSize );
function getThumbnailUrl( $pSize = 'small', $pInfoHash = NULL, $pSecondaryId = NULL, $pDefault= TRUE ) {
if( empty( $this->mInfo['preview_content'] ) ) {
return $this->mInfo['preview_content']->getThumbnailUrl( $pSize );
function getThumbnailImage( $pContentId= NULL, $pThumbnailContentId= NULL, $pThumbnailContentType= NULL ) {
global $gLibertySystem, $gBitUser;
if( !@$this->verifyId( $pThumbnailContentId ) ) {
$pThumbnailContentId = $this->mInfo['preview_content_id'];
if( $this->mDb->isAdvancedPostgresEnabled() ) {
$bindVars = array( $pContentId );
if( !$gBitUser->isAdmin() ) {
$whereSql = " AND (cgm.`security_id` IS NULL OR lc.`user_id`=?) ";
$bindVars[] = $gBitUser->mUserId;
$query = "SELECT COALESCE( fg.`preview_content_id`, lc.`content_id` ) AS `content_id`, lc.`content_type_guid`
FROM connectby('`". BIT_DB_PREFIX. "fisheye_gallery_image_map`', '`item_content_id`', '`gallery_content_id`', ?, 0, '/') AS t(`cb_item_content_id` int, `cb_parent_content_id` int, `level` int, `branch` text)
INNER JOIN liberty_content lc ON(content_id=cb_item_content_id)
LEFT OUTER JOIN `". BIT_DB_PREFIX. "gatekeeper_security_map` cgm ON (cgm.`content_id`=lc.`content_id`), `". BIT_DB_PREFIX. "fisheye_gallery` fg
WHERE `cb_parent_content_id`=fg.`content_id` $whereSql "; // ORDER BY RANDOM() is DOG slow (seq scans)
if( $row = $this->mDb->getRow( $query, $bindVars ) ) {
$pThumbnailContentType = $row['content_type_guid'];
$pThumbnailContentId = $row['content_id'];
$query = "SELECT fgim.`item_content_id`, lc.`content_type_guid`
FROM `". BIT_DB_PREFIX. "fisheye_gallery_image_map` fgim INNER JOIN `". BIT_DB_PREFIX. "liberty_content` lc ON ( fgim.`item_content_id`=lc.`content_id` )
WHERE fgim.`gallery_content_id` = ?
ORDER BY ". $this->mDb->convertSortmode('random');
$rs = $this->mDb->query($query, array( $pContentId ), 1);
$pThumbnailContentId = $rs->fields['item_content_id'];
$pThumbnailContentType = $rs->fields['content_type_guid'];
if( @$this->verifyId( $pThumbnailContentId ) ) {
if( is_a( $ret, 'FisheyeGallery' ) ) {
//recurse down in to find the first image
if( $ret = $ret->getThumbnailImage() ) {
$this->mInfo['thumbnail_content_id'] = $ret->getField( 'content_id' );
$this->mInfo['thumbnail_content_id'] = $pThumbnailContentId;
$this->mInfo['preview_content'] = &$this->mPreviewImage;
$this->mInfo['image_file'] = &$this->mPreviewImage->mInfo['image_file'];
$query = "UPDATE `". BIT_DB_PREFIX. "fisheye_gallery` SET `preview_content_id` = ? WHERE `gallery_id`= ?";
$rs = $this->mDb->query($query, array($pContentId, $this->mGalleryId));
$this->mInfo['preview_content_id'] = $pContentId;
function store(&$pStorageHash) {
$this->mDb->StartTrans();
SET `rows_per_page` = ?, `cols_per_page` = ?, `thumbnail_size` = ?
$bindVars = array($pStorageHash['rows_per_page'], $pStorageHash['cols_per_page'], $pStorageHash['thumbnail_size'], $this->mGalleryId);
$query = "INSERT INTO `". BIT_DB_PREFIX. "fisheye_gallery` (`gallery_id`, `content_id`, `rows_per_page`, `cols_per_page`, `thumbnail_size`) VALUES (?,?,?,?,?)";
$bindVars = array($this->mGalleryId, $this->mContentId, $pStorageHash['rows_per_page'], $pStorageHash['cols_per_page'], $pStorageHash['thumbnail_size']);
$rs = $this->mDb->query($query, $bindVars);
$this->mDb->CompleteTrans();
$this->mDb->RollbackTrans();
$this->mErrors[] = "There were errors while attempting to save this gallery";
$this->mErrors[] = "There were errors while attempting to save this gallery";
$query = "DELETE FROM `". BIT_DB_PREFIX. "fisheye_gallery_image_map`
WHERE `item_content_id`=? AND `gallery_content_id`=?";
$rs = $this->mDb->query($query, array($pContentId, $this->mContentId ) );
* Adds a new item (image or gallery) to this gallery. We check to make sure we are not a member
* of this gallery and this gallery is not a member of the new item to avoid infinite recursion scenarios
* @return boolean wheter or not the item was added
function addItem( $pContentId, $pPosition= NULL ) {
$query = "INSERT INTO `". BIT_DB_PREFIX. "fisheye_gallery_image_map` (`item_content_id`, `gallery_content_id`, `item_position`) VALUES (?,?,?)";
$rs = $this->mDb->query($query, array($pContentId, $this->mContentId, $pPosition ) );
$query = "UPDATE `". BIT_DB_PREFIX. "liberty_content` SET `last_modified`=? WHERE `content_id`=?";
$rs = $this->mDb->query( $query, array( $gBitSystem->getUTCTime(), $this->mContentId ) );
function expunge( $pRecursiveDelete = FALSE ) {
$this->mDb->StartTrans();
if( $pRecursiveDelete ) {
$this->mItems[$key]->expunge( $pRecursiveDelete );
} elseif( is_a( $this->mItems[$key], 'FisheyeImage' ) ) {
// make sure we have a valid content_id before we exec
$query = "SELECT COUNT(`item_content_id`) AS `other_gallery`
WHERE `item_content_id`=? AND `gallery_content_id`!=?";
if( !($inOtherGallery = $this->mDb->getOne($query, array($this->mItems[$key]->mContentId, $this->mContentId ) )) ) {
$this->mItems[$key]->expunge();
$query = "DELETE FROM `". BIT_DB_PREFIX. "fisheye_gallery_image_map` WHERE `gallery_content_id`=?";
$query = "DELETE FROM `". BIT_DB_PREFIX. "fisheye_gallery_image_map` WHERE `item_content_id`=?";
$query = "DELETE FROM `". BIT_DB_PREFIX. "fisheye_gallery` WHERE `content_id`=?";
$this->mDb->CompleteTrans();
$this->mDb->RollbackTrans();
$query = "SELECT COUNT(`gallery_id`) AS `gcount`
if ($rs->fields['gcount'] > 0)
* Returns the layout of the gallery accounting for various defaults
* @return the layout string preference
// FISHEYE_PAGINATION_MATTEO => 'Matteo',
* Returns include file that will setup the object for rendering
* @return the fully specified path to file to be included
return FISHEYE_PKG_PATH. "display_fisheye_gallery_inc.php";
* Returns template file used for display
* @return the fully specified path to file to be included
return 'bitpackage:fisheye/view_gallery.tpl';
* Function that returns link to display a piece of content
* @param pGalleryId id of gallery to link
* @return the url to display the gallery.
if( BitBase::verifyIdParameter( $pParamHash, 'gallery_id' ) ) {
if( $gBitSystem->isFeatureActive( 'pretty_urls' ) ) {
$ret .= 'gallery'. $path. '/'. $pParamHash['gallery_id'];
$ret .= 'view.php?gallery_id='. $pParamHash['gallery_id'];
if( !empty( $pHash['path'] ) ) {
$ret .= '&gallery_path='. $pParamHash['path'];
} elseif( @BitBase::verifyId( $pParamHash['content_id'] ) ) {
$ret = FISHEYE_PKG_URL. 'view.php?content_id='. $pParamHash['content_id'];
if( $this->mDb->isAdvancedPostgresEnabled() ) {
if( !empty( $pListHash['contain_item'] ) ) {
$selectSql = " , tfgim3.`item_content_id` AS `in_gallery` ";
$joinSql .= " LEFT OUTER JOIN `". BIT_DB_PREFIX. "fisheye_gallery_image_map` tfgim3 ON (tfgim3.`gallery_content_id`=lc.`content_id`) AND tfgim3.`item_content_id`=? ";
$bindVars[] = $pListHash['contain_item'];
$containVars[] = $pListHash['contain_item'];
if( isset ( $pListHash['contain_item'] ) ) {
// contain item might have squeaked in as 0, clear our from pListHash
unset ( $pListHash['contain_item'] );
foreach( $pListHash as $key=> $val ) {
$whereSql .= " $key=? AND ";
$query = "SELECT lc.`content_id` AS `hash_key`, fg.*, lc.* $selectSql
INNER JOIN `". BIT_DB_PREFIX. "liberty_content` lc ON(fg.`content_id`=lc.`content_id`)
WHERE $whereSql NOT EXISTS (SELECT gallery_content_id FROM fisheye_gallery_image_map tfgim2 WHERE tfgim2.item_content_id=lc.content_id)
$rootContent = $gBitDb->GetAssoc( $query, $bindVars );
$query = "SELECT branch AS hash_key, * $selectSql
FROM connectby('`". BIT_DB_PREFIX. "fisheye_gallery_image_map`', '`item_content_id`', '`gallery_content_id`', ?, 0, '/') AS t(cb_item_content_id int,cb_gallery_content_id int, level int, branch text)
INNER JOIN `". BIT_DB_PREFIX. "fisheye_gallery` fg ON (fg.`content_id`=cb_item_content_id)
INNER JOIN `". BIT_DB_PREFIX. "liberty_content` lc ON(lc.`content_id`=fg.`content_id`)
ORDER BY branch, lc.`title`";
if( !empty( $containVars ) ) {
$splitVars[] = $containVars[0];
} else if ( $this->mDb->mType == 'firebird' ) {
if( !empty( $pListHash['contain_item'] ) ) {
$selectSql = " , tfgim3.`item_content_id` AS `in_gallery` ";
$joinSql .= " LEFT OUTER JOIN `". BIT_DB_PREFIX. "fisheye_gallery_image_map` tfgim3 ON (tfgim3.`gallery_content_id`=lc.`content_id`) AND tfgim3.`item_content_id`=? ";
$bindVars[] = $pListHash['contain_item'];
$containVars[] = $pListHash['contain_item'];
$this->getServicesSql( 'content_list_sql_function', $selectSql, $joinSql, $whereSql, $bindVars );
if( isset ( $pListHash['contain_item'] ) ) {
// contain item might have squeaked in as 0, clear our from pListHash
unset ( $pListHash['contain_item'] );
foreach( $pListHash as $key=> $val ) {
$whereSql .= " AND lc.$key=? ";
SELECT B.`content_id` AS gallery_content_id, B.`content_id` AS item_content_id, 0 AS BLEVEL, CAST( lcp.`title` AS VARCHAR(255) ) AS BRANCH, 0 AS gallery_parent_id
INNER JOIN `". BIT_DB_PREFIX. "liberty_content` lcp ON(lcp.`content_id`=B.`content_id`)
WHERE NOT EXISTS (SELECT gallery_content_id FROM fisheye_gallery_image_map tfgim2 WHERE tfgim2.item_content_id=B.content_id)
SELECT `item_content_id` AS gallery_content_id, `item_content_id`, G.BLEVEL + 1, G.BRANCH || '/' || `item_content_id` AS BRANCH, `gallery_content_id` AS gallery_parent_id
ON G1.`gallery_content_id` = G.`item_content_id`
INNER JOIN `". BIT_DB_PREFIX. "liberty_content` lcg1 ON(lcg1.`content_id`=`item_content_id`) and lcg1.`content_type_guid` = 'fisheyegallery'
SELECT T.BRANCH AS hash_key, T.BLEVEL, fg.*, lc.* $selectSql
INNER JOIN `". BIT_DB_PREFIX. "fisheye_gallery` fg ON (fg.`content_id`=T.`gallery_content_id`)
INNER JOIN `". BIT_DB_PREFIX. "liberty_content` lc ON (lc.`content_id`=T.`item_content_id`)
LEFT OUTER JOIN `". BIT_DB_PREFIX. "fisheye_gallery_image_map` fgimo ON (fgimo.`gallery_content_id`=T.gallery_parent_id) AND fgimo.`item_content_id`=T.gallery_content_id
WHERE lc.`content_type_guid` = 'fisheyegallery' $whereSql
ORDER BY T.BRANCH, fgimo.`item_position`";
if( !empty( $bindVars ) ) {
// this needs replacing with a more suitable list query ...
$pListHash['show_empty'] = TRUE;
$galList = $this->getList( $pListHash );
foreach( $galList as $galId => $gal ) {
$ret[$gal['content_id']] = $gal;
if( !empty( $pTree[$k]['children'] ) ) {
uasort( $pTree, array( 'FisheyeGallery', 'getTreeSortCmp' ) );
return strcmp( $a['content']['title'], $b['content']['title'] );
if( count( $pPath ) > 0 ) {
if( empty( $pRet[$popId]['children'] ) ) {
$pRet[$popId]['children'] = array();
$pRet[$popId]['content'] = $pTreeHash;
// Generate a nested ul list of listed galleries
function generateList( $pListHash, $pOptions, $pLocate = FALSE ) {
foreach( array( 'class', 'name', 'id', 'onchange' ) as $key ) {
if( !empty( $pOptions[$key] ) ) {
$class .= ' '. $pOptions[$key];
$ret .= " $key=\"$pOptions[$key]\" ";
$ret .= ' class="'. $class. '">';
// Helper method for generateMenu. See that method. Is Recursive
$class = !empty( $pOptions['radio_checkbox'] ) ? 'checkbox' : '';
$ret .= '<li id="fisheyegallery'. $pHash[$conId]['content']['gallery_id']. '" gallery_id="'. $pHash[$conId]['content']['gallery_id']. '" ';
if( !empty( $pOptions['item_attributes'] ) ) {
foreach( $pOptions['item_attributes'] as $key=> $value ) {
$ret .= " $key=\"$value\" ";
$ret .= ' class="'. $class. '"><label>';
if ( $pLocate || $pHash[$conId]['content']['content_id'] != $this->mContentId ) {
if( !empty( $pOptions['radio_checkbox'] ) ) {
$ret .= '<input type="checkbox" name="gallery_additions[]" value="'. $pHash[$conId]['content']['gallery_id']. '" ';
if( !empty( $pHash[$conId]['content']['in_gallery'] ) || $pHash[$conId]['content']['content_id'] == $this->mContentId ) {
$ret .= ' checked="checked" ';
if ( $pHash[$conId]['content']['content_id'] == $this->mContentId
or ( isset ( $pHash[$conId]['content']['in_gallery'] ) and $pHash[$conId]['content']['in_gallery'] ) ) {
$ret .= '<span class="active">'. htmlspecialchars( $pHash[$conId]['content']['title'] ). '</span>';
if( !empty( $pHash[$conId]['children'] ) ) {
// Generate a select drop menu of listed galleries
function generateMenu( $pListHash, $pOptions, $pLocate= NULL ) {
$ret = "<select class='form-control' ";
foreach( array( 'class', 'name', 'id', 'onchange' ) as $key ) {
if( !empty( $pOptions[$key] ) ) {
$ret .= " $key=\"$pOptions[$key]\" ";
$ret .= !empty( $pOptions['first_option'] ) ? $pOptions['first_option'] : '';
// Helper method for generateMenu. See that method. Is Recursive
$ret .= '<option gallery_id="'. $pHash[$conId]['content']['gallery_id']. '" value="'. $pHash[$conId]['content']['gallery_id']. '"';
if( !empty( $pOptions['item_attributes'] ) ) {
foreach( $pOptions['item_attributes'] as $key=> $value ) {
$ret .= " $key=\"$value\" ";
if ( $pLocate && $pLocate == $pHash[$conId]['content']['gallery_id'] ) {
$ret .= ' selected="selected" ';
$ret .= ' >'. ($pPrefix? $pPrefix. '» ': ''). htmlspecialchars( $pHash[$conId]['content']['title'] ). '</option>';
if( !empty( $pHash[$conId]['children'] ) ) {
global $gBitUser,$gBitSystem, $gBitDbType;
$pListHash['valid_sort_modes'] = array( 'real_name', 'login', 'hits', 'title', 'created', 'last_modified', 'last_hit', 'event_time', 'ip' );
$selectSql = $joinSql = $whereSql = $sortSql = '';
if( $gBitDbType == 'mysql' ) {
// loser mysql without subselects
if( !empty( $pListHash['root_only'] ) ) {
$joinSql .= " LEFT OUTER JOIN `". BIT_DB_PREFIX. "fisheye_gallery_image_map` tfgim2 ON (tfgim2.`item_content_id`=lc.`content_id`)";
$whereSql .= ' AND tfgim2.`item_content_id` IS NULL ';
if( !empty( $pListHash['contain_item'] ) ) {
$selectSql = " , tfgim3.`item_content_id` AS `in_gallery` ";
$joinSql .= " LEFT OUTER JOIN `". BIT_DB_PREFIX. "fisheye_gallery_image_map` tfgim3 ON (tfgim3.`gallery_content_id`=lc.`content_id`) AND tfgim3.`item_content_id`=? ";
$bindVars[] = $pListHash['contain_item'];
if( @$this->verifyId( $pListHash['user_id'] ) ) {
$whereSql .= " AND lc.`user_id` = ? ";
$bindVars[] = (int) $pListHash['user_id'];
if( !empty( $pListHash['find'] ) ) {
$whereSql .= " AND UPPER( lc.`title` ) LIKE ? ";
$bindVars[] = '%'. strtoupper( $pListHash['find'] ). '%';
if( !empty( $pListHash['show_public'] ) ) {
$joinSql .= " LEFT OUTER JOIN `". BIT_DB_PREFIX. "liberty_content_prefs` lcp ON( lcp.`content_id`=lc.`content_id` )";
$whereSql .= " OR ( lcp.`pref_name`=? AND lcp.`pref_value`=? ) ";
$bindVars[] = 'is_public';
if( $gBitDbType != 'mysql' ) {
// weed out empty galleries if we don't need them. DO NOT get clever and change the IN and EXISTS choices here.
if( empty( $pListHash['show_empty'] ) ) {
$whereSql .= " AND fg.`content_id` IN (SELECT `gallery_content_id` FROM `". BIT_DB_PREFIX. "fisheye_gallery_image_map` fgim WHERE fgim.`gallery_content_id`=fg.`content_id`)";
if( !empty( $pListHash['root_only'] ) ) {
$whereSql .= " AND NOT EXISTS (SELECT `gallery_content_id` FROM `". BIT_DB_PREFIX. "fisheye_gallery_image_map` tfgim2 WHERE tfgim2.`item_content_id`=lc.`content_id`)";
// weed out empty galleries if we don't need them
if( empty( $pListHash['show_empty'] ) ) {
$mapJoin = "INNER JOIN `". BIT_DB_PREFIX. "fisheye_gallery_image_map` fgim ON (fgim.`gallery_content_id`=lc.`content_id`)";
if ( !empty( $pListHash['sort_mode'] ) ) {
//converted in prepGetList()
$sortSql .= " ORDER BY ". $this->mDb->convertSortmode( $pListHash['sort_mode'] ). " ";
// Putting in the below hack because mssql cannot select distinct on a text blob column.
$selectSql .= $gBitDbType == 'mssql' ? " ,CAST(lc.`data` AS VARCHAR(250)) as `data` " : " ,lc.`data` ";
$this->getServicesSql( 'content_list_sql_function', $selectSql, $joinSql, $whereSql, $bindVars );
if( !empty( $whereSql ) ) {
$query = "SELECT fg.`gallery_id` AS `hash_key`, fg.*,
lc.`user_id`, lc.`modifier_user_id`, lc.`created`, lc.`last_modified`,
lc.`content_type_guid`, lc.`format_guid`, lch.`hits`, lch.`last_hit`, lc.`event_time`, lc.`version`,
lc.`lang_code`, lc.`title`, lc.`ip`, uu.`login`, uu.`real_name`, plc.`content_type_guid` AS `preview_content_type_guid`
INNER JOIN `". BIT_DB_PREFIX. "liberty_content` lc ON (fg.`content_id` = lc.`content_id`)
INNER JOIN `". BIT_DB_PREFIX. "users_users` uu ON (uu.`user_id` = lc.`user_id`)
LEFT JOIN `". BIT_DB_PREFIX. "liberty_content_hits` lch ON (lch.`content_id` = lc.`content_id`)
LEFT OUTER JOIN `". BIT_DB_PREFIX. "liberty_content` plc ON (fg.`preview_content_id` = plc.`content_id`)
if( $rs = $this->mDb->query( $query, $bindVars, $pListHash['max_records'], $pListHash['offset'] ) ) {
if( empty( $pListHash['no_thumbnails'] ) ) {
$thumbsize = !empty( $pListHash['thumbnail_size'] ) ? $pListHash['thumbnail_size'] : 'small';
$data[$galleryId]['display_url'] = static::getDisplayUrlFromHash( $data[$galleryId] );
$data[$galleryId]['display_uri'] = static::getDisplayUriFromHash( $data[$galleryId] );
if( $thumbImage = $this->getThumbnailImage( $data[$galleryId]['content_id'], $data[$galleryId]['preview_content_id'], $data[$galleryId]['preview_content_type_guid'] ) ) {
$data[$galleryId]['thumbnail_url'] = $thumbImage->getThumbnailUrl( $thumbsize );
$data[$galleryId]['thumbnail_uri'] = $thumbImage->getThumbnailUri( $thumbsize );
} elseif( !empty( $pListHash['show_empty'] ) ) {
$data[$galleryId]['thumbnail_url'] = FISHEYE_PKG_URL. 'image/no_image.png';
unset ( $data[$galleryId] );
$query_c = "SELECT COUNT( fg.`gallery_id` )
INNER JOIN `". BIT_DB_PREFIX. "liberty_content` lc ON (fg.`content_id` = lc.`content_id` )
INNER JOIN `". BIT_DB_PREFIX. "users_users` uu ON (uu.`user_id` = lc.`user_id`)
LEFT OUTER JOIN `". BIT_DB_PREFIX. "liberty_content` ptc ON( fg.`preview_content_id`=ptc.`content_id` )
$cant = $this->mDb->getOne( $query_c, $bindVars );
// add all pagination info to $ret
$pListHash['cant'] = $cant;
$filename = tempnam(TEMP_PKG_PATH,"galleryzip");
if( $zip->open ($filename, ZIPARCHIVE::OVERWRITE) !== TRUE ){
$this->mErrors['download'] = "Unable to create zip file";
$outputFileTitle = str_replace('"','\\"',$outputFileTitle);
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
Header ("Content-disposition: attachment; filename=\"". $outputFileTitle. ".zip\"");
header('Content-Transfer-Encoding: binary');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
Header ("Content-Length: ". filesize( $filename ) );
return '<i class="icon-camera"></i>';
foreach ( $gallery->mItems as $item ){
if( is_a( $item , 'FisheyeImage' ) ){
$pZip->addFile($sourcePath, $pPath. $title. substr($sourcePath,strrpos($sourcePath,'.')) );
}elseif ( is_a( $item , 'FisheyeGallery' ) ){
|