Overview

Packages

  • admin
  • classes
    • media
  • CodeIgniter
    • Libraries
  • core
  • functions
  • JSMin
  • None
  • OpenID
  • PHP
  • PHPMailer
  • plugins
    • admin
    • development
    • feed
    • mail
    • media
    • misc
    • seo
    • spam
    • uploader
    • users
    • zenpage
    • zenphoto
      • news
  • Services
    • JSON

Classes

  • _zp_captcha
  • _zp_HTML_cache
  • admin_approval
  • Album
  • AlbumBase
  • AlbumZip
  • AMFReader
  • AMFStream
  • AnyFile
  • AnyFile_Options
  • Auth_OpenID
  • Auth_OpenID_AlreadySigned
  • Auth_OpenID_AssociateRequest
  • Auth_OpenID_Association
  • Auth_OpenID_AuthRequest
  • Auth_OpenID_AX
  • Auth_OpenID_AX_AttrInfo
  • Auth_OpenID_AX_Error
  • Auth_OpenID_AX_FetchRequest
  • Auth_OpenID_AX_FetchResponse
  • Auth_OpenID_AX_KeyValueMessage
  • Auth_OpenID_AX_Message
  • Auth_OpenID_AX_StoreRequest
  • Auth_OpenID_AX_StoreResponse
  • Auth_OpenID_BcMathWrapper
  • Auth_OpenID_CancelResponse
  • Auth_OpenID_CheckAuthRequest
  • Auth_OpenID_CheckIDRequest
  • Auth_OpenID_Consumer
  • Auth_OpenID_ConsumerResponse
  • Auth_OpenID_CryptUtil
  • Auth_OpenID_DatabaseConnection
  • Auth_OpenID_Decoder
  • Auth_OpenID_DiffieHellman
  • Auth_OpenID_DiffieHellmanSHA1ConsumerSession
  • Auth_OpenID_DiffieHellmanSHA1ServerSession
  • Auth_OpenID_DiffieHellmanSHA256ConsumerSession
  • Auth_OpenID_DiffieHellmanSHA256ServerSession
  • Auth_OpenID_DumbStore
  • Auth_OpenID_Encoder
  • Auth_OpenID_EncodingError
  • Auth_OpenID_Extension
  • Auth_OpenID_FailureResponse
  • Auth_OpenID_FileStore
  • Auth_OpenID_GenericConsumer
  • Auth_OpenID_GmpMathWrapper
  • Auth_OpenID_KVForm
  • Auth_OpenID_MalformedReturnURL
  • Auth_OpenID_MalformedTrustRoot
  • Auth_OpenID_Mapping
  • Auth_OpenID_MathLibrary
  • Auth_OpenID_MDB2Store
  • Auth_OpenID_MemcachedStore
  • Auth_OpenID_Message
  • Auth_OpenID_MySQLStore
  • Auth_OpenID_NamespaceMap
  • Auth_OpenID_NoReturnToError
  • Auth_OpenID_OpenIDStore
  • Auth_OpenID_PAPE_Request
  • Auth_OpenID_PAPE_Response
  • Auth_OpenID_Parse
  • Auth_OpenID_PlainTextConsumerSession
  • Auth_OpenID_PlainTextServerSession
  • Auth_OpenID_PostgreSQLStore
  • Auth_OpenID_Request
  • Auth_OpenID_Server
  • Auth_OpenID_ServerError
  • Auth_OpenID_ServerErrorContainer
  • Auth_OpenID_ServerRequest
  • Auth_OpenID_ServerResponse
  • Auth_OpenID_ServiceEndpoint
  • Auth_OpenID_ServiceEndpointLoader
  • Auth_OpenID_SessionNegotiator
  • Auth_OpenID_SetupNeededResponse
  • Auth_OpenID_Signatory
  • Auth_OpenID_SigningEncoder
  • Auth_OpenID_SQLiteStore
  • Auth_OpenID_SQLStore
  • Auth_OpenID_SRegBase
  • Auth_OpenID_SRegRequest
  • Auth_OpenID_SRegResponse
  • Auth_OpenID_SuccessResponse
  • Auth_OpenID_TrustRoot
  • Auth_OpenID_TypeURIMismatch
  • Auth_OpenID_UntrustedReturnURL
  • Auth_OpenID_WebResponse
  • Auth_Yadis_Discovery
  • Auth_Yadis_DiscoveryResult
  • Auth_Yadis_dom
  • Auth_Yadis_domxml
  • Auth_Yadis_HTTPFetcher
  • Auth_Yadis_HTTPResponse
  • Auth_Yadis_Manager
  • Auth_Yadis_ManagerLoader
  • Auth_Yadis_ParanoidHTTPFetcher
  • Auth_Yadis_ParseHTML
  • Auth_Yadis_PHPSession
  • Auth_Yadis_PlainHTTPFetcher
  • Auth_Yadis_ProxyResolver
  • Auth_Yadis_Service
  • Auth_Yadis_SessionLoader
  • Auth_Yadis_XMLParser
  • Auth_Yadis_XRDS
  • Auth_Yadis_Yadis
  • auto_backup
  • AVCSequenceParameterSetReader
  • bxslider
  • cacheManager
  • cacheManagerFeed
  • CI_jsmin
  • CI_load
  • cloneZenphoto
  • codeIgniter_kludge
  • colorbox
  • Comment
  • comment_form
  • contactformOptions
  • crop_image
  • cycle
  • defaultCodeblocks
  • deprecated_functions
  • DownloadList
  • dynamic_locale
  • dynamicAlbum
  • elFinder_options
  • email_new_user
  • exampleMacros
  • external_auth
  • ExternalFeed
  • externalFeed_options
  • favorites
  • favoritesOptions
  • federated_logon
  • feed
  • fieldExtender
  • flag_thumbnail
  • Gallery
  • galleryArticles
  • getID3
  • getid3_aac
  • getid3_apetag
  • getid3_flv
  • getid3_handler
  • getid3_id3v1
  • getid3_id3v2
  • getid3_lib
  • getid3_lyrics3
  • getid3_mp3
  • getid3_mpeg
  • getid3_quicktime
  • getid3_swf
  • GoogleMap
  • Googlemaps
  • googleVerifyOptions
  • hitcounter
  • HTML
  • htmlmetatags
  • http_auth
  • Image
  • image_effects
  • internal_deprecations
  • ipBlocker
  • jcarousel
  • jPlayer
  • jplayer_options
  • jquery_rating
  • JSMin
  • lib_GD_Options
  • lib_Imagick_Options
  • lib_NoGraphics
  • MediaObject
  • menu_manager
  • MergedRSS
  • MergedRSSOptions
  • mobile
  • Mobile_Detect
  • mobileTheme
  • multipleLayoutOptions
  • null_seo
  • OAuthConsumer
  • OAuthDataStore
  • OAuthRequest
  • OAuthServer
  • OAuthSignatureMethod
  • OAuthSignatureMethod_HMAC_SHA1
  • OAuthSignatureMethod_PLAINTEXT
  • OAuthSignatureMethod_RSA_SHA1
  • OAuthToken
  • OAuthUtil
  • pagedThumbsNav
  • pagedthumbsOptions
  • PclZip
  • PersistentObject
  • PHPMailer
  • PlainText
  • POP3
  • print_album_menu
  • pseudoPlayer
  • publishContent
  • quota_manager
  • reCaptcha
  • ReCaptchaResponse
  • register_user
  • rewriteRules
  • rewriteTokens
  • RSS
  • RSS_internal_deprecations
  • rss_options
  • search_statistics
  • SearchEngine
  • security_logger
  • seo_locale
  • Services_JSON
  • Services_JSON_Error
  • setupexternalFeed
  • setupRSS
  • show_not_loggedin
  • sitemap
  • slideshow
  • SMTP
  • static_html_cache
  • tagsuggest
  • TextObject
  • TextObject_internal_deprecations
  • TextObject_Options
  • ThemeObject
  • themeSwitcher
  • tinymce4Options
  • tinyURL
  • Transientimage
  • tweet
  • TwitterOAuth
  • UploadHandler
  • user_expiry
  • user_groups
  • user_logout_options
  • userAddressFields
  • utf8
  • Video
  • Video_internal_deprecations
  • VideoObject_Options
  • viewer_size_image_options
  • WEBdocs
  • WEBdocs_Options
  • xmpMetadata
  • Zenpage
  • Zenpage_internal_deprecations
  • ZenpageCategory
  • zenpagecms
  • ZenpageItems
  • ZenpageNews
  • ZenpagePage
  • ZenpageRoot
  • Zenphoto_Administrator
  • Zenphoto_Authority
  • zenphoto_org_news
  • zenphoto_seo
  • zenphotoDonate
  • ZipStream
  • zp_PHPMailer
  • zpCaptcha
  • zpFunctions
  • zpLegacySpam
  • zpMutex
  • zpSimpleSpam
  • zpTrivialSpam

Exceptions

  • BadFunctionCallException
  • BadMethodCallException
  • Exception
  • getid3_exception
  • JSMin_UnterminatedCommentException
  • JSMin_UnterminatedRegExpException
  • JSMin_UnterminatedStringException
  • LogicException
  • OAuthExcept
  • phpmailerException

Functions

  • __autoload
  • _escape_xref
  • _recaptcha_aes_encrypt
  • _recaptcha_aes_pad
  • _recaptcha_http_post
  • _recaptcha_mailhide_email_parts
  • _recaptcha_mailhide_urlbase64
  • _recaptcha_qsencode
  • accessAllAlbums
  • add_context
  • addalbumsToDatabase
  • addCategoriesToDatabase
  • addGeoCoord
  • addItem
  • addPagesToDatabase
  • addPluginScript
  • addPluginType
  • addSubalbumMenus
  • admin_album_list
  • admin_securityChecks
  • admin_showupdate
  • adminPageNav
  • adminToolbox
  • albumNumber
  • applyMacros
  • Auth_OpenID_arrangeByType
  • Auth_OpenID_AX_checkAlias
  • Auth_OpenID_AX_toTypeURIs
  • Auth_OpenID_bestMatchingService
  • Auth_OpenID_checkFieldName
  • Auth_OpenID_checkSessionType
  • Auth_OpenID_checkTimestamp
  • Auth_OpenID_detectMathLibrary
  • Auth_OpenID_discover
  • Auth_OpenID_discoverURI
  • Auth_OpenID_discoverWithoutYadis
  • Auth_OpenID_discoverWithYadis
  • Auth_OpenID_discoverXRI
  • Auth_OpenID_extractReturnURL
  • Auth_OpenID_findOPLocalIdentifier
  • Auth_OpenID_getAllAssociationTypes
  • Auth_OpenID_getAllowedReturnURLs
  • Auth_OpenID_getAuthorityPattern
  • Auth_OpenID_getAvailableSessionTypes
  • Auth_OpenID_getDefaultAssociationOrder
  • Auth_OpenID_getDefaultGen
  • Auth_OpenID_getDefaultMod
  • Auth_OpenID_getDefaultNegotiator
  • Auth_OpenID_getEncodedPattern
  • Auth_OpenID_getEncryptedNegotiator
  • Auth_OpenID_getEscapeRE
  • Auth_OpenID_getMathLib
  • Auth_OpenID_getOnlyEncryptedOrder
  • Auth_OpenID_getOpenIDConsumerTypeURIs
  • Auth_OpenID_getOpenIDTypeName
  • Auth_OpenID_getOpenIDTypeURIs
  • Auth_OpenID_getOPOrUserServices
  • Auth_OpenID_getSecretSize
  • Auth_OpenID_getSessionTypes
  • Auth_OpenID_getSupportedAssociationTypes
  • Auth_OpenID_getUnreserved
  • Auth_OpenID_getURIPattern
  • Auth_OpenID_getURLIllegalCharRE
  • Auth_OpenID_HMACSHA1
  • Auth_OpenID_HMACSHA256
  • Auth_OpenID_include_init
  • Auth_OpenID_isError
  • Auth_OpenID_isOpenID1
  • Auth_OpenID_legacy_discover
  • Auth_OpenID_makeOpenIDEndpoints
  • Auth_OpenID_math_extensions
  • Auth_OpenID_mkNonce
  • Auth_OpenID_noMathSupport
  • Auth_OpenID_pct_encoded_replace
  • Auth_OpenID_pct_encoded_replace_unreserved
  • Auth_OpenID_registerNamespaceAlias
  • Auth_OpenID_remove_dot_segments
  • Auth_OpenID_removeNamespaceAlias
  • Auth_OpenID_returnToMatches
  • Auth_OpenID_setNoMathSupport
  • Auth_OpenID_SHA1
  • Auth_OpenID_SHA256
  • Auth_OpenID_splitNonce
  • Auth_OpenID_supportsSReg
  • Auth_OpenID_urinorm
  • Auth_OpenID_verifyReturnTo
  • Auth_Yadis_array_scramble
  • Auth_Yadis_escapeForIRI
  • Auth_Yadis_getCanonicalID
  • Auth_Yadis_getDefaultProxy
  • Auth_Yadis_getEscapeRE
  • Auth_Yadis_getIPrivateChars
  • Auth_Yadis_getNSMap
  • Auth_Yadis_getServiceEndpoints
  • Auth_Yadis_getSupportedExtensions
  • Auth_Yadis_getUCSChars
  • Auth_Yadis_getXMLParser
  • Auth_Yadis_getXRDExpiration
  • Auth_Yadis_getXrefRE
  • Auth_Yadis_getXRIAuthorities
  • Auth_Yadis_identifierScheme
  • Auth_Yadis_iriToURI
  • Auth_Yadis_pct_escape_unicode
  • Auth_Yadis_providerIsAuthoritative
  • Auth_Yadis_rootAuthority
  • Auth_Yadis_setDefaultParser
  • Auth_Yadis_startswith
  • Auth_Yadis_toIRINormal
  • Auth_Yadis_toURINormal
  • Auth_Yadis_XRI
  • Auth_Yadis_XRIAppendArgs
  • authorSelector
  • build_query
  • build_url
  • bulkActionRedirect
  • bulkTags
  • byteConvert
  • cacheImage
  • checkAccess
  • checkAlbumimagesort
  • checkAlbumParentid
  • checkAlbumPassword
  • checkChosenItemStatus
  • checkChosenMenuset
  • checked
  • checkFolder
  • checkForEmptyTitle
  • checkForGuest
  • checkForPage
  • checkForPassword
  • checkForUpdate
  • checkHitcounterDisplay
  • checkIfChecked
  • checkIfLockedNews
  • checkIfLockedPage
  • checkIfNew
  • checkInstall
  • checkLayoutUseForImages
  • checkNewsAccess
  • checkNewsCategoryPassword
  • checkObjectsThumb
  • checkPagePassword
  • checkPageValidity
  • checkParentLayouts
  • checkPublishDates
  • checkRequiredField
  • checkSelectedAlbum
  • checkSignature
  • cleanAlbum
  • cleanHTML
  • clearSitemapCache
  • clonedFrom
  • codeblocktabsJS
  • comment_form_addComment
  • comment_form_handle_comment
  • comment_form_PaginationJS
  • comment_form_postcomment
  • comment_form_print10Most
  • comment_form_visualEditor
  • commentFormUseCaptcha
  • commentReply
  • commentsAllowed
  • consolidatedEditMessages
  • copyLayoutSelection
  • copyThemeDirectory
  • countArticles
  • countCombiNews
  • createMenuIfNotExists
  • createRelatedItemsResultArray
  • cron_starter
  • currentRelativeURL
  • customOptions
  • dateDiff
  • datepickerJS
  • dateTimeConvert
  • db_affected_rows
  • db_close
  • db_collation
  • db_connect
  • db_count
  • db_create
  • db_create_table
  • db_error
  • db_fetch_assoc
  • db_fetch_row
  • db_free_result
  • db_getSQLmode
  • db_insert_id
  • db_LIKE_escape
  • db_list_fields
  • db_name
  • db_num_rows
  • db_permissions
  • db_quote
  • db_setSQLmode
  • db_show
  • db_software
  • db_table_update
  • db_truncate_table
  • debug404
  • debugLog
  • debugLogBacktrace
  • debugLogVar
  • defaultCodeblocks_codebox
  • deleteArticle
  • deleteCategory
  • deleteItem
  • deleteLayoutSelection
  • deletePage
  • deleteThemeDirectory
  • detect_fetcher
  • detect_math
  • detect_query_corruption
  • detect_random
  • detect_stores
  • detect_xml
  • dircopy
  • displayError
  • doIncludes
  • elFinder_admin_tabs
  • elFinder_tinymce
  • enableExtension
  • escape
  • executeRSS
  • exitZP
  • exposeZenPhotoInformations
  • extensionEnabled
  • fetchComments
  • filesystemToInternal
  • filter_extractReturnURL
  • filter_MatchesAnyOpenIDConsumerType
  • filter_MatchesAnyOpenIDType
  • filterImageQuery
  • fix_path_redirect
  • formatList
  • fullText
  • galleryAlbumsPerPage
  • genAlbumList
  • generateCaptcha
  • generateLanguageList
  • generateListFromArray
  • generateListFromFiles
  • generateRadiobuttonsFromArray
  • generateSitemapCacheFile
  • generateSitemapIndexCacheFile
  • generateUnorderedListFromArray
  • get_AnyFile_suffixes
  • get_context
  • get_filterScript
  • get_instance
  • get_language_string
  • getAdminThumb
  • getAlbumArray
  • getAlbumBreadcrumb
  • getAlbumBreadcrumbAdmin
  • getAlbumCustomData
  • getAlbumData
  • getAlbumDate
  • getAlbumDesc
  • getAlbumFolder
  • getAlbumGeodata
  • getAlbumId
  • getAlbumInherited
  • getAlbumLinkURL
  • getAlbumLocation
  • getAlbumPage
  • getAlbumPlace
  • getAlbumStatistic
  • getAlbumThumb
  • getAlbumTitle
  • getAlbumURL
  • getAllAccessibleAlbums
  • getAllAlbums
  • getAllArticleDates
  • getAllCategories
  • getAllDates
  • getAllowedTags
  • getAllSubAlbumIDs
  • getAllSubalbums
  • getAllTagsCount
  • getAllTagsFromAlbum
  • getAllTagsFromAlbum_multi_unique
  • getAllTagsFromZenpage
  • getAllTagsUnique
  • getAllTranslations
  • getAnnotatedAlbumTitle
  • getAnnotatedImageTitle
  • getArticles
  • getAuthor
  • getBare
  • getBareAlbumDesc
  • getBareAlbumTitle
  • getBareGalleryDesc
  • getBareGalleryTitle
  • getBareImageDesc
  • getBareImageTitle
  • getBareNewsAlbumTitle
  • getBareNewsTitle
  • getBarePageTitle
  • getCategory
  • getCategoryID
  • getCategoryLink
  • getCategoryParentID
  • getCategorySortOrder
  • getCategoryTitle
  • getCheckboxState
  • getCodeblock
  • getCombiNews
  • getCommentAddress
  • getCommentAuthorEmail
  • getCommentAuthorLink
  • getCommentAuthorName
  • getCommentAuthorSite
  • getCommentBody
  • getCommentCount
  • getCommentDate
  • getCommentDateTime
  • getCommentErrors
  • getCommentsAllowed
  • getCommentStored
  • getCommentTime
  • getConsumer
  • getContentShorten
  • getCurrentMenuItem
  • getCurrentNewsArchive
  • getCurrentNewsCategory
  • getCurrentNewsCategoryID
  • getCurrentNewsCategoryParentID
  • getCurrentNewsPage
  • getCurrentPage
  • getCurrentTheme
  • getCustomAlbumThumb
  • getCustomAlbumThumbMaxSpace
  • getCustomImageURL
  • getCustomPageURL
  • getCustomSizedImageMaxSpace
  • getCustomSizedImageThumbMaxSpace
  • getDefaultHeight
  • getDefaultSizedImage
  • getDefaultWidth
  • getDownloadLink
  • getdownloadList
  • getDownloadURL
  • getE
  • getEnabledPlugins
  • getExpiryDatePost
  • getFavoritesURL
  • getField
  • getFirstImageURL
  • getFullHeight
  • getFullImageURL
  • getFullNewsImage
  • getFullWidth
  • getGalleryDesc
  • getGalleryIndexURL
  • getGalleryTitle
  • getGeoCoord
  • getHeadTitle
  • getHitcounter
  • getImageArgs
  • getImageCacheFilename
  • getImageCachePostfix
  • getImageCity
  • getImageCountry
  • getImageCustomData
  • getImageData
  • getImageDate
  • getImageDesc
  • getImageEXIFData
  • getImageGeodata
  • getImageID
  • getImageLinkURL
  • getImageLocation
  • getImageMetaData
  • getImageParameters
  • getImageProcessorURI
  • getImageProcessorURIFromCacheName
  • getImageRotation
  • getImageSortOrder
  • getImageState
  • getImageStatistic
  • getImageThumb
  • getImageTitle
  • getImageURI
  • getImageURL
  • getItem
  • getItemByID
  • getItemTitleAndURL
  • getjPlayerSkinCSS
  • getjPlayerSkins
  • getLanguageArray
  • getLanguageFlag
  • getLastImageURL
  • getLatestComments
  • getLatestNews
  • getLatestZenpageComments
  • getLayout
  • getLayoutSelector
  • getLink
  • getLinkHTML
  • getLogTabs
  • getMacros
  • getMainSiteName
  • getMainSiteURL
  • getManagedAlbumList
  • getMaxSpaceContainer
  • getMenuFromLink
  • getMenuItemChilds
  • getMenuItems
  • getMenumanagerPredicessor
  • getMenumanagerSuccessor
  • getMenuSetSelector
  • getMenuVisibility
  • getMimeString
  • getNestedAlbumList
  • getNewsAdminOption
  • getNewsAdminOptionPath
  • getNewsAlbumName
  • getNewsAlbumTitle
  • getNewsAlbumURL
  • getNewsArchivePath
  • getNewsArchiveURL
  • getNewsAuthor
  • getNewsCategories
  • getNewsCategoryCustomData
  • getNewsCategoryDesc
  • getNewsCategoryPath
  • getNewsCategoryURL
  • getNewsContent
  • getNewsContentShorten
  • getNewsCustomData
  • getNewsDate
  • getNewsExtraContent
  • getNewsID
  • getNewsImageTags
  • getNewsIndexURL
  • getNewsLink
  • getNewsPagesStatistic
  • getNewsPathNav
  • getNewsReadMore
  • getNewsTitle
  • getNewsTitleLink
  • getNewsTitlePath
  • getNewsType
  • getNewsURL
  • getNewsVideoContent
  • getNextAlbum
  • getNextAlbumURL
  • getNextImageThumb
  • getNextImageURL
  • getNextNewsPageURL
  • getNextNewsURL
  • getNextPageURL
  • getNextPrevNews
  • getNotViewableAlbums
  • getNotViewableImages
  • getNumAlbums
  • getNumAllSubalbums
  • getNumImages
  • getNumNews
  • getNumPages
  • getNumSubalbums
  • getOpenIDURL
  • getOption
  • getOptionFromDB
  • getOptionList
  • getPageAuthor
  • getPageContent
  • getPageCustomData
  • getPageDate
  • getPageExtraContent
  • getPageID
  • getPageLastChangeDate
  • getPageLinkPath
  • getPageLinkURL
  • getPageNavList
  • getPageNumURL
  • getPageParentID
  • getPageRedirect
  • getPages
  • getPageSelector
  • getPageSortorder
  • getPageTitle
  • getPageTitleLink
  • getPageURL
  • getParentAlbums
  • getParentAlbumsAdmin
  • getParentBreadcrumb
  • getParentItems
  • getParentMenuItems
  • getParentNewsCategories
  • getParentPages
  • getPasswordProtectImage
  • getPHPFiles
  • getPlugin
  • getPluginFiles
  • getPluginTabs
  • getPrevAlbum
  • getPrevAlbumURL
  • getPrevImageThumb
  • getPrevImageURL
  • getPrevNewsPageURL
  • getPrevNewsURL
  • getPrevPageURL
  • getProtectedImageURL
  • getRandomImages
  • getRandomImagesAlbum
  • getRating
  • getRelatedItems
  • getRequestURI
  • getReturnTo
  • getRSSHeaderLink
  • getRSSLink
  • getScheme
  • getSearchDate
  • getSearchURL
  • getSearchWords
  • getSelectedLayout
  • getSerializedArray
  • getSetClause
  • getSiteHomeURL
  • getSitemapAlbumList
  • getSitemapAlbums
  • getSitemapGoogleImageVideoExtras
  • getSitemapGoogleLoopIndex
  • getSitemapImages
  • getSitemapIndexLinks
  • getSitemapZenpageNewsArticles
  • getSitemapZenpageNewsCategories
  • getSitemapZenpageNewsIndex
  • getSitemapZenpagePages
  • getSizeCustomImage
  • getSizeDefaultImage
  • getSizeDefaultThumb
  • getSizedImageURL
  • getSizeFullImage
  • getStore
  • getSubCategories
  • getSubtabs
  • getSuffix
  • getTagCountByAccess
  • getTagOrder
  • getTags
  • gettext_pl
  • gettext_th
  • getTheme
  • getThemeFiles
  • getThemeOption
  • getTimezones
  • getTinyMCE4ConfigFiles
  • getTitle
  • getTotalArticles
  • getTotalImagesIn
  • getTotalNewsPages
  • getTotalPages
  • getTrustRoot
  • getUnprotectedImageURL
  • getUrAlbum
  • getURL
  • getUserIP
  • getUserLocale
  • getVersion
  • getViewerImageSize
  • getWatermarkParam
  • getWatermarkPath
  • getWatermarks
  • getWhereClause
  • getXSRFToken
  • getZenpageHitcounter
  • getZenpageRSSHeaderLink
  • getZenpageRSSLink
  • getZenpageStatistic
  • googleVerifyHead
  • handleSearchParms
  • hasDynamicAlbumSuffix
  • hasNextImage
  • hasNextPage
  • hasPrevImage
  • hasPrevPage
  • hitcounter
  • html_decode
  • html_encode
  • html_encodeTagged
  • httpsRedirect
  • httpUploadHandler
  • httpUploadHandler_admin_tabs
  • i18nSetLocale
  • imageBlurGD
  • imageDebug
  • imageError
  • imageNumber
  • imgSrcURI
  • in_context
  • inNewsCategory
  • inProtectedNewsCategory
  • installSignature
  • instrument
  • inSubNewsCategoryOf
  • internalToFilesystem
  • inventMenuItem
  • iptc_make_tag
  • is_AdminEditPage
  • is_connected
  • is_GalleryNewsType
  • is_News
  • is_NewsArchive
  • is_NewsArticle
  • is_NewsCategory
  • is_NewsPage
  • is_NewsType
  • is_Pages
  • is_valid_email_zp
  • is_valid_image
  • is_valid_other_type
  • is_zip
  • isAlbumClass
  • isAlbumPage
  • isArchive
  • isHandledAlbum
  • isImageClass
  • isImagePage
  • isImagePhoto
  • isImageVideo
  • isLandscape
  • isMyAlbum
  • isMyNews
  • isMyPage
  • isolate
  • isProtectedAlbum
  • isProtectedNewsCategory
  • isProtectedPage
  • isSubNewsCategoryOf
  • isValidURL
  • jQueryUpload_head
  • jQueryUpload_headers
  • jQueryUploadHandler
  • jQueryUploadHandler_admin_tabs
  • js_encode
  • json_decode
  • json_encode
  • kses
  • kses_array_lc
  • kses_attr
  • kses_bad_protocol
  • kses_bad_protocol_once
  • kses_bad_protocol_once2
  • kses_check_attr_val
  • kses_decode_entities
  • kses_hair
  • kses_hook
  • kses_html_error
  • kses_js_entities
  • kses_no_null
  • kses_normalize_entities
  • kses_normalize_entities2
  • kses_split
  • kses_split2
  • kses_stripslashes
  • kses_version
  • ksesProcess
  • layoutSelector
  • layoutSelector_album
  • listDBUses
  • listDirectoryFiles
  • listUses
  • load_zenpage_news
  • load_zenpage_pages
  • loadLocalOptions
  • log_message
  • lookupSortKey
  • macro_admin_tabs
  • macroList_show
  • makeAlbumCurrent
  • makeImageCurrent
  • makeSpecialImageName
  • markRelease_button
  • mb_strlen
  • mb_strpos
  • mb_strrpos
  • mb_strtolower
  • mb_strtoupper
  • mb_substr
  • mb_substr_count
  • menu_admin_toolbox_global
  • menu_tabs
  • minDiff
  • mkdir_recursive
  • my_truncate_string
  • myts_date
  • newAlbum
  • newImage
  • next_album
  • next_comment
  • next_image
  • next_news
  • next_page
  • ngettext_pl
  • ngettext_th
  • normalizeColumns
  • omsAdditions
  • openedForComments
  • parse_query
  • parse_size
  • parseAllowedTags
  • parseHttpAcceptLanguage
  • passAlbums
  • passImages
  • pathurlencode
  • PclZipUtilCopyBlock
  • PclZipUtilOptionText
  • PclZipUtilPathInclusion
  • PclZipUtilPathReduction
  • PclZipUtilRename
  • PclZipUtilTranslateWinPath
  • PHPMailerAutoload
  • populateManagedObjectsList
  • postAlbumSort
  • postIndexDecode
  • postIndexEncode
  • prefix
  • prepareAlbumPage
  • prepareCustomPage
  • prepareImagePage
  • prepareIndexPage
  • print404status
  • print_language_string_list
  • printAddToFavorites
  • printAdminFooter
  • printAdminHeader
  • printAdminRightsTable
  • printAdminToolbox
  • printAlbumBreadcrumb
  • printAlbumButtons
  • printAlbumCustomData
  • printAlbumData
  • printAlbumDate
  • printAlbumDesc
  • printAlbumEditForm
  • printAlbumEditRow
  • printAlbumLegend
  • printAlbumLink
  • printAlbumLocation
  • printAlbumMap
  • printAlbumMenu
  • printAlbumMenuJump
  • printAlbumMenuList
  • printAlbumMenuListAlbum
  • printAlbumPlace
  • printAlbumRating
  • printAlbumsSelector
  • printAlbumStatistic
  • printAlbumStatisticItem
  • printAlbumThumbImage
  • printAlbumTitle
  • printAlbumURL
  • printAlbumZip
  • printAllDates
  • printAllNewsCategories
  • printAllTags
  • printAllTagsAs
  • printAllTagsFromAlbum
  • printAllTagsFromZenpage
  • printAnnotatedAlbumTitle
  • printAnnotatedImageTitle
  • printArticleCategories
  • printArticleDatesDropdown
  • printArticlesPerPageDropdown
  • printBareAlbumDesc
  • printBareAlbumTitle
  • printBareGalleryDesc
  • printBareGalleryTitle
  • printBareImageDesc
  • printBareImageTitle
  • printBareNewsTitle
  • printBarePageTitle
  • printBulkActions
  • printCaptcha
  • printCategoriesStatistic
  • printCategoryCheckboxListEntry
  • printCategoryDropdown
  • printCategoryListSortableTable
  • printCategorySelection
  • printCodeblock
  • printCodeblockEdit
  • printCommentAuthorLink
  • printCommentErrors
  • printCommentForm
  • printContactForm
  • printCurrentNewsArchive
  • printCurrentNewsCategory
  • printCustomAlbumThumbImage
  • printCustomAlbumThumbMaxSpace
  • printCustomMenu
  • printCustomPageSelector
  • printCustomPageURL
  • printCustomSizedImage
  • printCustomSizedImageMaxHeight
  • printCustomSizedImageMaxSpace
  • printCustomSizedImageThumbMaxSpace
  • printDefaultSizedImage
  • printDownloadAlbumZipURL
  • printDownloadLink
  • printDownloadLinkAlbumZip
  • printdownloadList
  • printDownloadURL
  • printEditable
  • printEditCommentLink
  • printEditDropdown
  • printExpired
  • printFavoritesLink
  • printFavoritesURL
  • printField
  • printGalleryDesc
  • printGalleryIndexURL
  • printGalleryTitle
  • printGoogleMap
  • printHeadTitle
  • printHomeLink
  • printImageCustomData
  • printImageData
  • printImageDate
  • printImageDesc
  • printImageDiv
  • printImageEXIFData
  • printImageID
  • printImageLink
  • printImageMap
  • printImageMetadata
  • printImageRating
  • printImageSortOrder
  • printImageStatistic
  • printImageThumb
  • printImageTitle
  • printImageURL
  • printItemEditLink
  • printItemsList
  • printItemsListTable
  • printItemStatusDropdown
  • printjCarouselThumbNav
  • printjPlayerPlaylist
  • printLanguageSelector
  • printLatestAlbums
  • printLatestComments
  • printLatestImages
  • printLatestImagesByDate
  • printLatestImagesByMtime
  • printLatestNews
  • printLatestUpdatedAlbums
  • printLatestZenpageComments
  • printLink
  • printLinkHTML
  • printLogoAndLinks
  • printManagedObjects
  • printMenuemanagerPageList
  • printMenuemanagerPageListWithNav
  • printMenumanagerBreadcrumb
  • printMenumanagerNextLink
  • printMenumanagerPrevLink
  • printMostPopularItems
  • printMostRatedAlbums
  • printMostRatedImages
  • printMostRatedItems
  • printNestedAlbumsList
  • printNestedItemsList
  • printNestedMenu
  • printNews
  • printNewsArchive
  • printNewsAuthor
  • printNewsCategories
  • printNewsCategoryCustomData
  • printNewsCategoryDesc
  • printNewsCategoryURL
  • printNewsContent
  • printNewsCustomData
  • printNewsDate
  • printNewsExtraContent
  • printNewsImageTags
  • printNewsIndexURL
  • printNewsLink
  • printNewsPageList
  • printNewsPageListWithNav
  • printNewsReadMoreLink
  • printNewsStatistic
  • printNewsTitle
  • printNewsTitleLink
  • printNewsURL
  • printNextNewsLink
  • printNextNewsPageLink
  • printNextPageLink
  • printNextPageURL
  • printPageArticleTags
  • printPageAuthor
  • printPageContent
  • printPageCustomData
  • printPageDate
  • printPagedThumbsNav
  • printPageExtraContent
  • printPageID
  • printPageLastChangeDate
  • printPageLinkURL
  • printPageList
  • printPageListWithNav
  • printPageMenu
  • printPageNav
  • printPageSelector
  • printPagesListTable
  • printPagesStatistic
  • printPageTitle
  • printPageTitleLink
  • printPageURL
  • printParentBreadcrumb
  • printParentPagesBreadcrumb
  • printPasswordForm
  • printPopularAlbums
  • printPopularImages
  • printPreloadScript
  • printPrevNewsLink
  • printPrevNewsPageLink
  • printPrevPageLink
  • printPrevPageURL
  • printPublished
  • printPublishIconLink
  • printRandomImages
  • printRating
  • printRegisterURL
  • printRegistrationForm
  • printRelatedItems
  • printRSSHeaderLink
  • printRSSLink
  • printSearchBreadcrumb
  • printSearchForm
  • printSiteHomeURL
  • printSizedImageLink
  • printSizedImageURL
  • printSlideShow
  • printSlideShowJS
  • printSlideShowLink
  • printSortableHead
  • printSortOrderDropdown
  • printSubPagesExcerpts
  • printSubtabs
  • printTabs
  • printTags
  • printThumbNav
  • printTopRatedAlbums
  • printTopRatedImages
  • printTopRatedItems
  • printUnpublishedDropdown
  • printUserLogin_out
  • printUserSizeImage
  • printUserSizeSelector
  • printVersion
  • printZenJavascripts
  • printZenpageIconLegend
  • printZenpageItemsBreadcrumb
  • printZenpageNewsCategorySelector
  • printZenpagePagesSelector
  • printZenpageRSSHeaderLink
  • printZenpageRSSLink
  • printZenpageStatistic
  • printZenphotoLink
  • process_language_string_save
  • processAlbumBulkActions
  • processAlbumEdit
  • processCodeblockSave
  • processCommentBulkActions
  • processCredentials
  • processCustomOptionSave
  • processEditSelection
  • processExpired
  • processImageBulkActions
  • processImageEdit
  • processManagedObjects
  • processMenuBulkActions
  • processOrder
  • processRights
  • processTags
  • processZenpageBulkActions
  • propSizes
  • publishItem
  • purgeOption
  • query
  • query_full_array
  • query_single_row
  • rc4
  • read_exif_data_protected
  • readTags
  • recaptcha_check_answer
  • recaptcha_get_html
  • recaptcha_get_signup_url
  • recaptcha_mailhide_html
  • recaptcha_mailhide_url
  • reconfigureAction
  • reconfigureCS
  • reconfigurePage
  • recordMissing
  • rem_context
  • removeParentAlbumNames
  • resetCurrentAlbum
  • restore_context
  • reveal
  • rewrite_get_album_image
  • rewrite_path
  • rewrite_path_zenpage
  • RSS_Channel
  • RSS_Retrieve
  • RSS_Tags
  • rulesList
  • run
  • safe_fnmatch
  • safe_glob
  • sanitize
  • sanitize_numeric
  • sanitize_path
  • sanitize_script
  • sanitize_string
  • sanitizeRedirect
  • save_context
  • saveLayoutSelection
  • saveZenphotoLayoutSelection
  • search_quote
  • secureServer
  • seo_cleanup_button
  • seoFriendly
  • seoFriendlyJS
  • set_context
  • setAlbumCustomData
  • setAlbumSubtabs
  • setImageCustomData
  • setMainDomain
  • setOption
  • setOptionDefault
  • setPluginDomain
  • setThemeColumns
  • setThemeDomain
  • setThemeOption
  • setThemeOptionDefault
  • setupAllowedMaps
  • setupCurrentLocale
  • setupDomain
  • setupTheme
  • shortenContent
  • showOrNotShowField
  • shuffle_assoc
  • signatureChange
  • site_upgrade_button
  • site_upgrade_status
  • sitemap_echonl
  • sitemap_getChangefreq
  • sitemap_getDateformat
  • sitemap_getDBLimit
  • sitemap_getISO8601Date
  • skipScheduledPublishing
  • sortByKey
  • sortByMultilingual
  • sortMultiArray
  • standardScripts
  • standardThemeOptions
  • stickyNews
  • storeConfig
  • storeTags
  • stripSuffix
  • submenuOf
  • switchLog
  • tagSelector
  • tagSuggestJS
  • tagSuggestJS_admin
  • tagSuggestJS_frontend
  • themeIsEditable
  • themeSetup
  • timezoneDiff
  • tinymce4ConfigJS
  • truncate_string
  • unpublishedZenphotoItemCheck
  • unpublishSubalbums
  • unQuote
  • unzip
  • updateArticle
  • updateCacheName
  • updateCategory
  • updateConfigItem
  • updateItemSortorder
  • updateItemsSortorder
  • updateMenuItem
  • updatePage
  • upload_extra
  • upload_form
  • upload_head
  • user_mailing_list_button
  • validateLocale
  • wordpress_import_button
  • wp_prefix
  • wp_query_full_array
  • wpimport_TryAgainError
  • XSRFdefender
  • XSRFToken
  • zenJavascript
  • zenpageAlbumImage
  • zenpageBulkActionMessage
  • zenpageHitcounter
  • zenpageJSCSS
  • zenpageOpenedForComments
  • zenpagePublish
  • zenphoto_PHPMailer
  • zenphoto_sendmail
  • zenPhotoTheme
  • zp_apply_filter
  • zp_clearCookie
  • zp_colorAllocate
  • zp_cookieEncode
  • zp_copyCanvas
  • zp_createImage
  • zp_drawRectangle
  • zp_error
  • zp_filter_slot
  • zp_filter_unique_id
  • zp_getCookie
  • zp_getFonts
  • zp_graphicsLibInfo
  • zp_handle_password
  • zp_handle_password_single
  • zp_has_filter
  • zp_image_types
  • zp_imageCanRotate
  • zp_imageColorTransparent
  • zp_imageDims
  • zp_imageFill
  • zp_imageFontHeight
  • zp_imageFontWidth
  • zp_imageFromString
  • zp_imageGet
  • zp_imageGray
  • zp_imageHeight
  • zp_imageIPTC
  • zp_imageKill
  • zp_imageLoadFont
  • zp_imageMerge
  • zp_imageOutput
  • zp_imageResizeAlpha
  • zp_imageUnsharpMask
  • zp_imageWidth
  • zp_load_album
  • zp_load_gallery
  • zp_load_image
  • zp_load_page
  • zp_load_request
  • zp_load_search
  • zp_loggedin
  • zp_mail
  • zp_register_filter
  • zp_remove_filter
  • zp_resampleImage
  • zp_rotateImage
  • zp_session_start
  • zp_setCookie
  • zp_writeString
  • zpErrorHandler
  • zpFormattedDate
  • zpRewriteURL
  • Overview
  • Package
  • Class
  • Tree
  • Deprecated
   1: <?php
   2: /**
   3:  * Functions used to display content in themes.
   4:  * @package functions
   5:  */
   6: // force UTF-8 Ø
   7: 
   8: require_once(dirname(__FILE__) . '/functions.php');
   9: if (!defined('SEO_FULLWEBPATH')) {
  10:     define('SEO_FULLWEBPATH', FULLWEBPATH);
  11:     define('SEO_WEBPATH', WEBPATH);
  12: }
  13: 
  14: //******************************************************************************
  15: //*** Template Functions *******************************************************
  16: //******************************************************************************
  17: 
  18: /* * * Generic Helper Functions ************ */
  19: /* * *************************************** */
  20: 
  21: /**
  22:  * Returns the zenphoto version string
  23:  */
  24: function getVersion() {
  25:     return ZENPHOTO_VERSION . ' [' . ZENPHOTO_RELEASE . ']';
  26: }
  27: 
  28: /**
  29:  * Prints the zenphoto version string
  30:  */
  31: function printVersion() {
  32:     echo getVersion();
  33: }
  34: 
  35: /**
  36:  * Print any Javascript required by zenphoto.
  37:  */
  38: function printZenJavascripts() {
  39:     global $_zp_current_album;
  40:     ?>
  41:     <script type="text/javascript" src="<?php echo WEBPATH . "/" . ZENFOLDER; ?>/js/jquery.js"></script>
  42:     <script type="text/javascript" src="<?php echo WEBPATH . "/" . ZENFOLDER; ?>/js/zenphoto.js"></script>
  43:     <?php
  44:     if (zp_loggedin()) {
  45:         ?>
  46:         <script type="text/javascript">
  47:             // <!-- <![CDATA[
  48:             var deleteAlbum1 = "<?php echo gettext("Are you sure you want to delete this entire album?"); ?>";
  49:             var deleteAlbum2 = "<?php echo gettext("Are you Absolutely Positively sure you want to delete the album? THIS CANNOT BE UNDONE!"); ?>";
  50:             var deleteImage = "<?php echo gettext("Are you sure you want to delete the image? THIS CANNOT BE UNDONE!"); ?>";
  51:             var deleteArticle = "<?php echo gettext("Are you sure you want to delete this article? THIS CANNOT BE UNDONE!"); ?>";
  52:             var deletePage = "<?php echo gettext("Are you sure you want to delete this page? THIS CANNOT BE UNDONE!"); ?>";
  53:             // ]]> -->
  54:         </script>
  55:         <link rel="stylesheet" href="<?php echo WEBPATH . '/' . ZENFOLDER; ?>/admintoolbox.css" type="text/css" />
  56:         <?php
  57:     }
  58: }
  59: 
  60: /**
  61:  * Prints the clickable drop down toolbox on any theme page with generic admin helpers
  62:  *
  63:  */
  64: function adminToolbox() {
  65:     global $_zp_current_album, $_zp_current_image, $_zp_current_search, $_zp_gallery_page, $_zp_gallery, $_zp_current_admin_obj, $_zp_loggedin;
  66:     if (zp_loggedin()) {
  67:         $zf = FULLWEBPATH . "/" . ZENFOLDER;
  68:         $page = getCurrentPage();
  69:         ob_start();
  70:         ?>
  71:         <script type="text/javascript">
  72:             // <!-- <![CDATA[
  73:             function newAlbum(folder, albumtab) {
  74:                 var album = prompt('<?php echo gettext('New album name?'); ?>', '<?php echo gettext('new album'); ?>');
  75:                 if (album) {
  76:                     launchScript('<?php echo $zf; ?>/admin-edit.php', ['action=newalbum', 'album=' + encodeURIComponent(folder), 'name=' + encodeURIComponent(album), 'albumtab=' + albumtab, 'XSRFToken=<?php echo getXSRFToken('newalbum'); ?>']);
  77:                 }
  78:             }
  79:             // ]]> -->
  80:         </script>
  81:         <div id="zp__admin_module">
  82:             <div id="zp__admin_info">
  83:                 <span class="zp_logo">ZP</span>
  84:                 <span class="zp_user"> <?php echo $_zp_current_admin_obj->getUser(); ?></span>
  85:             </div>
  86:             <button type="button" id="zp__admin_link" onclick="javascript:toggle('zp__admin_data');">
  87:                 <?php echo gettext('Admin'); ?>
  88:             </button>
  89:             <div id="zp__admin_data" style="display: none;">
  90: 
  91:                 <ul>
  92:                 <?php
  93:                 $outputA = ob_get_contents();
  94:                 ob_end_clean();
  95:                 ob_start();
  96: 
  97:                 if (zp_loggedin(OVERVIEW_RIGHTS)) {
  98:                     ?>
  99:                     <li>
 100:                         <?php printLinkHTML($zf . '/admin.php', gettext("Overview"), NULL, NULL, NULL); ?>
 101:                     </li>
 102:                     <?php
 103:                 }
 104:                 if (zp_loggedin(UPLOAD_RIGHTS | FILES_RIGHTS | THEMES_RIGHTS)) {
 105:                     ?>
 106:                     <li>
 107:                         <?php printLinkHTML($zf . '/admin-upload.php', gettext("Upload"), NULL, NULL, NULL); ?>
 108:                     </li>
 109:                     <?php
 110:                 }
 111:                 if (zp_loggedin(ALBUM_RIGHTS)) {
 112:                     ?>
 113:                     <li>
 114:                         <?php printLinkHTML($zf . '/admin-edit.php', gettext("Albums"), NULL, NULL, NULL); ?>
 115:                     </li>
 116:                     <?php
 117:                 }
 118:                 zp_apply_filter('admin_toolbox_global', $zf);
 119: 
 120:                 if (zp_loggedin(TAGS_RIGHTS)) {
 121:                     ?>
 122:                     <li>
 123:                         <?php printLinkHTML($zf . '/admin-tags.php', gettext("Tags"), NULL, NULL, NULL); ?>
 124:                     </li>
 125:                     <?php
 126:                 }
 127:                 if (zp_loggedin(USER_RIGHTS)) {
 128:                     ?>
 129:                     <li>
 130:                         <?php printLinkHTML($zf . '/admin-users.php', gettext("Users"), NULL, NULL, NULL); ?>
 131:                     </li>
 132:                     <?php
 133:                 }
 134:                 if (zp_loggedin(OPTIONS_RIGHTS)) {
 135:                     ?>
 136:                     <li>
 137:                         <?php printLinkHTML($zf . '/admin-options.php?tab=general', gettext("Options"), NULL, NULL, NULL); ?>
 138:                     </li>
 139:                     <?php
 140:                 }
 141:                 if (zp_loggedin(THEMES_RIGHTS)) {
 142:                     ?>
 143:                     <li>
 144:                         <?php printLinkHTML($zf . '/admin-themes.php', gettext("Themes"), NULL, NULL, NULL); ?>
 145:                     </li>
 146:                     <?php
 147:                 }
 148:                 if (zp_loggedin(ADMIN_RIGHTS)) {
 149:                     ?>
 150:                     <li>
 151:                         <?php printLinkHTML($zf . '/admin-plugins.php', gettext("Plugins"), NULL, NULL, NULL); ?>
 152:                     </li>
 153:                     <li>
 154:                         <?php printLinkHTML($zf . '/admin-logs.php', gettext("Logs"), NULL, NULL, NULL); ?>
 155:                     </li>
 156:                     <?php
 157:                 }
 158: 
 159:                 $gal = getOption('custom_index_page');
 160:                 if (empty($gal) || !file_exists(SERVERPATH . '/' . THEMEFOLDER . '/' . $_zp_gallery->getCurrentTheme() . '/' . internalToFilesystem($gal) . '.php')) {
 161:                     $gal = 'index.php';
 162:                 } else {
 163:                     $gal .= '.php';
 164:                 }
 165:                 $inImage = false;
 166:                 switch ($_zp_gallery_page) {
 167:                     case 'index.php':
 168:                     case $gal:
 169:                         // script is either index.php or the gallery index page
 170:                         if (zp_loggedin(ADMIN_RIGHTS)) {
 171:                             ?>
 172:                             <li>
 173:                                 <?php printLinkHTML($zf . '/admin-edit.php?page=edit', gettext("Sort Gallery"), NULL, NULL, NULL); ?>
 174:                             </li>
 175:                             <?php
 176:                         }
 177:                         if (zp_loggedin(UPLOAD_RIGHTS)) {
 178:                             // admin has upload rights, provide an upload link for a new album
 179:                             if (GALLERY_SESSION) { // XSRF defense requires sessions
 180:                                 ?>
 181:                                 <li>
 182:                                     <a href="javascript:newAlbum('',true);"><?php echo gettext("New Album"); ?></a>
 183:                                 </li>
 184:                                 <?php
 185:                             }
 186:                         }
 187:                         if ($_zp_gallery_page == 'index.php') {
 188:                             $redirect = '';
 189:                         } else {
 190:                             $redirect = "&amp;p=" . urlencode(stripSuffix($_zp_gallery_page));
 191:                         }
 192:                         if ($page > 1) {
 193:                             $redirect .= "&amp;page=$page";
 194:                         }
 195:                         zp_apply_filter('admin_toolbox_gallery', $zf);
 196:                         break;
 197:                     case 'image.php':
 198:                         $inImage = true; // images are also in albums[sic]
 199:                     case 'album.php':
 200:                         // script is album.php
 201:                         $albumname = $_zp_current_album->name;
 202:                         if ($_zp_current_album->isMyItem(ALBUM_RIGHTS)) {
 203:                             // admin is empowered to edit this album--show an edit link
 204:                             ?>
 205:                             <li>
 206:                                 <?php printLinkHTML($zf . '/admin-edit.php?page=edit&album=' . pathurlencode($_zp_current_album->name), gettext('Edit album'), NULL, NULL, NULL); ?>
 207:                             </li>
 208:                             <?php
 209:                             if (!$_zp_current_album->isDynamic()) {
 210:                                 if ($_zp_current_album->getNumAlbums()) {
 211:                                     ?>
 212:                                     <li>
 213:                                         <?php printLinkHTML($zf . '/admin-edit.php?page=edit&album=' . pathurlencode($albumname) . '&tab=subalbuminfo', gettext("Sort subalbums"), NULL, NULL, NULL); ?>
 214:                                     </li>
 215:                                     <?php
 216:                                 }
 217:                                 if ($_zp_current_album->getNumImages() > 0) {
 218:                                     ?>
 219:                                     <li>
 220:                                         <?php printLinkHTML($zf . '/admin-albumsort.php?page=edit&album=' . pathurlencode($albumname) . '&tab=sort', gettext("Sort images"), NULL, NULL, NULL); ?>
 221:                                     </li>
 222:                                     <?php
 223:                                 }
 224:                             }
 225:                             // and a delete link
 226:                             if (GALLERY_SESSION) { // XSRF defense requires sessions
 227:                                 ?>
 228:                                 <li>
 229:                                     <a href="javascript:confirmDeleteAlbum('<?php echo $zf; ?>/admin-edit.php?page=edit&amp;action=deletealbum&amp;album=<?php echo urlencode(pathurlencode($albumname)) ?>&amp;XSRFToken=<?php echo getXSRFToken('delete'); ?>');"
 230:                                          title="<?php echo gettext('Delete the album'); ?>"><?php echo gettext('Delete album'); ?></a>
 231:                                 </li>
 232:                                 <?php
 233:                             }
 234:                         }
 235:                         if ($_zp_current_album->isMyItem(UPLOAD_RIGHTS) && !$_zp_current_album->isDynamic()) {
 236:                             // provide an album upload link if the admin has upload rights for this album and it is not a dynamic album
 237:                             ?>
 238:                             <li>
 239:                                 <?php printLinkHTML($zf . '/admin-upload.php?album=' . pathurlencode($albumname), gettext("Upload Here"), NULL, NULL, NULL); ?>
 240:                             </li>
 241:                             <?php
 242:                             if (GALLERY_SESSION) { // XSRF defense requires sessions
 243:                                 ?>
 244:                                 <li>
 245:                                     <a href="javascript:newAlbum('<?php echo pathurlencode($albumname); ?>',true);"><?php echo gettext("New Album Here"); ?></a>
 246:                                 </li>
 247:                                 <?php
 248:                             }
 249:                         }
 250:                         zp_apply_filter('admin_toolbox_album', $albumname, $zf);
 251:                         if ($inImage) {
 252:                             // script is image.php
 253:                             $imagename = $_zp_current_image->filename;
 254:                             if (!$_zp_current_album->isDynamic()) { // don't provide links when it is a dynamic album
 255:                                 if ($_zp_current_album->isMyItem(ALBUM_RIGHTS)) {
 256:                                     // if admin has edit rights on this album, provide a delete link for the image.
 257:                                     if (GALLERY_SESSION) { // XSRF defense requires sessions
 258:                                         ?>
 259:                                         <li>
 260:                                             <a href="javascript:confirmDelete('<?php echo $zf; ?>/admin-edit.php?page=edit&amp;action=deleteimage&amp;album=<?php echo urlencode(pathurlencode($albumname)); ?>&amp;image=<?php echo urlencode($imagename); ?>&amp;XSRFToken=<?php echo getXSRFToken('delete'); ?>',deleteImage);"
 261:                                                  title="<?php echo gettext("Delete the image"); ?>"><?php echo gettext("Delete image"); ?></a>
 262:                                         </li>
 263:                                         <?php
 264:                                     }
 265:                                     ?>
 266:                                     <li>
 267:                                         <a href="<?php echo $zf; ?>/admin-edit.php?page=edit&amp;album=<?php echo pathurlencode($albumname); ?>&amp;singleimage=<?php echo urlencode($imagename); ?>&amp;tab=imageinfo&amp;nopagination"
 268:                                              title="<?php echo gettext('Edit image'); ?>"><?php echo gettext('Edit image'); ?></a>
 269:                                     </li>
 270:                                     <?php
 271:                                 }
 272:                                 // set return to this image page
 273:                                 zp_apply_filter('admin_toolbox_image', $albumname, $imagename, $zf);
 274:                             }
 275:                             $redirect = "&amp;album=" . html_encode(pathurlencode($albumname)) . "&amp;image=" . urlencode($imagename);
 276:                         } else {
 277:                             // set the return to this album/page
 278:                             $redirect = "&amp;album=" . html_encode(pathurlencode($albumname));
 279:                             if ($page > 1) {
 280:                                 $redirect .= "&amp;page=$page";
 281:                             }
 282:                         }
 283:                         break;
 284:                     case 'search.php':
 285:                         $words = $_zp_current_search->getSearchWords();
 286:                         if (!empty($words)) {
 287:                             // script is search.php with a search string
 288:                             if (zp_loggedin(UPLOAD_RIGHTS)) {
 289:                                 $link = $zf . '/admin-dynamic-album.php?' . substr($_zp_current_search->getSearchParams(), 1);
 290:                                 // if admin has edit rights allow him to create a dynamic album from the search
 291:                                 ?>
 292:                                 <li>
 293:                                     <a href="<?php echo $link; ?>" title="<?php echo gettext('Create an album from the search'); ?>" ><?php echo gettext('Create Album'); ?></a>
 294:                                 </li>
 295:                                 <?php
 296:                             }
 297:                             zp_apply_filter('admin_toolbox_search', $zf);
 298:                         }
 299:                         $redirect = "&amp;p=search" . $_zp_current_search->getSearchParams() . "&amp;page=$page";
 300:                         break;
 301:                     default:
 302:                         // arbitrary custom page
 303:                         $gal = stripSuffix($_zp_gallery_page);
 304:                         $redirect = "&amp;p=" . urlencode($gal);
 305:                         if ($page > 1) {
 306:                             $redirect .= "&amp;page=$page";
 307:                         }
 308:                         $redirect = zp_apply_filter('admin_toolbox_' . $gal, $redirect, $zf);
 309:                         break;
 310:                 }
 311:                 $redirect = zp_apply_filter('admin_toolbox_close', $redirect, $zf);
 312:                 if ($_zp_current_admin_obj->logout_link) {
 313:                     // logout link
 314:                     $sec = (int) ((SERVER_PROTOCOL == 'https') & true);
 315:                     $link = SEO_FULLWEBPATH . '/index.php?logout=' . $sec . $redirect;
 316:                     ?>
 317:                     <li>
 318:                         <a href="<?php echo $link; ?>"><?php echo gettext("Logout"); ?> </a>
 319:                     </li>
 320:                     <?php
 321:                 }
 322:                 $outputB = ob_get_contents();
 323:                 ob_end_clean();
 324:                 if ($outputB) {
 325:                     echo $outputA . $outputB;
 326:                     ?>
 327:                 </ul>
 328:             </div>
 329:         </div>
 330:         <?php
 331:         }
 332:     }
 333: }
 334: 
 335: //*** Gallery Index (album list) Context ***
 336: //******************************************
 337: 
 338: /**
 339:  * Returns the raw title of the gallery.
 340:  *
 341:  * @return string
 342:  */
 343: function getGalleryTitle() {
 344:     global $_zp_gallery;
 345:     return $_zp_gallery->getTitle();
 346: }
 347: 
 348: /**
 349:  * Returns a text-only title of the gallery.
 350:  *
 351:  * @return string
 352:  */
 353: function getBareGalleryTitle() {
 354:     return getBare(getGalleryTitle());
 355: }
 356: 
 357: /**
 358:  * Prints the title of the gallery.
 359:  */
 360: function printGalleryTitle() {
 361:     echo html_encodeTagged(getGalleryTitle());
 362: }
 363: 
 364: function printBareGalleryTitle() {
 365:     echo html_encode(getBareGalleryTitle());
 366: }
 367: 
 368: /**
 369:  * Function to create the page title to be used within the html <head> <title></title> element.
 370:  * Usefull if you use one header.php for the header of all theme pages instead of individual ones on the theme pages
 371:  * It returns the title and site name in reversed breadcrumb order:
 372:  * <title of current page> | <parent item if present> | <gallery title>
 373:  * It supports standard gallery pages as well a custom and Zenpage news articles, categories and pages.
 374:  *
 375:  * @param string $separator How you wish the parts to be separated
 376:  * @param bool $listparentalbums If the parent albums should be printed in reversed order before the current
 377:  * @param bool $listparentpage If the parent Zenpage pages should be printed in reversed order before the current page
 378:  */
 379: function getHeadTitle($separator = ' | ', $listparentalbums = true, $listparentpages = true) {
 380:     global $_zp_gallery, $_zp_current_album, $_zp_current_image, $_zp_current_zenpage_news, $_zp_current_zenpage_page, $_zp_gallery_page, $_zp_current_category, $_zp_page, $_myFavorites;
 381:     $mainsitetitle = html_encode(getBare(getMainSiteName()));
 382:     $separator = html_encode($separator);
 383:     if ($mainsitetitle) {
 384:         $mainsitetitle = $separator . $mainsitetitle;
 385:     }
 386:     $gallerytitle = html_encode(getBareGalleryTitle());
 387:     if ($_zp_page > 1) {
 388:         $pagenumber = ' (' . $_zp_page . ')';
 389:     } else {
 390:         $pagenumber = '';
 391:     }
 392:     switch ($_zp_gallery_page) {
 393:         case 'index.php':
 394:             return $gallerytitle . $mainsitetitle . $pagenumber;
 395:             break;
 396:         case 'album.php':
 397:         case 'image.php':
 398:             if ($listparentalbums) {
 399:                 $parents = getParentAlbums();
 400:                 $parentalbums = '';
 401:                 if (count($parents) != 0) {
 402:                     $parents = array_reverse($parents);
 403:                     foreach ($parents as $parent) {
 404:                         $parentalbums .= html_encode(getBare($parent->getTitle())) . $separator;
 405:                     }
 406:                 }
 407:             } else {
 408:                 $parentalbums = '';
 409:             }
 410:             $albumtitle = html_encode(getBareAlbumTitle()) . $pagenumber . $separator . $parentalbums . $gallerytitle . $mainsitetitle;
 411:             switch ($_zp_gallery_page) {
 412:                 case 'album.php':
 413:                     return $albumtitle;
 414:                     break;
 415:                 case 'image.php':
 416:                     return html_encode(getBareImageTitle()) . $separator . $albumtitle;
 417:                     break;
 418:             }
 419:             break;
 420:         case 'news.php':
 421:             if (function_exists("is_NewsArticle")) {
 422:                 if (is_NewsArticle()) {
 423:                     return html_encode(getBareNewsTitle()) . $pagenumber . $separator . gettext('News') . $separator . $gallerytitle . $mainsitetitle;
 424:                 } else if (is_NewsCategory()) {
 425:                     return html_encode(getBare($_zp_current_category->getTitle())) . $pagenumber . $separator . gettext('News') . $separator . $gallerytitle . $mainsitetitle;
 426:                 } else {
 427:                     return gettext('News') . $pagenumber . $separator . $gallerytitle . $mainsitetitle;
 428:                 }
 429:             }
 430:             break;
 431:         case 'pages.php':
 432:             if ($listparentpages) {
 433:                 $parents = $_zp_current_zenpage_page->getParents();
 434:                 $parentpages = '';
 435:                 if (count($parents) != 0) {
 436:                     $parents = array_reverse($parents);
 437:                     foreach ($parents as $parent) {
 438:                         $obj = new ZenpagePage($parent);
 439:                         $parentpages .= html_encode(getBare($obj->getTitle())) . $separator;
 440:                     }
 441:                 }
 442:             } else {
 443:                 $parentpages = '';
 444:             }
 445:             return html_encode(getBarePageTitle()) . $pagenumber . $separator . $parentpages . $gallerytitle . $mainsitetitle;
 446:             break;
 447:         case '404.php':
 448:             return gettext('Object not found') . $separator . $gallerytitle . $mainsitetitle;
 449:             break;
 450:         default: // for all other possible static custom pages
 451:             $custompage = stripSuffix($_zp_gallery_page);
 452:             $standard = array('contact' => gettext('Contact'), 'register' => gettext('Register'), 'search' => gettext('Search'), 'archive' => gettext('Archive view'), 'password' => gettext('Password required'));
 453:             if (is_object($_myFavorites)) {
 454:                 $standard['favorites'] = gettext('My favorites');
 455:             }
 456:             if (array_key_exists($custompage, $standard)) {
 457:                 return $standard[$custompage] . $pagenumber . $separator . $gallerytitle . $mainsitetitle;
 458:             } else {
 459:                 return $custompage . $pagenumber . $separator . $gallerytitle . $mainsitetitle;
 460:             }
 461:             break;
 462:     }
 463: }
 464: 
 465: /**
 466:  * Function to print the html <title>title</title> within the <head> of a html page based on the current theme page
 467:  * Usefull if you use one header.php for the header of all theme pages instead of individual ones on the theme pages
 468:  * It prints the title and site name including the <title> tag in reversed breadcrumb order:
 469:  * <title><title of current page> | <parent item if present> | <gallery title></title>
 470:  * It supports standard gallery pages as well a custom and Zenpage news articles, categories and pages.
 471:  *
 472:  * @param string $separator How you wish the parts to be separated
 473:  * @param bool $listparentalbums If the parent albums should be printed in reversed order before the current
 474:  * @param bool $listparentpage If the parent Zenpage pages should be printed in reversed order before the current page
 475:  */
 476: function printHeadTitle($separator = ' | ', $listparentalbums = true, $listparentpages = true) {
 477:     echo '<title>' . getHeadTitle($separator, $listparentalbums, $listparentpages) . '</title>';
 478: }
 479: 
 480: /**
 481:  * Returns the raw description of the gallery.
 482:  *
 483:  * @return string
 484:  */
 485: function getGalleryDesc() {
 486:     global $_zp_gallery;
 487:     return $_zp_gallery->getDesc();
 488: }
 489: 
 490: /**
 491:  * Returns a text-only description of the gallery.
 492:  *
 493:  * @return string
 494:  */
 495: function getBareGalleryDesc() {
 496:     return getBare(getGalleryDesc());
 497: }
 498: 
 499: /**
 500:  * Prints the description of the gallery.
 501:  */
 502: function printGalleryDesc() {
 503:     echo html_encodeTagged(getGalleryDesc());
 504: }
 505: 
 506: function printBareGalleryDesc() {
 507:     echo html_encode(getBareGalleryDesc());
 508: }
 509: 
 510: /**
 511:  * Returns the name of the main website as set by the "Website Title" option
 512:  * on the gallery options tab. Use this if Zenphoto is only a part of your website.
 513:  *
 514:  * @return string
 515:  */
 516: function getMainSiteName() {
 517:     global $_zp_gallery;
 518:     return $_zp_gallery->getWebsiteTitle();
 519: }
 520: 
 521: /**
 522:  * Returns the URL of the main website as set by the "Website URL" option
 523:  * on the gallery options tab. Use this if Zenphoto is only a part of your website.
 524:  *
 525:  * @return string
 526:  */
 527: function getMainSiteURL() {
 528:     global $_zp_gallery;
 529:     return $_zp_gallery->getWebsiteURL();
 530: }
 531: 
 532: /**
 533:  * Returns the URL of the main gallery index page. If a custom index page is set this returns that page.
 534:  * So this is not necessarily the home page of the site!
 535:  * @return string
 536:  */
 537: function getGalleryIndexURL() {
 538:   global $_zp_current_album, $_zp_gallery_page;
 539:   if (func_num_args() !== 0) {
 540:     internal_deprecations::getGalleryIndexURL();
 541:   }
 542:     $custom_index = getOption('custom_index_page');
 543:     if ($custom_index) {
 544:         $link = rewrite_path('/' . _PAGE_ . '/' . $custom_index . '/', "/index.php?p=" . $custom_index);
 545:     } else {
 546:         $link = WEBPATH . "/";
 547:     }
 548:     if (in_context(ZP_ALBUM) && $_zp_gallery_page != 'index.php') {
 549:         $album = getUrAlbum($_zp_current_album);
 550:         if (($page = $album->getGalleryPage()) > 1) {
 551:             if ($custom_index) {
 552:                 $link = rewrite_path('/' . _PAGE_ . '/' . $custom_index . '/' . $page . '/', "/index.php?p=" . $custom_index . "&amp;page=" . $page);
 553:             } else {
 554:                 $link = rewrite_path('/' . _PAGE_ . '/' . $page . '/', "/index.php?" . "page=" . $page);
 555:             }
 556:         }
 557:     }
 558:     return zp_apply_filter('getLink', $link, 'index.php', NULL);
 559: }
 560: 
 561: /**
 562:  * If a custom gallery index page is set this first prints a link to the actual site index (home page = index.php)
 563:  * followed by the gallery index page link. Otherwise just the gallery index link
 564:  *
 565:  * @since 1.4.9
 566:  * @param string $after Text to append after and outside the link for breadcrumbs
 567:  * @param string $text Name of the link, if NULL "Gallery" is used
 568:  * @param bool $printHomeURL In case of a custom gallery index, display breadcrumb with home link (default is true)
 569:  */
 570: function printGalleryIndexURL($after = NULL, $text = NULL, $printHomeURL = true) {
 571:     global $_zp_gallery_page;
 572:     if(is_null($text)) {
 573:         $text = gettext('Gallery');
 574:     }
 575:     $customgalleryindex = getOption('custom_index_page');
 576:     if($customgalleryindex && $printHomeURL) {
 577:         printSiteHomeURL($after);
 578:     }
 579:     if ($_zp_gallery_page == getOption('custom_index_page').'.php') {
 580:         $after = NULL;
 581:     }
 582:     if(!$customgalleryindex || ($customgalleryindex && in_array($_zp_gallery_page, array('image.php', 'album.php', 'gallery.php')))) {
 583:         printLinkHTML(getGalleryIndexURL(), $text, $text, 'galleryindexurl'); echo $after;
 584:     }
 585: }
 586: 
 587: 
 588: /**
 589:      * Returns the home page link (WEBPATH) to the Zenphoto theme index.php page
 590:      * Use in breadcrumbs if the theme uses a custom gallery index page so the gallery is not the site's home page
 591:      *
 592:      * @since 1.4.9
 593:      * @global string $_zp_gallery_page
 594:      * @return string
 595:      */
 596:     function getSiteHomeURL() {
 597:         return WEBPATH . '/';
 598:     }
 599: 
 600:     /**
 601:      * Prints the home page link (WEBPATH with trailing slash) to a Zenphoto theme index.php page
 602:      * Use in breadcrumbs if the theme uses a custom gallery index page so the gallery is not the site's home page
 603:      *
 604:      * @param string $after Text after and outside the link for breadcrumbs
 605:          * @param string $text Text of the link, if NULL "Home"
 606:      */
 607:     function printSiteHomeURL($after = NULL, $text = NULL) {
 608:         global $_zp_gallery_page;
 609:         if ($_zp_gallery_page == 'index.php') {
 610:             $after = '';
 611:         }
 612:         if (is_null($text)) {
 613:             $text= gettext('Home');
 614:         }
 615:         printLinkHTML(getSiteHomeURL(), $text, $text, 'homeurl'); echo $after;
 616:     }
 617: 
 618: /**
 619:  * Returns the number of albums.
 620:  *
 621:  * @return int
 622:  */
 623: function getNumAlbums() {
 624:     global $_zp_gallery, $_zp_current_album, $_zp_current_search;
 625:     if (in_context(ZP_SEARCH) && is_null($_zp_current_album)) {
 626:         return $_zp_current_search->getNumAlbums();
 627:     } else if (in_context(ZP_ALBUM)) {
 628:         return $_zp_current_album->getNumAlbums();
 629:     } else {
 630:         return $_zp_gallery->getNumAlbums();
 631:     }
 632: }
 633: 
 634: /**
 635:  * Returns the name of the currently active theme
 636:  *
 637:  * @return string
 638:  */
 639: function getCurrentTheme() {
 640:     global $_zp_gallery;
 641:     return $_zp_gallery->getCurrentTheme();
 642: }
 643: 
 644: /* * * Album AND Gallery Context *********** */
 645: /* * *************************************** */
 646: 
 647: /**
 648:  * WHILE next_album(): context switches to Album.
 649:  * If we're already in the album context, this is a sub-albums loop, which,
 650:  * quite simply, changes the source of the album list.
 651:  * Switch back to the previous context when there are no more albums.
 652: 
 653:  * Returns true if there are albums, false if none
 654:  *
 655:  * @param bool $all true to go through all the albums
 656:  * @param bool $mine override the password checks
 657:  * @return bool
 658:  * @since 0.6
 659:  */
 660: function next_album($all = false, $mine = NULL) {
 661:     global $_zp_albums, $_zp_gallery, $_zp_current_album, $_zp_page, $_zp_current_album_restore, $_zp_current_search;
 662:     if (($mine != NULL && gettype($mine) != 'boolean') || func_num_args() > 2) {
 663:         internal_deprecations::next_album();
 664:     }
 665: 
 666:     if (is_null($_zp_albums)) {
 667:         if (in_context(ZP_SEARCH)) {
 668:             $_zp_albums = $_zp_current_search->getAlbums($all ? 0 : $_zp_page, NULL, NULL, true, $mine);
 669:         } else if (in_context(ZP_ALBUM)) {
 670:             $_zp_albums = $_zp_current_album->getAlbums($all ? 0 : $_zp_page, NULL, NULL, true, $mine);
 671:         } else {
 672:             $_zp_albums = $_zp_gallery->getAlbums($all ? 0 : $_zp_page, NULL, NULL, true, $mine);
 673:         }
 674:         if (empty($_zp_albums)) {
 675:             return NULL;
 676:         }
 677:         $_zp_current_album_restore = $_zp_current_album;
 678:         $_zp_current_album = newAlbum(array_shift($_zp_albums), true, true);
 679:         save_context();
 680:         add_context(ZP_ALBUM);
 681:         return true;
 682:     } else if (empty($_zp_albums)) {
 683:         $_zp_albums = NULL;
 684:         $_zp_current_album = $_zp_current_album_restore;
 685:         restore_context();
 686:         return false;
 687:     } else {
 688:         $_zp_current_album = newAlbum(array_shift($_zp_albums), true, true);
 689:         return true;
 690:     }
 691: }
 692: 
 693: /**
 694:  * Returns the number of the current page without printing it.
 695:  *
 696:  * @return int
 697:  */
 698: function getCurrentPage() {
 699:     global $_zp_page;
 700:     return $_zp_page;
 701: }
 702: 
 703: /**
 704:  * Returns a list of all albums decendent from an album
 705:  *
 706:  * @param object $album optional album. If absent the current album is used
 707:  * @return array
 708:  */
 709: function getAllAlbums($album = NULL) {
 710:     global $_zp_current_album, $_zp_gallery;
 711:     if (is_null($album))
 712:         $album = $_zp_current_album;
 713:     if (!is_object($album))
 714:         return;
 715:     $list = array();
 716:     $subalbums = $album->getAlbums(0);
 717:     if (is_array($subalbums)) {
 718:         foreach ($subalbums as $subalbum) {
 719:             $list[] = $subalbum;
 720:             $sub = newAlbum($subalbum);
 721:             $list = array_merge($list, getAllAlbums($sub));
 722:         }
 723:     }
 724:     return $list;
 725: }
 726: 
 727: /**
 728:  * Gets an array of the album ids of all accessible albums (publich or user dependend)
 729:  *
 730:  * @param object $obj from whence to get the albums
 731:  * @param array $albumlist collects the list
 732:  * @param bool $scan force scan for new images in the album folder
 733:  */
 734: function getAllAccessibleAlbums($obj, &$albumlist, $scan) {
 735:     global $_zp_gallery;
 736:     $locallist = $obj->getAlbums();
 737:  foreach ($locallist as $folder) {
 738:         $album = newAlbum($folder);
 739:         If (!$album->isDynamic() && $album->checkAccess()) {
 740:             if ($scan)
 741:                 $album->getImages();
 742:             $albumlist[] = $album->getID();
 743:             getAllAccessibleAlbums($album, $albumlist, $scan);
 744:         }
 745:     }
 746: }
 747: 
 748: /**
 749:  * Returns the number of pages for the current object
 750:  *
 751:  * @param bool $_oneImagePage set to true if your theme collapses all image thumbs
 752:  * or their equivalent to one page. This is typical with flash viewer themes
 753:  *
 754:  * @return int
 755:  */
 756: function getTotalPages($_oneImagePage = false) {
 757:     global $_zp_gallery, $_zp_current_album, $_firstPageImages, $_zp_zenpage, $_zp_current_category;
 758:     if (in_context(ZP_ALBUM | ZP_SEARCH)) {
 759:         $albums_per_page = max(1, getOption('albums_per_page'));
 760:         $pageCount = (int) ceil(getNumAlbums() / $albums_per_page);
 761:         $imageCount = getNumImages();
 762:         if ($_oneImagePage) {
 763:             if ($_oneImagePage === true) {
 764:                 $imageCount = min(1, $imageCount);
 765:             } else {
 766:                 $imageCount = 0;
 767:             }
 768:         }
 769:         $images_per_page = max(1, getOption('images_per_page'));
 770:         $pageCount = ($pageCount + ceil(($imageCount - $_firstPageImages) / $images_per_page));
 771:         return $pageCount;
 772:     } else if (get_context() == ZP_INDEX) {
 773:         if (galleryAlbumsPerPage() != 0) {
 774:             return (int) ceil($_zp_gallery->getNumAlbums() / galleryAlbumsPerPage());
 775:         } else {
 776:             return NULL;
 777:         }
 778:         return NULL;
 779:     } else if (isset($_zp_zenpage)) {
 780:         if (in_context(ZP_ZENPAGE_NEWS_CATEGORY)) {
 781:             $cat = $_zp_current_category;
 782:         } else {
 783:             $cat = NULL;
 784:         }
 785:         return (int) ceil(count($_zp_zenpage->getArticles(0, NULL, true, NULL, NULL, NULL, $cat)) / ZP_ARTICLES_PER_PAGE);
 786:     }
 787: }
 788: 
 789: /**
 790:  * Returns the URL of the page number passed as a parameter
 791:  *
 792:  * @param int $page Which page is desired
 793:  * @param int $total How many pages there are.
 794:  * @return int
 795:  */
 796: function getPageNumURL($page, $total = null) {
 797:     global $_zp_current_album, $_zp_gallery, $_zp_current_search, $_zp_gallery_page;
 798:     if (is_null($total)) {
 799:         $total = getTotalPages();
 800:     }
 801:     if ($page <= 0 || $page > $total) {
 802:         return NULL;
 803:     }
 804:     if (in_context(ZP_SEARCH)) {
 805:         $searchwords = $_zp_current_search->codifySearchString();
 806:         $searchdate = $_zp_current_search->getSearchDate();
 807:         $searchfields = $_zp_current_search->getSearchFields(true);
 808:         $searchpagepath = getSearchURL($searchwords, $searchdate, $searchfields, $page, array('albums' => $_zp_current_search->getAlbumList()));
 809:         return $searchpagepath;
 810:     } else if (in_context(ZP_ALBUM)) {
 811:         return $_zp_current_album->getLink($page);
 812:     } else if (in_array($_zp_gallery_page, array('index.php', 'album.php', 'image.php'))) {
 813:         if (in_context(ZP_INDEX)) {
 814:             $pagination1 = '/';
 815:             $pagination2 = 'index.php';
 816:             if ($page > 1) {
 817:                 $pagination1 .= _PAGE_ . '/' . $page . '/';
 818:                 $pagination2 .= '?page=' . $page;
 819:             }
 820:         } else {
 821:             return NULL;
 822:         }
 823:     } else {
 824: // handle custom page
 825:         $pg = stripSuffix($_zp_gallery_page);
 826:         $pagination1 = '/' . _PAGE_ . '/' . $pg . '/';
 827:         $pagination2 = 'index.php?p=' . $pg;
 828:         if ($page > 1) {
 829:             $pagination1 .= $page . '/';
 830:             $pagination2 .= '&page=' . $page;
 831:         }
 832:     }
 833:     return zp_apply_filter('getLink', rewrite_path($pagination1, $pagination2), $_zp_gallery_page, $page);
 834: }
 835: 
 836: /**
 837:  * Returns true if there is a next page
 838:  *
 839:  * @return bool
 840:  */
 841: function hasNextPage() {
 842:     return (getCurrentPage() < getTotalPages());
 843: }
 844: 
 845: /**
 846:  * Returns the URL of the next page. Use within If or while loops for pagination.
 847:  *
 848:  * @return string
 849:  */
 850: function getNextPageURL() {
 851:     return getPageNumURL(getCurrentPage() + 1);
 852: }
 853: 
 854: /**
 855:  * Prints the URL of the next page.
 856:  *
 857:  * @param string $text text for the URL
 858:  * @param string $title Text for the HTML title
 859:  * @param string $class Text for the HTML class
 860:  * @param string $id Text for the HTML id
 861:  */
 862: function printNextPageURL($text, $title = NULL, $class = NULL, $id = NULL) {
 863:     if (hasNextPage()) {
 864:         printLinkHTML(getNextPageURL(), $text, $title, $class, $id);
 865:     } else {
 866:         echo "<span class=\"disabledlink\">$text</span>";
 867:     }
 868: }
 869: 
 870: /**
 871:  * Returns TRUE if there is a previous page. Use within If or while loops for pagination.
 872:  *
 873:  * @return bool
 874:  */
 875: function hasPrevPage() {
 876:     return (getCurrentPage() > 1);
 877: }
 878: 
 879: /**
 880:  * Returns the URL of the previous page.
 881:  *
 882:  * @return string
 883:  */
 884: function getPrevPageURL() {
 885:     return getPageNumURL(getCurrentPage() - 1);
 886: }
 887: 
 888: /**
 889:  * Returns the URL of the previous page.
 890:  *
 891:  * @param string $text The linktext that should be printed as a link
 892:  * @param string $title The text the html-tag "title" should contain
 893:  * @param string $class Insert here the CSS-class name you want to style the link with
 894:  * @param string $id Insert here the CSS-ID name you want to style the link with
 895:  */
 896: function printPrevPageURL($text, $title = NULL, $class = NULL, $id = NULL) {
 897:     if (hasPrevPage()) {
 898:         printLinkHTML(getPrevPageURL(), $text, $title, $class, $id);
 899:     } else {
 900:         echo "<span class=\"disabledlink\">$text</span>";
 901:     }
 902: }
 903: 
 904: /**
 905:  * Prints a page navigation including previous and next page links
 906:  *
 907:  * @param string $prevtext Insert here the linktext like 'previous page'
 908:  * @param string $separator Insert here what you like to be shown between the prev and next links
 909:  * @param string $nexttext Insert here the linktext like "next page"
 910:  * @param string $class Insert here the CSS-class name you want to style the link with (default is "pagelist")
 911:  * @param string $id Insert here the CSS-ID name if you want to style the link with this
 912:  */
 913: function printPageNav($prevtext, $separator, $nexttext, $class = 'pagenav', $id = NULL) {
 914:     echo "<div" . (($id) ? " id=\"$id\"" : "") . " class=\"$class\">";
 915:     printPrevPageURL($prevtext, gettext("Previous Page"));
 916:     echo " $separator ";
 917:     printNextPageURL($nexttext, gettext("Next Page"));
 918:     echo "</div>\n";
 919: }
 920: 
 921: /**
 922:  * Prints a list of all pages.
 923:  *
 924:  * @param string $class the css class to use, "pagelist" by default
 925:  * @param string $id the css id to use
 926:  * @param int $navlen Number of navigation links to show (0 for all pages). Works best if the number is odd.
 927:  */
 928: function printPageList($class = 'pagelist', $id = NULL, $navlen = 9) {
 929:     printPageListWithNav(null, null, false, false, $class, $id, false, $navlen);
 930: }
 931: 
 932: /**
 933:  * returns a page nav list.
 934:  *
 935:  * @param bool $_oneImagePage set to true if there is only one image page as, for instance, in flash themes
 936:  * @param int $navlen Number of navigation links to show (0 for all pages). Works best if the number is odd.
 937:  * @param bool $firstlast Add links to the first and last pages of you gallery
 938:  * @param int $current the current page
 939:  * @param int $total total number of pages
 940:  *
 941:  */
 942: function getPageNavList($_oneImagePage, $navlen, $firstlast, $current, $total) {
 943:     $result = array();
 944:     if (hasPrevPage()) {
 945:         $result['prev'] = getPrevPageURL();
 946:     } else {
 947:         $result['prev'] = NULL;
 948:     }
 949:     if ($firstlast) {
 950:         $result[1] = getPageNumURL(1, $total);
 951:     }
 952: 
 953:     if ($navlen == 0) {
 954:         $navlen = $total;
 955:     }
 956:     $extralinks = 2;
 957:     if ($firstlast)
 958:         $extralinks = $extralinks + 2;
 959:     $len = floor(($navlen - $extralinks) / 2);
 960:     $j = max(round($extralinks / 2), min($current - $len - (2 - round($extralinks / 2)), $total - $navlen + $extralinks - 1));
 961:     $ilim = min($total, max($navlen - round($extralinks / 2), $current + floor($len)));
 962:     $k1 = round(($j - 2) / 2) + 1;
 963:     $k2 = $total - round(($total - $ilim) / 2);
 964: 
 965:     for ($i = $j; $i <= $ilim; $i++) {
 966:         $result[$i] = getPageNumURL($i, $total);
 967:     }
 968:     if ($firstlast) {
 969:         $result[$total] = getPageNumURL($total, $total);
 970:     }
 971:     if (hasNextPage()) {
 972:         $result['next'] = getNextPageURL();
 973:     } else {
 974:         $result['next'] = NULL;
 975:     }
 976:     return $result;
 977: }
 978: 
 979: /**
 980:  * Prints a full page navigation including previous and next page links with a list of all pages in between.
 981:  *
 982:  * @param string $prevtext Insert here the linktext like 'previous page'
 983:  * @param string $nexttext Insert here the linktext like 'next page'
 984:  * @param bool $_oneImagePage set to true if there is only one image page as, for instance, in flash themes
 985:  * @param string $nextprev set to true to get the 'next' and 'prev' links printed
 986:  * @param string $class Insert here the CSS-class name you want to style the link with (default is "pagelist")
 987:  * @param string $id Insert here the CSS-ID name if you want to style the link with this
 988:  * @param bool $firstlast Add links to the first and last pages of you gallery
 989:  * @param int $navlen Number of navigation links to show (0 for all pages). Works best if the number is odd.
 990:  */
 991: function printPageListWithNav($prevtext, $nexttext, $_oneImagePage = false, $nextprev = true, $class = 'pagelist', $id = NULL, $firstlast = true, $navlen = 9) {
 992:     $current = getCurrentPage();
 993:     $total = max(1, getTotalPages($_oneImagePage));
 994:     $nav = getPageNavList($_oneImagePage, $navlen, $firstlast, $current, $total);
 995:     if ($total > 1) {
 996:         ?>
 997:         <div <?php if ($id) echo ' id="'.$id.'"'; ?> class="<?php echo $class; ?>">
 998:             <ul class="<?php echo $class; ?>">
 999:                 <?php
1000:                 $prev = $nav['prev'];
1001:                 unset($nav['prev']);
1002:                 $next = $nav['next'];
1003:                 unset($nav['next']);
1004:                 if ($nextprev) {
1005:                     ?>
1006:                     <li class="prev">
1007:                         <?php
1008:                         if ($prev) {
1009:                             printLinkHTML($prev, html_encode($prevtext), gettext('Previous Page'));
1010:                         } else {
1011:                             ?>
1012:                             <span class="disabledlink"><?php echo html_encode($prevtext); ?></span>
1013:                             <?php
1014:                         }
1015:                         ?>
1016:                     </li>
1017:                     <?php
1018:                 }
1019:                 $last = NULL;
1020:                 if ($firstlast) {
1021:                     ?>
1022:                     <li class="<?php
1023:                     if ($current == 1)
1024:                         echo 'current';
1025:                     else
1026:                         echo 'first';
1027:                     ?>">
1028:                                 <?php
1029:                                 if ($current == 1) {
1030:                                     echo '1';
1031:                                 } else {
1032:                                     printLinkHTML($nav[1], 1, gettext("Page 1"));
1033:                                 }
1034:                                 ?>
1035:                     </li>
1036:                     <?php
1037:                     $last = 1;
1038:                     unset($nav[1]);
1039:                 }
1040:                 foreach ($nav as $i => $link) {
1041:                     $d = $i - $last;
1042:                     if ($d > 2) {
1043:                         ?>
1044:                         <li>
1045:                             <?php
1046:                             $k1 = $i - (int) (($i - $last) / 2);
1047:                             printLinkHTML(getPageNumURL($k1, $total), '...', sprintf(ngettext('Page %u', 'Page %u', $k1), $k1));
1048:                             ?>
1049:                         </li>
1050:                         <?php
1051:                     } else if ($d == 2) {
1052:                         ?>
1053:                         <li>
1054:                             <?php
1055:                             $k1 = $last + 1;
1056:                             printLinkHTML(getPageNumURL($k1, $total), $k1, sprintf(ngettext('Page %u', 'Page %u', $k1), $k1));
1057:                             ?>
1058:                         </li>
1059:                         <?php
1060:                     }
1061:                     ?>
1062:                     <li<?php if ($current == $i) echo ' class="current"'; ?>>
1063:                         <?php
1064:                         if ($i == $current) {
1065:                             echo $i;
1066:                         } else {
1067:                             $title = sprintf(ngettext('Page %1$u', 'Page %1$u', $i), $i);
1068:                             printLinkHTML($link, $i, $title);
1069:                         }
1070:                         ?>
1071:                     </li>
1072:                     <?php
1073:                     $last = $i;
1074:                     unset($nav[$i]);
1075:                     if ($firstlast && count($nav) == 1) {
1076:                         break;
1077:                     }
1078:                 }
1079:                 if ($firstlast) {
1080:                     foreach ($nav as $i => $link) {
1081:                         $d = $i - $last;
1082:                         if ($d > 2) {
1083:                             $k1 = $i - (int) (($i - $last) / 2);
1084:                             ?>
1085:                             <li>
1086:                                 <?php printLinkHTML(getPageNumURL($k1, $total), '...', sprintf(ngettext('Page %u', 'Page %u', $k1), $k1)); ?>
1087:                             </li>
1088:                             <?php
1089:                         } else if ($d == 2) {
1090:                             $k1 = $last + 1;
1091:                             ?>
1092:                             <li>
1093:                                 <?php printLinkHTML(getPageNumURL($k1, $total), $k1, sprintf(ngettext('Page %u', 'Page %u', $k1), $k1)); ?>
1094:                             </li>
1095:                             <?php
1096:                         }
1097:                         ?>
1098:                         <li class="last<?php if ($current == $i) echo ' current'; ?>">
1099:                             <?php
1100:                             if ($current == $i) {
1101:                                 echo $i;
1102:                             } else {
1103:                                 printLinkHTML($link, $i, sprintf(ngettext('Page %u', 'Page %u', $i), $i));
1104:                             }
1105:                             ?>
1106:                         </li>
1107:                         <?php
1108:                     }
1109:                 }
1110:                 if ($nextprev) {
1111:                     ?>
1112:                     <li class="next">
1113:                         <?php
1114:                         if ($next) {
1115:                             printLinkHTML($next, html_encode($nexttext), gettext('Next Page'));
1116:                         } else {
1117:                             ?>
1118:                             <span class="disabledlink"><?php echo html_encode($nexttext); ?></span>
1119:                             <?php
1120:                         }
1121:                         ?>
1122:                     </li>
1123:                     <?php
1124:                 }
1125:                 ?>
1126:             </ul>
1127:         </div>
1128:         <?php
1129:     }
1130: }
1131: 
1132: //*** Album Context ************************
1133: //******************************************
1134: 
1135: /**
1136:  * Sets the album passed as the current album
1137:  *
1138:  * @param object $album the album to be made current
1139:  */
1140: function makeAlbumCurrent($album) {
1141:     global $_zp_current_album;
1142:     $_zp_current_album = $album;
1143:     set_context(ZP_INDEX | ZP_ALBUM);
1144: }
1145: 
1146: /**
1147:  * Returns the raw title of the current album.
1148:  *
1149:  * @return string
1150:  */
1151: function getAlbumTitle() {
1152:     if (!in_context(ZP_ALBUM))
1153:         return false;
1154:     global $_zp_current_album;
1155:     return $_zp_current_album->getTitle();
1156: }
1157: 
1158: /**
1159:  * Returns a text-only title of the current album.
1160:  *
1161:  * @return string
1162:  */
1163: function getBareAlbumTitle() {
1164:     return getBare(getAlbumTitle());
1165: }
1166: 
1167: /**
1168:  * Returns an album title taged with of Not visible or password protected status
1169:  *
1170:  * @return string;
1171:  */
1172: function getAnnotatedAlbumTitle() {
1173:     global $_zp_current_album;
1174:     $title = getBareAlbumTitle();
1175:     $pwd = $_zp_current_album->getPassword();
1176:     if (zp_loggedin() && !empty($pwd)) {
1177:         $title .= "\n" . gettext('The album is password protected.');
1178:     }
1179:     if (!$_zp_current_album->getShow()) {
1180:         $title .= "\n" . gettext('The album is un-published.');
1181:     }
1182:     return $title;
1183: }
1184: 
1185: function printAnnotatedAlbumTitle() {
1186:     echo html_encode(getAnnotatedAlbumTitle());
1187: }
1188: 
1189: /**
1190:  * Prints an encapsulated title of the current album.
1191:  * If you are logged in you can click on this to modify the title on the fly.
1192:  *
1193:  * @author Ozh
1194:  */
1195: function printAlbumTitle() {
1196:     echo html_encodeTagged(getAlbumTitle());
1197: }
1198: 
1199: function printBareAlbumTitle() {
1200:     echo html_encodeTagged(getBareAlbumTitle());
1201: }
1202: 
1203: /**
1204:  * Gets the 'n' for n of m albums
1205:  *
1206:  * @return int
1207:  */
1208: function albumNumber() {
1209:     global $_zp_current_album, $_zp_current_image, $_zp_current_search, $_zp_gallery;
1210:     $name = $_zp_current_album->getFileName();
1211:     if (in_context(ZP_SEARCH)) {
1212:         $albums = $_zp_current_search->getAlbums();
1213:     } else if (in_context(ZP_ALBUM)) {
1214:         $parent = $_zp_current_album->getParent();
1215:         if (is_null($parent)) {
1216:             $albums = $_zp_gallery->getAlbums();
1217:         } else {
1218:             $albums = $parent->getAlbums();
1219:         }
1220:     }
1221:     $c = 0;
1222:     foreach ($albums as $albumfolder) {
1223:         $c++;
1224:         if ($name == $albumfolder) {
1225:             return $c;
1226:         }
1227:     }
1228:     return false;
1229: }
1230: 
1231: /**
1232:  * Returns an array of the names of the parents of the current album.
1233:  *
1234:  * @param object $album optional album object to use inseted of the current album
1235:  * @return array
1236:  */
1237: function getParentAlbums($album = null) {
1238:     $parents = array();
1239:     if (in_context(ZP_ALBUM)) {
1240:         global $_zp_current_album, $_zp_current_search, $_zp_gallery;
1241:         if (is_null($album)) {
1242:             if (in_context(ZP_SEARCH_LINKED) && !in_context(ZP_ALBUM_LINKED)) {
1243:                 $album = $_zp_current_search->getDynamicAlbum();
1244:                 if (empty($album))
1245:                     return $parents;
1246:             } else {
1247:                 $album = $_zp_current_album;
1248:             }
1249:         }
1250:         while (!is_null($album = $album->getParent())) {
1251:             array_unshift($parents, $album);
1252:         }
1253:     }
1254:     return $parents;
1255: }
1256: 
1257: /**
1258:  * returns the breadcrumb item for the current images's album
1259:  *
1260:  * @param string $title Text to be used as the URL title tag
1261:  * @return array
1262:  */
1263: function getAlbumBreadcrumb($title = NULL) {
1264:     global $_zp_current_search, $_zp_gallery, $_zp_current_album, $_zp_last_album;
1265:     $output = array();
1266:     if (in_context(ZP_SEARCH_LINKED)) {
1267:         $album = NULL;
1268:         $dynamic_album = $_zp_current_search->getDynamicAlbum();
1269:         if (empty($dynamic_album)) {
1270:             if (!is_null($_zp_current_album)) {
1271:                 if (in_context(ZP_ALBUM_LINKED) && $_zp_last_album == $_zp_current_album->name) {
1272:                     $album = $_zp_current_album;
1273:                 }
1274:             }
1275:         } else {
1276:             if (in_context(ZP_IMAGE) && in_context(ZP_ALBUM_LINKED)) {
1277:                 $album = $_zp_current_album;
1278:             } else {
1279:                 $album = $dynamic_album;
1280:             }
1281:         }
1282:     } else {
1283:         $album = $_zp_current_album;
1284:     }
1285:     if ($album) {
1286:         if (is_null($title)) {
1287:             $title = $album->getTitle();
1288:             if (empty($title)) {
1289:                 $title = gettext('Album Thumbnails');
1290:             }
1291:         }
1292:         return array('link' => $album->getLink(), 'text' => $title, 'title' => getBare($title));
1293:     }
1294:     return false;
1295: }
1296: 
1297: /**
1298:  * prints the breadcrumb item for the current images's album
1299:  *
1300:  * @param string $before Text to place before the breadcrumb
1301:  * @param string $after Text to place after the breadcrumb
1302:  * @param string $title Text to be used as the URL title attribute and text link
1303:  */
1304: function printAlbumBreadcrumb($before = '', $after = '', $title = NULL) {
1305:     if ($breadcrumb = getAlbumBreadcrumb($title)) {
1306:         if ($before) {
1307:             $output = '<span class="beforetext">' . html_encode($before) . '</span>';
1308:         } else {
1309:             $output = '';
1310:         }
1311:         $output .= '<a href="' . html_encode($breadcrumb['link']) . '" title="' . html_encode($breadcrumb['title']) . '">';
1312:         $output .= html_encode($breadcrumb['text']);
1313:         $output .= '</a>';
1314:         if ($after) {
1315:             $output .= '<span class="aftertext">' . html_encode($after) . '</span>';
1316:         }
1317:         echo $output;
1318:     }
1319: }
1320: 
1321: /**
1322:  * Prints the "breadcrumb" for a search page
1323:  *      if the search was for a data range, the breadcrumb is "Archive"
1324:  *      otherwise it is "Search"
1325:  * @param string $between Insert here the text to be printed between the links
1326:  * @param string $class is the class for the link (if present)
1327:  * @param string $search text for a search page title
1328:  * @param string $archive text for an archive page title
1329:  * @param string $format data format for archive page crumb
1330:  */
1331: function printSearchBreadcrumb($between = NULL, $class = NULL, $search = NULL, $archive = NULL, $format = '%B %Y') {
1332:     global $_zp_current_search;
1333:     if (is_null($between)) {
1334:         $between = ' | ';
1335:     }
1336:     if ($class) {
1337:         $class = ' class="' . $class . '"';
1338:     }
1339:     if ($d = $_zp_current_search->getSearchDate()) {
1340:         if (is_null($archive)) {
1341:             $text = gettext('Archive');
1342:             $textdecoration = true;
1343:         } else {
1344:             $text = getBare(html_encode($archive));
1345:             $textdecoration = false;
1346:         }
1347:         echo "<a href=\"" . html_encode(getCustomPageURL('archive', NULL)) . "\"$class title=\"" . $text . "\">";
1348:         printf('%s' . $text . '%s', $textdecoration ? '<em>' : '', $textdecoration ? '</em>' : '');
1349:         echo "</a>";
1350:         echo '<span class="betweentext">' . html_encode($between) . '</span>';
1351:         if ($format) {
1352:             $d = strtotime($d);
1353:             $d = strftime($format, $d);
1354:         }
1355:         echo $d;
1356:     } else {
1357:         if (is_null($search)) {
1358:             $text = gettext('Search');
1359:             $textdecoration = true;
1360:         } else {
1361:             $text = getBare(html_encode($search));
1362:             $textdecoration = false;
1363:         }
1364:         printf('%s' . $text . '%s', $textdecoration ? '<em>' : '', $textdecoration ? '</em>' : '');
1365:     }
1366: }
1367: 
1368: /**
1369:  * returns the breadcrumb navigation for album, gallery and image view.
1370:  *
1371:  * @return array
1372:  */
1373: function getParentBreadcrumb() {
1374:     global $_zp_gallery, $_zp_current_search, $_zp_current_album, $_zp_last_album;
1375:     $output = array();
1376:     if (in_context(ZP_SEARCH_LINKED)) {
1377:         $page = $_zp_current_search->page;
1378:         $searchwords = $_zp_current_search->getSearchWords();
1379:         $searchdate = $_zp_current_search->getSearchDate();
1380:         $searchfields = $_zp_current_search->getSearchFields(true);
1381:         $search_album_list = $_zp_current_search->getAlbumList();
1382:         if (!is_array($search_album_list)) {
1383:             $search_album_list = array();
1384:         }
1385:         $searchpagepath = getSearchURL($searchwords, $searchdate, $searchfields, $page, array('albums' => $search_album_list));
1386:         $dynamic_album = $_zp_current_search->getDynamicAlbum();
1387:         if (empty($dynamic_album)) {
1388:             if (empty($searchdate)) {
1389:                 $output[] = array('link' => $searchpagepath, 'title' => gettext("Return to search"), 'text' => gettext("Search"));
1390:                 if (is_null($_zp_current_album)) {
1391:                     return $output;
1392:                 } else {
1393:                     $parents = getParentAlbums();
1394:                 }
1395:             } else {
1396:                 return array(array('link' => $searchpagepath, 'title' => gettext("Return to archive"), 'text' => gettext("Archive")));
1397:             }
1398:         } else {
1399:             $album = $dynamic_album;
1400:             $parents = getParentAlbums($album);
1401:             if (in_context(ZP_ALBUM_LINKED)) {
1402:                 array_push($parents, $album);
1403:             }
1404:         }
1405: // remove parent links that are not in the search path
1406:         foreach ($parents as $key => $analbum) {
1407:             $target = $analbum->name;
1408:             if ($target !== $dynamic_album && !in_array($target, $search_album_list)) {
1409:                 unset($parents[$key]);
1410:             }
1411:         }
1412:     } else {
1413:         $parents = getParentAlbums();
1414:     }
1415:     $n = count($parents);
1416:     if ($n > 0) {
1417:         array_push($parents, $_zp_current_album);
1418:         $index = -1;
1419:         foreach ($parents as $parent) {
1420:             $index++;
1421:             if($index != 0) {
1422:                 $parentparent = $parents[$index-1];
1423:                 $page = $parent->getGalleryPage();
1424:                 $url = $parentparent->getLink($page);
1425:                 $output[] = array('link' => html_encode($url), 'title' => $parentparent->getTitle(), 'text' => $parentparent->getTitle());
1426:             }
1427:         }
1428:     }
1429:     return $output;
1430: }
1431: 
1432: /**
1433:  * Prints the breadcrumb navigation for album, gallery and image view.
1434:  *
1435:  * @param string $before Insert here the text to be printed before the links
1436:  * @param string $between Insert here the text to be printed between the links
1437:  * @param string $after Insert here the text to be printed after the links
1438:  * @param mixed $truncate if not empty, the max lenght of the description.
1439:  * @param string $elipsis the text to append to the truncated description
1440:  */
1441: function printParentBreadcrumb($before = NULL, $between = NULL, $after = NULL, $truncate = NULL, $elipsis = NULL) {
1442:     $crumbs = getParentBreadcrumb();
1443:     if (!empty($crumbs)) {
1444:         if (is_null($between)) {
1445:             $between = ' | ';
1446:         }
1447:         if (is_null($after)) {
1448:             $after = ' | ';
1449:         }
1450:         if (is_null($elipsis)) {
1451:             $elipsis = '...';
1452:         }
1453:         if ($before) {
1454:             $output = '<span class="beforetext">' . html_encode($before) . '</span>';
1455:         } else {
1456:             $output = '';
1457:         }
1458:         if ($between) {
1459:             $between = '<span class="betweentext">' . html_encode($between) . '</span>';
1460:         }
1461:         $i = 0;
1462:         foreach ($crumbs as $crumb) {
1463:             if ($i > 0) {
1464:                 $output .= $between;
1465:             }
1466: //cleanup things in description for use as attribute tag
1467:             $desc = $crumb['title'];
1468:             if (!empty($desc) && $truncate) {
1469:                 $desc = truncate_string($desc, $truncate, $elipsis);
1470:             }
1471:             $output .= '<a href="' . html_encode($crumb['link']) . '"' . ' title="' . html_encode(getBare($desc)) . '">' . html_encode($crumb['text']) . '</a>';
1472:             $i++;
1473:         }
1474:         if ($after) {
1475:             $output .= '<span class="aftertext">' . html_encode($after) . '</span>';
1476:         }
1477:         echo $output;
1478:     }
1479: }
1480: 
1481: /**
1482:  * Prints a link to the 'main website', not the Zenphoto site home page!
1483:  * Only prints the link if the url is not empty and does not point back the gallery page
1484:  *
1485:  * @param string $before text to precede the link
1486:  * @param string $after text to follow the link
1487:  * @param string $title Title text
1488:  * @param string $class optional css class
1489:  * @param string $id optional css id
1490:  *  */
1491: function printHomeLink($before = '', $after = '', $title = NULL, $class = NULL, $id = NULL) {
1492:     global $_zp_gallery;
1493:     $site = rtrim($_zp_gallery->getWebsiteURL(), '/');
1494:     if (!empty($site)) {
1495:         $name = $_zp_gallery->getWebsiteTitle();
1496:         if (empty($name)) {
1497:             $name = gettext('Home');
1498:         }
1499:         if ($site != SEO_FULLWEBPATH) {
1500:             if ($before) {
1501:                 echo '<span class="beforetext">' . html_encode($before) . '</span>';
1502:             }
1503:             printLinkHTML($site, $name, $title, $class, $id);
1504:             if ($after) {
1505:                 echo '<span class="aftertext">' . html_encode($after) . '</span>';
1506:             }
1507:         }
1508:     }
1509: }
1510: 
1511: /**
1512:  * Returns the formatted date field of the album
1513:  *
1514:  * @param string $format optional format string for the date
1515:  * @return string
1516:  */
1517: function getAlbumDate($format = null) {
1518:     global $_zp_current_album;
1519:     $d = $_zp_current_album->getDateTime();
1520:     if (empty($d) || ($d == '0000-00-00 00:00:00')) {
1521:         return false;
1522:     }
1523:     if (is_null($format)) {
1524:         return $d;
1525:     }
1526:     return zpFormattedDate($format, strtotime($d));
1527: }
1528: 
1529: /**
1530:  * Prints the date of the current album
1531:  *
1532:  * @param string $before Insert here the text to be printed before the date.
1533:  * @param string $format Format string for the date formatting
1534:  */
1535: function printAlbumDate($before = '', $format = NULL) {
1536:     global $_zp_current_album;
1537:     if (is_null($format)) {
1538:         $format = DATE_FORMAT;
1539:     }
1540:     $date = getAlbumDate($format);
1541:     if ($date) {
1542:         if ($before) {
1543:             $date = '<span class="beforetext">' . $before . '</span>' . $date;
1544:         }
1545:     }
1546:     echo html_encodeTagged($date);
1547: }
1548: 
1549: /**
1550:  * Returns the Location of the album.
1551:  *
1552:  * @return string
1553:  */
1554: function getAlbumLocation() {
1555:     global $_zp_current_album;
1556:     return $_zp_current_album->getLocation();
1557: }
1558: 
1559: /**
1560:  * Prints the location of the album
1561:  *
1562:  * @author Ozh
1563:  */
1564: function printAlbumLocation() {
1565:     echo html_encodeTagged(getAlbumLocation());
1566: }
1567: 
1568: /**
1569:  * Returns the raw description of the current album.
1570:  *
1571:  * @return string
1572:  */
1573: function getAlbumDesc() {
1574:     if (!in_context(ZP_ALBUM))
1575:         return false;
1576:     global $_zp_current_album;
1577:     return $_zp_current_album->getDesc();
1578: }
1579: 
1580: /**
1581:  * Returns a text-only description of the current album.
1582:  *
1583:  * @return string
1584:  */
1585: function getBareAlbumDesc() {
1586:     return getBare(getAlbumDesc());
1587: }
1588: 
1589: /**
1590:  * Prints description of the current album
1591:  *
1592:  * @author Ozh
1593:  */
1594: function printAlbumDesc() {
1595:     global $_zp_current_album;
1596:     echo html_encodeTagged(getAlbumDesc());
1597: }
1598: 
1599: function printBareAlbumDesc() {
1600:     echo html_encode(getBareAlbumDesc());
1601: }
1602: 
1603: /**
1604:  * Returns the custom_data field of the current album
1605:  *
1606:  * @return string
1607:  */
1608: function getAlbumCustomData() {
1609:     global $_zp_current_album;
1610:     return $_zp_current_album->getCustomData();
1611: }
1612: 
1613: /**
1614:  * Prints the custom_data field of the current album.
1615:  * Converts and displays line break in the admin field as <br />.
1616:  *
1617:  * @author Ozh
1618:  */
1619: function printAlbumCustomData() {
1620:     echo html_encodeTagged(getAlbumCustomData());
1621: }
1622: 
1623: /**
1624:  * A composit for getting album data
1625:  *
1626:  * @param string $field which field you want
1627:  * @return string
1628:  */
1629: function getAlbumData($field) {
1630:     if (!in_context(ZP_IMAGE))
1631:         return false;
1632:     global $_zp_album_image;
1633:     return get_language_string($_zp_album_image->get($field));
1634: }
1635: 
1636: /**
1637:  * Prints arbitrary data from the album object
1638:  *
1639:  * @param string $field the field name of the data desired
1640:  * @param string $label text to label the field
1641:  * @author Ozh
1642:  */
1643: function printAlbumData($field, $label = '') {
1644:     global $_zp_current_album;
1645:     echo html_encodeTagged($_zp_current_album->get($field));
1646: }
1647: 
1648: /**
1649:  * Returns the album page number of the current image
1650:  *
1651:  * @param object $album optional album object
1652:  * @return integer
1653:  */
1654: function getAlbumPage($album = NULL) {
1655:     global $_zp_current_album, $_zp_current_image, $_zp_current_search, $_firstPageImages;
1656:     if (is_null($album))
1657:         $album = $_zp_current_album;
1658:     $page = 0;
1659:     if (in_context(ZP_IMAGE) && !in_context(ZP_SEARCH)) {
1660:         if ($_zp_current_album->isDynamic()) {
1661:             $search = $_zp_current_album->getSearchEngine();
1662:             $imageindex = $search->getImageIndex($_zp_current_album->name, $_zp_current_image->filename);
1663:             $numalbums = $search->getNumAlbums();
1664:         } else {
1665:             $imageindex = $_zp_current_image->getIndex();
1666:             $numalbums = $album->getNumAlbums();
1667:         }
1668:         $imagepage = floor(($imageindex - $_firstPageImages) / max(1, getOption('images_per_page'))) + 1;
1669:         $albumpages = ceil($numalbums / max(1, getOption('albums_per_page')));
1670:         if ($albumpages == 0 && $_firstPageImages > 0)
1671:             $imagepage++;
1672:         $page = $albumpages + $imagepage;
1673:     }
1674:     return $page;
1675: }
1676: 
1677: /**
1678:  * Returns the album link url of the current album.
1679:  *
1680:  * @param object $album optional album object
1681:  * @return string
1682:  */
1683: function getAlbumURL($album = NULL) {
1684:     global $_zp_current_album;
1685:     if (is_null($album))
1686:         $album = $_zp_current_album;
1687:     if (in_context(ZP_IMAGE)) {
1688:         $page = getAlbumPage($album);
1689:         if ($page <= 1)
1690:             $page = 0;
1691:     } else {
1692:         $page = 0;
1693:     }
1694:     return $album->getLink($page);
1695: }
1696: 
1697: /**
1698:  * Prints the album link url of the current album.
1699:  *
1700:  * @param string $text Insert the link text here.
1701:  * @param string $title Insert the title text here.
1702:  * @param string $class Insert here the CSS-class name with with you want to style the link.
1703:  * @param string $id Insert here the CSS-id name with with you want to style the link.
1704:  */
1705: function printAlbumURL($text, $title, $class = NULL, $id = NULL) {
1706:     printLinkHTML(getAlbumURL(), $text, $title, $class, $id);
1707: }
1708: 
1709: /**
1710:  * Returns the name of the defined album thumbnail image.
1711:  *
1712:  * @return string
1713:  */
1714: function getAlbumThumb() {
1715:     global $_zp_current_album;
1716:     return $_zp_current_album->getThumb();
1717: }
1718: 
1719: /**
1720:  * Returns an img src link to the password protect thumb substitute
1721:  *
1722:  * @param string $extra extra stuff to put in the HTML
1723:  * @return string
1724:  */
1725: function getPasswordProtectImage($extra) {
1726:     global $_zp_themeroot;
1727:     $image = '';
1728:     $themedir = SERVERPATH . '/themes/' . basename($_zp_themeroot);
1729:     if (file_exists(internalToFilesystem($themedir . '/images/err-passwordprotected.png'))) {
1730:         $image = $_zp_themeroot . '/images/err-passwordprotected.png';
1731:     } else if (file_exists(internalToFilesystem($themedir . '/images/err-passwordprotected.gif'))) {
1732:         $image = $_zp_themeroot . '/images/err-passwordprotected.gif';
1733:     } else {
1734:         $image = WEBPATH . '/' . ZENFOLDER . '/images/err-passwordprotected.png';
1735:     }
1736:     return '<img src="' . $image . '" ' . $extra . ' alt="protected" />';
1737: }
1738: 
1739: /**
1740:  * Prints the album thumbnail image.
1741:  *
1742:  * @param string $alt Insert the text for the alternate image name here.
1743:  * @param string $class Insert here the CSS-class name with with you want to style the link.
1744:  * @param string $id Insert here the CSS-id name with with you want to style the link.
1745:  *  */
1746: function printAlbumThumbImage($alt, $class = NULL, $id = NULL) {
1747:     global $_zp_current_album, $_zp_themeroot;
1748:     if (!$_zp_current_album->getShow()) {
1749:         $class .= " not_visible";
1750:     }
1751:     $pwd = $_zp_current_album->getPassword();
1752:     if (!empty($pwd)) {
1753:         $class .= " password_protected";
1754:     }
1755: 
1756:     $class = trim($class);
1757:     if ($class) {
1758:         $class = ' class="' . $class . '"';
1759:     }
1760:     if ($id) {
1761:         $id = ' id="' . $id . '"';
1762:     }
1763:     $thumbobj = $_zp_current_album->getAlbumThumbImage();
1764:     $sizes = getSizeDefaultThumb($thumbobj);
1765:     $size = ' width="' . $sizes[0] . '" height="' . $sizes[1] . '"';
1766:     if (!getOption('use_lock_image') || $_zp_current_album->isMyItem(LIST_RIGHTS) || empty($pwd)) {
1767:         $html = '<img src="' . html_encode(pathurlencode($thumbobj->getThumb('album'))) . '"' . $size . ' alt="' . html_encode($alt) . '"' . $class . $id . ' />';
1768:         $html = zp_apply_filter('standard_album_thumb_html', $html);
1769:         echo $html;
1770:     } else {
1771:         echo getPasswordProtectImage($size);
1772:     }
1773: }
1774: 
1775: /**
1776:  * Returns a link to a custom sized thumbnail of the current album
1777:  *
1778:  * @param int $size the size of the image to have
1779:  * @param int $width width
1780:  * @param int $height height
1781:  * @param int $cropw crop width
1782:  * @param int $croph crop height
1783:  * @param int $cropx crop part x axis
1784:  * @param int $cropy crop part y axis
1785:  * @param bool $effects image effects (e.g. set 'gray' to force grayscale)
1786:  *
1787:  * @return string
1788:  */
1789: function getCustomAlbumThumb($size, $width = NULL, $height = NULL, $cropw = NULL, $croph = NULL, $cropx = NULL, $cropy = null, $effects = NULL) {
1790:     global $_zp_current_album;
1791:     $thumb = $_zp_current_album->getAlbumThumbImage();
1792:     return $thumb->getCustomImage($size, $width, $height, $cropw, $croph, $cropx, $cropy, true, $effects);
1793: }
1794: 
1795: /**
1796:  * Prints a link to a custom sized thumbnail of the current album
1797:  *
1798:  * See getCustomImageURL() for details.
1799:  *
1800:  * @param string $alt Alt atribute text
1801:  * @param int $size size
1802:  * @param int $width width
1803:  * @param int $height height
1804:  * @param int $cropw cropwidth
1805:  * @param int $croph crop height
1806:  * @param int $cropx crop part x axis
1807:  * @param int $cropy crop part y axis
1808:  * @param string $class css class
1809:  * @param string $id css id
1810:  *
1811:  * @return string
1812:  */
1813: function printCustomAlbumThumbImage($alt, $size, $width = NULL, $height = NULL, $cropw = NULL, $croph = NULL, $cropx = NULL, $cropy = null, $class = NULL, $id = NULL) {
1814:     global $_zp_current_album;
1815:     if (!$_zp_current_album->getShow()) {
1816:         $class .= " not_visible";
1817:     }
1818:     $pwd = $_zp_current_album->getPassword();
1819:     if (!empty($pwd)) {
1820:         $class .= " password_protected";
1821:     }
1822:     $class = trim($class);
1823:     /* set the HTML image width and height parameters in case this image was "imageDefault.png" substituted for no thumbnail then the thumb layout is preserved */
1824:     $sizing = '';
1825:     if (is_null($width)) {
1826:         if (!is_null($cropw) && !is_null($croph)) {
1827:             if (empty($height)) {
1828:                 $height = $size;
1829:             }
1830:             $s = round($height * ($cropw / $croph));
1831:             if (!empty($s))
1832:                 $sizing = ' width="' . $s . '"';
1833:         }
1834:     } else {
1835:         $sizing = ' width="' . $width . '"';
1836:     }
1837:     if (is_null($height)) {
1838:         if (!is_null($cropw) && !is_null($croph)) {
1839:             if (empty($width)) {
1840:                 $width = $size;
1841:             }
1842:             $s = round($width * ($croph / $cropw));
1843:             if (!empty($s))
1844:                 $sizing = $sizing . ' height="' . $s . '"';
1845:         }
1846:     } else {
1847:         $sizing = $sizing . ' height="' . $height . '"';
1848:     }
1849:     if (!getOption('use_lock_image') || $_zp_current_album->isMyItem(LIST_RIGHTS) || empty($pwd)) {
1850:         $html = '<img src="' . html_encode(pathurlencode(getCustomAlbumThumb($size, $width, $height, $cropw, $croph, $cropx, $cropy))) . '"' . $sizing . ' alt="' . html_encode($alt) . '"' .
1851:                         (($class) ? ' class="' . $class . '"' : '') . (($id) ? ' id="' . $id . '"' : '') . " />";
1852:         $html = zp_apply_filter('custom_album_thumb_html', $html);
1853:         echo $html;
1854:     } else {
1855:         echo getPasswordProtectImage($sizing);
1856:     }
1857: }
1858: 
1859: /**
1860:  * Called by ***MaxSpace functions to compute the parameters to be passed to xxCustomyyy functions.
1861:  *
1862:  * @param int $width maxspace width
1863:  * @param int $height maxspace height
1864:  * @param object $image the image in question
1865:  * @param bool $thumb true if for a thumbnail
1866:  */
1867: function getMaxSpaceContainer(&$width, &$height, $image, $thumb = false) {
1868:     global $_zp_gallery;
1869:     $upscale = getOption('image_allow_upscale');
1870:     $imagename = $image->filename;
1871:     if (!isImagePhoto($image) & $thumb) {
1872:         $imgfile = $image->getThumbImageFile();
1873:         $image = zp_imageGet($imgfile);
1874:         $s_width = zp_imageWidth($image);
1875:         $s_height = zp_imageHeight($image);
1876:     } else {
1877:         $s_width = $image->get('width');
1878:         if ($s_width == 0)
1879:             $s_width = max($width, $height);
1880:         $s_height = $image->get('height');
1881:         if ($s_height == 0)
1882:             $s_height = max($width, $height);
1883:     }
1884: 
1885:     $newW = round($height / $s_height * $s_width);
1886:     $newH = round($width / $s_width * $s_height);
1887:     if (DEBUG_IMAGE)
1888:         debugLog("getMaxSpaceContainer($width, $height, $imagename, $thumb): \$s_width=$s_width; \$s_height=$s_height; \$newW=$newW; \$newH=$newH; \$upscale=$upscale;");
1889:     if ($newW > $width) {
1890:         if ($upscale || $s_height > $newH) {
1891:             $height = $newH;
1892:         } else {
1893:             $height = $s_height;
1894:             $width = $s_width;
1895:         }
1896:     } else {
1897:         if ($upscale || $s_width > $newW) {
1898:             $width = $newW;
1899:         } else {
1900:             $height = $s_height;
1901:             $width = $s_width;
1902:         }
1903:     }
1904: }
1905: 
1906: /**
1907:  * Returns a link to a un-cropped custom sized version of the current album thumb within the given height and width dimensions.
1908:  *
1909:  * @param int $width width
1910:  * @param int $height height
1911:  * @return string
1912:  */
1913: function getCustomAlbumThumbMaxSpace($width, $height) {
1914:     global $_zp_current_album;
1915:     $albumthumb = $_zp_current_album->getAlbumThumbImage();
1916:     getMaxSpaceContainer($width, $height, $albumthumb, true);
1917:     return getCustomAlbumThumb(NULL, $width, $height, NULL, NULL, NULL, NULL);
1918: }
1919: 
1920: /**
1921:  * Prints a un-cropped custom sized album thumb within the given height and width dimensions.
1922:  * Note: a class of 'not_visible' or 'password_protected' will be added as appropriate
1923:  *
1924:  * @param string $alt Alt text for the url
1925:  * @param int $width width
1926:  * @param int $height height
1927:  * @param string $class Optional style class
1928:  * @param string $id Optional style id
1929:  * @param bool $thumbStandin set to true to treat as thumbnail
1930:  */
1931: function printCustomAlbumThumbMaxSpace($alt, $width, $height, $class = NULL, $id = NULL) {
1932:     global $_zp_current_album;
1933:     $albumthumb = $_zp_current_album->getAlbumThumbImage();
1934:     getMaxSpaceContainer($width, $height, $albumthumb, true);
1935:     printCustomAlbumThumbImage($alt, NULL, $width, $height, NULL, NULL, NULL, NULL, $class, $id);
1936: }
1937: 
1938: /**
1939:  * Returns the next album
1940:  *
1941:  * @return object
1942:  */
1943: function getNextAlbum() {
1944:     global $_zp_current_album, $_zp_current_search, $_zp_gallery;
1945:     if (in_context(ZP_SEARCH) || in_context(ZP_SEARCH_LINKED)) {
1946:         $nextalbum = $_zp_current_search->getNextAlbum($_zp_current_album->name);
1947:     } else if (in_context(ZP_ALBUM)) {
1948:         $nextalbum = $_zp_current_album->getNextAlbum();
1949:     } else {
1950:         return null;
1951:     }
1952:     return $nextalbum;
1953: }
1954: 
1955: /**
1956:  * Get the URL of the next album in the gallery.
1957:  *
1958:  * @return string
1959:  */
1960: function getNextAlbumURL() {
1961:     $nextalbum = getNextAlbum();
1962:     if ($nextalbum) {
1963:         return $nextalbum->getLink();
1964:     }
1965:     return false;
1966: }
1967: 
1968: /**
1969:  * Returns the previous album
1970:  *
1971:  * @return object
1972:  */
1973: function getPrevAlbum() {
1974:     global $_zp_current_album, $_zp_current_search;
1975:     if (in_context(ZP_SEARCH) || in_context(ZP_SEARCH_LINKED)) {
1976:         $prevalbum = $_zp_current_search->getPrevAlbum($_zp_current_album->name);
1977:     } else if (in_context(ZP_ALBUM)) {
1978:         $prevalbum = $_zp_current_album->getPrevAlbum();
1979:     } else {
1980:         return null;
1981:     }
1982:     return $prevalbum;
1983: }
1984: 
1985: /**
1986:  * Get the URL of the previous album in the gallery.
1987:  *
1988:  * @return string
1989:  */
1990: function getPrevAlbumURL() {
1991:     $prevalbum = getPrevAlbum();
1992:     if ($prevalbum) {
1993:         return $prevalbum->getLink();
1994:     }
1995:     return false;
1996: }
1997: 
1998: /**
1999:  * Returns true if this page has image thumbs on it
2000:  *
2001:  * @return bool
2002:  */
2003: function isImagePage() {
2004:     if (getNumImages()) {
2005:         global $_zp_page, $_firstPageImages;
2006:         $imagestart = getTotalPages(2); // # of album pages
2007:         if (!$_firstPageImages)
2008:             $imagestart++; // then images start on the last album page.
2009:         return $_zp_page >= $imagestart;
2010:     }
2011:     return false;
2012: }
2013: 
2014: /**
2015:  * Returns true if this page has album thumbs on it
2016:  *
2017:  * @return bool
2018:  */
2019: function isAlbumPage() {
2020:     global $_zp_page;
2021:     $pageCount = Ceil(getNumAlbums() / max(1, getOption('albums_per_page')));
2022:     return ($_zp_page <= $pageCount);
2023: }
2024: 
2025: /**
2026:  * Returns the number of images in the album.
2027:  *
2028:  * @return int
2029:  */
2030: function getNumImages() {
2031:     global $_zp_current_album, $_zp_current_search;
2032:     if ((in_context(ZP_SEARCH_LINKED) && !in_context(ZP_ALBUM_LINKED)) || in_context(ZP_SEARCH) && is_null($_zp_current_album)) {
2033:         return $_zp_current_search->getNumImages();
2034:     } else {
2035:         return $_zp_current_album->getNumImages();
2036:     }
2037: }
2038: 
2039: /**
2040:  * Returns the count of all the images in the album and any subalbums
2041:  *
2042:  * @param object $album The album whose image count you want
2043:  * @return int
2044:  * @since 1.1.4
2045:  */
2046: function getTotalImagesIn($album) {
2047:     global $_zp_gallery;
2048:     $sum = $album->getNumImages();
2049:     $subalbums = $album->getAlbums(0);
2050:     while (count($subalbums) > 0) {
2051:         $albumname = array_pop($subalbums);
2052:         $album = newAlbum($albumname);
2053:         $sum = $sum + getTotalImagesIn($album);
2054:     }
2055:     return $sum;
2056: }
2057: 
2058: /**
2059:  * Returns the next image on a page.
2060:  * sets $_zp_current_image to the next image in the album.
2061: 
2062:  * Returns true if there is an image to be shown
2063:  *
2064:  * @param bool $all set to true disable pagination
2065:  * @param int $firstPageCount the number of images which can go on the page that transitions between albums and images
2066:  *                          Normally this parameter should be NULL so as to use the default computations.
2067:  * @param bool $mine overridePassword the password check
2068:  * @return bool
2069:  *
2070:  * @return bool
2071:  */
2072: function next_image($all = false, $firstPageCount = NULL, $mine = NULL) {
2073:     global $_zp_images, $_zp_current_image, $_zp_current_album, $_zp_page, $_zp_current_image_restore, $_zp_current_search, $_zp_gallery, $_firstPageImages;
2074:     if (($mine != NULL && gettype($mine) != 'boolean') || func_num_args() > 3) {
2075:         internal_deprecations::next_image();
2076:     }
2077:     if (is_null($firstPageCount)) {
2078:         $firstPageCount = $_firstPageImages;
2079:     }
2080:     $imagePageOffset = getTotalPages(2); /* gives us the count of pages for album thumbs */
2081:     if ($all) {
2082:         $imagePage = 1;
2083:         $firstPageCount = 0;
2084:     } else {
2085:         $_firstPageImages = $firstPageCount; /* save this so pagination can see it */
2086:         $imagePage = $_zp_page - $imagePageOffset;
2087:     }
2088:     if ($firstPageCount > 0 && $imagePageOffset > 0) {
2089:         $imagePage = $imagePage + 1; /* can share with last album page */
2090:     }
2091:     if ($imagePage <= 0) {
2092:         return false; /* we are on an album page */
2093:     }
2094:     if (is_null($_zp_images)) {
2095:         if (in_context(ZP_SEARCH)) {
2096:             $_zp_images = $_zp_current_search->getImages($all ? 0 : ($imagePage), $firstPageCount, NULL, NULL, true, $mine);
2097:         } else {
2098:             $_zp_images = $_zp_current_album->getImages($all ? 0 : ($imagePage), $firstPageCount, NULL, NULL, true, $mine);
2099:         }
2100:         if (empty($_zp_images)) {
2101:             return NULL;
2102:         }
2103:         $_zp_current_image_restore = $_zp_current_image;
2104:         $img = array_shift($_zp_images);
2105:         $_zp_current_image = newImage($_zp_current_album, $img, true, true);
2106:         save_context();
2107:         add_context(ZP_IMAGE);
2108:         return true;
2109:     } else if (empty($_zp_images)) {
2110:         $_zp_images = NULL;
2111:         $_zp_current_image = $_zp_current_image_restore;
2112:         restore_context();
2113:         return false;
2114:     } else {
2115:         $img = array_shift($_zp_images);
2116:         $_zp_current_image = newImage($_zp_current_album, $img, true, true);
2117:         return true;
2118:     }
2119: }
2120: 
2121: //*** Image Context ************************
2122: //******************************************
2123: 
2124: /**
2125:  * Sets the image passed as the current image
2126:  *
2127:  * @param object $image the image to become current
2128:  */
2129: function makeImageCurrent($image) {
2130:     if (!is_object($image))
2131:         return;
2132:     global $_zp_current_album, $_zp_current_image;
2133:     $_zp_current_image = $image;
2134:     $_zp_current_album = $_zp_current_image->getAlbum();
2135:     set_context(ZP_INDEX | ZP_ALBUM | ZP_IMAGE);
2136: }
2137: 
2138: /**
2139:  * Returns the raw title of the current image.
2140:  *
2141:  * @return string
2142:  */
2143: function getImageTitle() {
2144:     if (!in_context(ZP_IMAGE))
2145:         return false;
2146:     global $_zp_current_image;
2147:     return $_zp_current_image->getTitle();
2148: }
2149: 
2150: /**
2151:  * Returns a text-only title of the current image.
2152:  *
2153:  * @return string
2154:  */
2155: function getBareImageTitle() {
2156:     return getBare(getImageTitle());
2157: }
2158: 
2159: /**
2160:  * Returns the image title taged with not visible annotation.
2161:  *
2162:  * @return string
2163:  */
2164: function getAnnotatedImageTitle() {
2165:     global $_zp_current_image;
2166:     $title = getBareImageTitle();
2167:     if (!$_zp_current_image->getShow()) {
2168:         $title .= "\n" . gettext('The image is marked un-published.');
2169:     }
2170:     return $title;
2171: }
2172: 
2173: function printAnnotatedImageTitle() {
2174:     echo html_encode(getAnnotatedImageTitle());
2175: }
2176: 
2177: /**
2178:  * Prints title of the current image
2179:  *
2180:  * @author Ozh
2181:  */
2182: function printImageTitle() {
2183:     echo html_encodeTagged(getImageTitle());
2184: }
2185: 
2186: function printBareImageTitle() {
2187:     echo html_encode(getBareImageTitle());
2188: }
2189: 
2190: /**
2191:  * Returns the 'n' of n of m images
2192:  *
2193:  * @return int
2194:  */
2195: function imageNumber() {
2196:     global $_zp_current_image, $_zp_current_search, $_zp_current_album;
2197:     $name = $_zp_current_image->getFileName();
2198:     if (in_context(ZP_SEARCH) || (in_context(ZP_SEARCH_LINKED) && !in_context(ZP_ALBUM_LINKED))) {
2199:         $folder = $_zp_current_image->imagefolder;
2200:         $images = $_zp_current_search->getImages();
2201:         $c = 0;
2202:         foreach ($images as $image) {
2203:             $c++;
2204:             if ($name == $image['filename'] && $folder == $image['folder']) {
2205:                 return $c;
2206:             }
2207:         }
2208:     } else {
2209:         return $_zp_current_image->getIndex() + 1;
2210:     }
2211:     return false;
2212: }
2213: 
2214: /**
2215:  * Returns the image date of the current image in yyyy-mm-dd hh:mm:ss format.
2216:  * Pass it a date format string for custom formatting
2217:  *
2218:  * @param string $format formatting string for the data
2219:  * @return string
2220:  */
2221: function getImageDate($format = null) {
2222:     if (!in_context(ZP_IMAGE))
2223:         return false;
2224:     global $_zp_current_image;
2225:     $d = $_zp_current_image->getDateTime();
2226:     if (empty($d) || ($d == '0000-00-00 00:00:00')) {
2227:         return false;
2228:     }
2229:     if (is_null($format)) {
2230:         return $d;
2231:     }
2232:     return zpFormattedDate($format, strtotime($d));
2233: }
2234: 
2235: /**
2236:  * Prints the date of the current album
2237:  *
2238:  * @param string $before Insert here the text to be printed before the date.
2239:  * @param string $format Format string for the date formatting
2240:  */
2241: function printImageDate($before = '', $format = null) {
2242:     global $_zp_current_image;
2243:     if (is_null($format)) {
2244:         $format = DATE_FORMAT;
2245:     }
2246:     $date = getImageDate($format);
2247:     if ($date) {
2248:         if ($before) {
2249:             $date = '<span class="beforetext">' . $before . '</span>' . $date;
2250:         }
2251:     }
2252:     echo html_encodeTagged($date);
2253: }
2254: 
2255: // IPTC fields
2256: /**
2257:  * Returns the Location field of the current image
2258:  *
2259:  * @return string
2260:  */
2261: function getImageLocation() {
2262:     if (!in_context(ZP_IMAGE))
2263:         return false;
2264:     global $_zp_current_image;
2265:     return $_zp_current_image->getLocation();
2266: }
2267: 
2268: /**
2269:  * Returns the City field of the current image
2270:  *
2271:  * @return string
2272:  */
2273: function getImageCity() {
2274:     if (!in_context(ZP_IMAGE))
2275:         return false;
2276:     global $_zp_current_image;
2277:     return $_zp_current_image->getcity();
2278: }
2279: 
2280: /**
2281:  * Returns the State field of the current image
2282:  *
2283:  * @return string
2284:  */
2285: function getImageState() {
2286:     if (!in_context(ZP_IMAGE))
2287:         return false;
2288:     global $_zp_current_image;
2289:     return $_zp_current_image->getState();
2290: }
2291: 
2292: /**
2293:  * Returns the Country field of the current image
2294:  *
2295:  * @return string
2296:  */
2297: function getImageCountry() {
2298:     if (!in_context(ZP_IMAGE))
2299:         return false;
2300:     global $_zp_current_image;
2301:     return $_zp_current_image->getCountry();
2302: }
2303: 
2304: /**
2305:  * Returns the raw description of the current image.
2306:  * new lines are replaced with <br /> tags
2307:  *
2308:  * @return string
2309:  */
2310: function getImageDesc() {
2311:     if (!in_context(ZP_IMAGE))
2312:         return false;
2313:     global $_zp_current_image;
2314:     return $_zp_current_image->getDesc();
2315: }
2316: 
2317: /**
2318:  * Returns a text-only description of the current image.
2319:  *
2320:  * @return string
2321:  */
2322: function getBareImageDesc() {
2323:     return getBare(getImageDesc());
2324: }
2325: 
2326: /**
2327:  * Prints the description of the current image.
2328:  * Converts and displays line breaks set in the admin field as <br />.
2329:  *
2330:  */
2331: function printImageDesc() {
2332:     echo html_encodeTagged(getImageDesc());
2333: }
2334: 
2335: function printBareImageDesc() {
2336:     echo html_encode(getBareImageDesc());
2337: }
2338: 
2339: /**
2340:  * A composit for getting image data
2341:  *
2342:  * @param string $field which field you want
2343:  * @return string
2344:  */
2345: function getImageData($field) {
2346:     if (!in_context(ZP_IMAGE))
2347:         return false;
2348:     global $_zp_current_image;
2349:     return get_language_string($_zp_current_image->get($field));
2350: }
2351: 
2352: /**
2353:  * Returns the custom_data field of the current image
2354:  *
2355:  * @return string
2356:  */
2357: function getImageCustomData() {
2358:     Global $_zp_current_image;
2359:     return $_zp_current_image->getCustomData();
2360: }
2361: 
2362: /**
2363:  * Prints the custom_data field of the current image.
2364:  * Converts and displays line breaks set in the admin field as <br />.
2365:  *
2366:  * @return string
2367:  */
2368: function printImageCustomData() {
2369:     $data = getImageCustomData();
2370:     $data = str_replace("\r\n", "\n", $data);
2371:     $data = str_replace("\n", "<br />", $data);
2372:     echo $data;
2373: }
2374: 
2375: /**
2376:  * Prints arbitrary data from the image object
2377:  *
2378:  * @param string $field the field name of the data desired
2379:  * @param string $label text to label the field.
2380:  * @author Ozh
2381:  */
2382: function printImageData($field, $label = '') {
2383:   global $_zp_current_image;
2384:   $text = getImageData($field);
2385:   if (!empty($text)) {
2386:     echo html_encodeTagged($label . $text);
2387:   }
2388: }
2389: 
2390: /**
2391:  * True if there is a next image
2392:  *
2393:  * @return bool
2394:  */
2395: function hasNextImage() {
2396:   global $_zp_current_image;
2397:   if (is_null($_zp_current_image))
2398:     return false;
2399:   return $_zp_current_image->getNextImage();
2400: }
2401: 
2402: /**
2403:  * True if there is a previous image
2404:  *
2405:  * @return bool
2406:  */
2407: function hasPrevImage() {
2408:   global $_zp_current_image;
2409:   if (is_null($_zp_current_image))
2410:     return false;
2411:   return $_zp_current_image->getPrevImage();
2412: }
2413: 
2414: /**
2415:  * Returns the url of the next image.
2416:  *
2417:  * @return string
2418:  */
2419: function getNextImageURL() {
2420:     if (!in_context(ZP_IMAGE))
2421:         return false;
2422:     global $_zp_current_album, $_zp_current_image;
2423:     if (is_null($_zp_current_image))
2424:         return false;
2425:     $nextimg = $_zp_current_image->getNextImage();
2426:     return $nextimg->getLink();
2427: }
2428: 
2429: /**
2430:  * Returns the url of the previous image.
2431:  *
2432:  * @return string
2433:  */
2434: function getPrevImageURL() {
2435:     if (!in_context(ZP_IMAGE))
2436:         return false;
2437:     global $_zp_current_album, $_zp_current_image;
2438:     if (is_null($_zp_current_image))
2439:         return false;
2440:     $previmg = $_zp_current_image->getPrevImage();
2441:     return $previmg->getLink();
2442: }
2443: 
2444: /**
2445:  * Returns the thumbnail of the previous image.
2446:  *
2447:  * @return string
2448:  */
2449: function getPrevImageThumb() {
2450:     if (!in_context(ZP_IMAGE))
2451:         return false;
2452:     global $_zp_current_image;
2453:     if (is_null($_zp_current_image))
2454:         return false;
2455:     $img = $_zp_current_image->getPrevImage();
2456:     return $img->getThumb();
2457: }
2458: 
2459: /**
2460:  * Returns the thumbnail of the next image.
2461:  *
2462:  * @return string
2463:  */
2464: function getNextImageThumb() {
2465:     if (!in_context(ZP_IMAGE))
2466:         return false;
2467:     global $_zp_current_image;
2468:     if (is_null($_zp_current_image))
2469:         return false;
2470:     $img = $_zp_current_image->getNextImage();
2471:     return $img->getThumb();
2472: }
2473: 
2474: /**
2475:  * Returns the url of the current image.
2476:  *
2477:  * @return string
2478:  */
2479: function getImageURL() {
2480:     if (!in_context(ZP_IMAGE))
2481:         return false;
2482:     global $_zp_current_image;
2483:     if (is_null($_zp_current_image))
2484:         return false;
2485:     return $_zp_current_image->getLink();
2486: }
2487: 
2488: /**
2489:  * Prints the link to the current  image.
2490:  *
2491:  * @param string $text text for the link
2492:  * @param string $title title tag for the link
2493:  * @param string $class optional style class for the link
2494:  * @param string $id optional style id for the link
2495:  */
2496: function printImageURL($text, $title, $class = NULL, $id = NULL) {
2497:     printLinkHTML(getImageURL(), $text, $title, $class, $id);
2498: }
2499: 
2500: /**
2501:  * Returns the Metadata infromation from the current image
2502:  *
2503:  * @param $image optional image object
2504:  * @param string $displayonly set to true to return only the items selected for display
2505:  * @return array
2506:  */
2507: function getImageMetaData($image = NULL, $displayonly = true) {
2508:     global $_zp_current_image, $_zp_exifvars;
2509:     if (is_null($image))
2510:         $image = $_zp_current_image;
2511:     if (is_null($image) || !$image->get('hasMetadata')) {
2512:         return false;
2513:     }
2514:     $data = $image->getMetaData();
2515:     if ($displayonly) {
2516:         foreach ($data as $field => $value) { //    remove the empty or not selected to display
2517:             if (!$value || !$_zp_exifvars[$field][3]) {
2518:                 unset($data[$field]);
2519:             }
2520:         }
2521:     }
2522:     if (count($data) > 0) {
2523:         return $data;
2524:     }
2525:     return false;
2526: }
2527: 
2528: /**
2529:  * Prints the Metadata data of the current image
2530:  *
2531:  * @param string $title title tag for the class
2532:  * @param bool $toggle set to true to get a javascript toggle on the display of the data
2533:  * @param string $id style class id
2534:  * @param string $class style class
2535:  * @author Ozh
2536:  */
2537: function printImageMetadata($title = NULL, $toggle = true, $id = 'imagemetadata', $class = null, $span = NULL) {
2538:     global $_zp_exifvars, $_zp_current_image;
2539:     if (false === ($exif = getImageMetaData($_zp_current_image, true))) {
2540:         return;
2541:     }
2542:     if (is_null($title)) {
2543:         $title = gettext('Image Info');
2544:     }
2545:     if ($class) {
2546:         $class = ' class="' . $class . '"';
2547:     }
2548:     if (!$span) {
2549:         $span = 'exif_link';
2550:     }
2551:     $dataid = $id . '_data';
2552:     if ($id) {
2553:         $id = ' id="' . $id . '"';
2554:     }
2555:     $refh = $refa = $style = '';
2556:     if ($toggle == 'colorbox' && zp_has_filter('theme_head', 'colorbox::css')) {
2557:         $refh = '<a href="#" class="colorbox" title="' . $title . '">';
2558:         $refa = '</a>';
2559:         $style = ' style="display:none"';
2560:     } else if ($toggle) {
2561:         $refh = '<a href="javascript:toggle(\'' . $dataid . '\');" title="' . $title . '">';
2562:         $refa = '</a>';
2563:         $style = ' style="display:none"';
2564:     }
2565:     ?>
2566:     <span id="<?php echo $span; ?>" class="metadata_title">
2567:         <?php echo $refh; ?><?php echo $title; ?><?php echo $refa; ?>
2568:     </span>
2569:     <div id="<?php echo $dataid; ?>"<?php echo $style; ?>>
2570:         <div<?php echo $id . $class; ?>>
2571:             <table>
2572:                 <?php
2573:                 foreach ($exif as $field => $value) {
2574:                     $label = $_zp_exifvars[$field][2];
2575:                     echo "<tr><td class=\"label\">$label:</td><td class=\"value\">";
2576:                     switch ($_zp_exifvars[$field][6]) {
2577:                         case 'time':
2578:                             echo zpFormattedDate(DATE_FORMAT, strtotime($value));
2579:                             break;
2580:                         default:
2581:                             echo html_encode($value);
2582:                             break;
2583:                     }
2584:                     echo "</td></tr>\n";
2585:                 }
2586:                 ?>
2587:             </table>
2588:         </div>
2589:     </div>
2590:     <?php
2591: }
2592: 
2593: /**
2594:  * Returns an array with the height & width
2595:  *
2596:  * @param int $size size
2597:  * @param int $width width
2598:  * @param int $height height
2599:  * @param int $cw crop width
2600:  * @param int $ch crop height
2601:  * @param int $cx crop x axis
2602:  * @param int $cy crop y axis
2603:  * @param $image object the image for which the size is desired. NULL means the current image
2604:  * @return array
2605:  */
2606: function getSizeCustomImage($size, $width = NULL, $height = NULL, $cw = NULL, $ch = NULL, $cx = NULL, $cy = NULL, $image = NULL) {
2607:   global $_zp_current_image;
2608:   if (is_null($image))
2609:     $image = $_zp_current_image;
2610:   if (is_null($image))
2611:     return false;
2612: 
2613:   $h = $image->getHeight();
2614:   $w = $image->getWidth();
2615:   if (isImageVideo($image)) { // size is determined by the player
2616:     return array($w, $h);
2617:   }
2618:   //if we set width/height we are cropping and those are the sizes already
2619:   if (is_null($size) && !is_null($width) && !is_null($height)) {
2620:     return array($width, $height);
2621:   }
2622:   $side = getOption('image_use_side');
2623:   $us = getOption('image_allow_upscale');
2624:   $args = getImageParameters(array($size, $width, $height, $cw, $ch, $cx, $cy, NULL, NULL, NULL, NULL, NULL, NULL, NULL), $image->album->name);
2625:   @list($size, $width, $height, $cw, $ch, $cx, $cy, $quality, $thumb, $crop, $thumbstandin, $passedWM, $adminrequest, $effects) = $args;
2626:   if (!empty($size)) {
2627:     $dim = $size;
2628:     $width = $height = false;
2629:   } else if (!empty($width)) {
2630:     $dim = $width;
2631:     $size = $height = false;
2632:   } else if (!empty($height)) {
2633:     $dim = $height;
2634:     $size = $width = false;
2635:   } else {
2636:     $dim = 1;
2637:   }
2638: 
2639:   if ($w == 0) {
2640:     $hprop = 1;
2641:   } else {
2642:     $hprop = round(($h / $w) * $dim);
2643:   }
2644:   if ($h == 0) {
2645:     $wprop = 1;
2646:   } else {
2647:     $wprop = round(($w / $h) * $dim);
2648:   }
2649: 
2650:   if (($size && ($side == 'longest' && $h > $w) || ($side == 'height') || ($side == 'shortest' && $h < $w)) || $height) {
2651: // Scale the height
2652:     $newh = $dim;
2653:     $neww = $wprop;
2654:   } else {
2655: // Scale the width
2656:     $neww = $dim;
2657:     $newh = $hprop;
2658:   }
2659:   if (!$us && $newh >= $h && $neww >= $w) {
2660:     return array($w, $h);
2661:   } else {
2662:     if ($cw && $cw < $neww)
2663:       $neww = $cw;
2664:     if ($ch && $ch < $newh)
2665:       $newh = $ch;
2666:     if ($size && $ch && $cw) {
2667:       $neww = $cw;
2668:       $newh = $ch;
2669:     }
2670:     return array($neww, $newh);
2671:   }
2672: }
2673: 
2674: /**
2675:  * Returns an array [width, height] of the default-sized image.
2676:  *
2677:  * @param int $size override the 'image_zize' option
2678:  * @param $image object the image for which the size is desired. NULL means the current image
2679:  *
2680:  * @return array
2681:  */
2682: function getSizeDefaultImage($size = NULL, $image = NULL) {
2683:   if (is_null($size))
2684:     $size = getOption('image_size');
2685:   return getSizeCustomImage($size, NULL, NULL, NULL, NULL, NULL, NULL, $image);
2686: }
2687: 
2688: /**
2689:  * Returns an array [width, height] of the original image.
2690:  *
2691:  * @param $image object the image for which the size is desired. NULL means the current image
2692:  *
2693:  * @return array
2694:  */
2695: function getSizeFullImage($image = NULL) {
2696:     global $_zp_current_image;
2697:     if (is_null($image))
2698:         $image = $_zp_current_image;
2699:     if (is_null($image))
2700:         return false;
2701:     return array($image->getWidth(), $image->getHeight());
2702: }
2703: 
2704: /**
2705:  * The width of the default-sized image (in printDefaultSizedImage)
2706:  *
2707:  * @param $image object the image for which the size is desired. NULL means the current image
2708:  *
2709:  * @return int
2710:  */
2711: function getDefaultWidth($size = NULL, $image = NULL) {
2712:     $size_a = getSizeDefaultImage($size, $image);
2713:     return $size_a[0];
2714: }
2715: 
2716: /**
2717:  * Returns the height of the default-sized image (in printDefaultSizedImage)
2718:  *
2719:  * @param $image object the image for which the size is desired. NULL means the current image
2720:  *
2721:  * @return int
2722:  */
2723: function getDefaultHeight($size = NULL, $image = NULL) {
2724:     $size_a = getSizeDefaultImage($size, $image);
2725:     return $size_a[1];
2726: }
2727: 
2728: /**
2729:  * Returns the width of the original image
2730:  *
2731:  * @param $image object the image for which the size is desired. NULL means the current image
2732:  *
2733:  * @return int
2734:  */
2735: function getFullWidth($image = NULL) {
2736:     global $_zp_current_image;
2737:     if (is_null($image))
2738:         $image = $_zp_current_image;
2739:     if (is_null($image))
2740:         return false;
2741:     return $image->getWidth();
2742: }
2743: 
2744: /**
2745:  * Returns the height of the original image
2746:  *
2747:  * @param $image object the image for which the size is desired. NULL means the current image
2748:  *
2749:  * @return int
2750:  */
2751: function getFullHeight($image = NULL) {
2752:     global $_zp_current_image;
2753:     if (is_null($image))
2754:         $image = $_zp_current_image;
2755:     if (is_null($image))
2756:         return false;
2757:     return $image->getHeight();
2758: }
2759: 
2760: /**
2761:  * Returns true if the image is landscape-oriented (width is greater than height)
2762:  *
2763:  * @param $image object the image for which the size is desired. NULL means the current image
2764:  *
2765:  * @return bool
2766:  */
2767: function isLandscape($image = NULL) {
2768:     if (getFullWidth($image) >= getFullHeight($image))
2769:         return true;
2770:     return false;
2771: }
2772: 
2773: /**
2774:  * Returns the url to the default sized image.
2775:  *
2776:  * @param $image object the image for which the size is desired. NULL means the current image
2777:  *
2778:  * @return string
2779:  */
2780: function getDefaultSizedImage($image = NULL) {
2781:     global $_zp_current_image;
2782:     if (is_null($image))
2783:         $image = $_zp_current_image;
2784:     if (is_null($image))
2785:         return false;
2786:     return $image->getSizedImage(getOption('image_size'));
2787: }
2788: 
2789: /**
2790:  * Show video player with video loaded or display the image.
2791:  *
2792:  * @param string $alt Alt text
2793:  * @param string $class Optional style class
2794:  * @param string $id Optional style id
2795:  */
2796: function printDefaultSizedImage($alt, $class = NULL, $id = NULL) {
2797:     global $_zp_current_image;
2798:     if (is_null($_zp_current_image))
2799:         return;
2800:     if (!$_zp_current_image->getShow()) {
2801:         $class .= " not_visible";
2802:     }
2803:     $album = $_zp_current_image->getAlbum();
2804:     $pwd = $album->getPassword();
2805:     if (!empty($pwd)) {
2806:         $class .= " password_protected";
2807:     }
2808:     if (isImagePhoto()) { //Print images
2809:         $html = '<img src="' . html_encode(pathurlencode(getDefaultSizedImage())) . '" alt="' . html_encode($alt) . '"' .
2810:                         ' width="' . getDefaultWidth() . '" height="' . getDefaultHeight() . '"' .
2811:                         (($class) ? " class=\"$class\"" : "") .
2812:                         (($id) ? " id=\"$id\"" : "") . " />";
2813:         $html = zp_apply_filter('standard_image_html', $html);
2814:         echo $html;
2815:     } else { // better be a plugin class then
2816:         echo $_zp_current_image->getContent();
2817:     }
2818: }
2819: 
2820: /**
2821:  * Returns the url to the thumbnail of the current image.
2822:  *
2823:  * @return string
2824:  */
2825: function getImageThumb() {
2826:     global $_zp_current_image;
2827:     if (is_null($_zp_current_image))
2828:         return false;
2829:     return $_zp_current_image->getThumb();
2830: }
2831: 
2832: /**
2833:  * @param string $alt Alt text
2834:  * @param string $class optional class tag
2835:  * @param string $id optional id tag
2836:  */
2837: function printImageThumb($alt, $class = NULL, $id = NULL) {
2838:     global $_zp_current_image;
2839:     if (is_null($_zp_current_image))
2840:         return;
2841:     if (!$_zp_current_image->getShow()) {
2842:         $class .= " not_visible";
2843:     }
2844:     $album = $_zp_current_image->getAlbum();
2845:     $pwd = $album->getPassword();
2846:     if (!empty($pwd)) {
2847:         $class .= " password_protected";
2848:     }
2849:     $url = getImageThumb();
2850:     $sizes = getSizeDefaultThumb();
2851:     $size = ' width="' . $sizes[0] . '" height="' . $sizes[1] . '"';
2852:     $class = trim($class);
2853:     if ($class) {
2854:         $class = ' class="' . $class . '"';
2855:     }
2856:     if ($id) {
2857:         $id = ' id="' . $id . '"';
2858:     }
2859:     $html = '<img src="' . html_encode(pathurlencode($url)) . '"' . $size . ' alt="' . html_encode($alt) . '"' . $class . $id . " />";
2860:     $html = zp_apply_filter('standard_image_thumb_html', $html);
2861:     echo $html;
2862: }
2863: 
2864: /**
2865:  * Gets the width and height of a default thumb for the <img> tag height/width
2866:  * @global type $_zp_current_image
2867:  * @param obj $image Image object, if NULL the current image is used
2868:  * @return aray
2869:  */
2870: function getSizeDefaultThumb($image = NULL) {
2871:     global $_zp_current_image;
2872:     if (is_null($image)) {
2873:         $image = $_zp_current_image;
2874:     }
2875:     $s = getOption('thumb_size');
2876:     if (getOption('thumb_crop')) {
2877:         $w = getOption('thumb_crop_width');
2878:         $h = getOption('thumb_crop_height');
2879:         if ($w > $h) {
2880:             //landscape
2881:             $h = round($h * $s / $w);
2882:             $w = $s;
2883:         } else {
2884:             //portrait
2885:             $w = round($w * $s / $h);
2886:             $h = $s;
2887:         }
2888:     } else {
2889:         $w = $h = $s;
2890:         getMaxSpaceContainer($w, $h, $image, true);
2891:     }
2892:     return array($w, $h);
2893: }
2894: 
2895: /**
2896:  * Returns the url to original image.
2897:  * It will return a protected image is the option "protect_full_image" is set
2898:  *
2899:  * @param $image optional image object
2900:  * @return string
2901:  */
2902: function getFullImageURL($image = NULL) {
2903:     global $_zp_current_image;
2904:     if (is_null($image)) {
2905:         $image = $_zp_current_image;
2906:     }
2907:     if (is_null($image)) {
2908:         return false;
2909:     }
2910:     $outcome = getOption('protect_full_image');
2911:     if ($outcome == 'No access') {
2912:         return NULL;
2913:     }
2914:     if ($outcome == 'Unprotected') {
2915:         return $image->getFullImageURL();
2916:     } else {
2917:         return getProtectedImageURL($image, $outcome);
2918:     }
2919: }
2920: 
2921: /**
2922:  * Returns the "raw" url to the image in the albums folder
2923:  *
2924:  * @param $image optional image object
2925:  * @return string
2926:  *
2927:  */
2928: function getUnprotectedImageURL($image = NULL) {
2929:     global $_zp_current_image;
2930:     if (is_null($image)) {
2931:         $image = $_zp_current_image;
2932:     }
2933:     if (!is_null($image)) {
2934:         return $image->getFullImageURL();
2935:     }
2936: }
2937: 
2938: /**
2939:  * Returns an url to the password protected/watermarked current image
2940:  *
2941:  * @param object $image optional image object overrides the current image
2942:  * @param string $disposal set to override the 'protect_full_image' option
2943:  * @return string
2944:  * */
2945: function getProtectedImageURL($image = NULL, $disposal = NULL) {
2946:     global $_zp_current_image;
2947:     if (is_null($disposal)) {
2948:         $disposal = getOption('protect_full_image');
2949:     }
2950:     if ($disposal == 'No access')
2951:         return NULL;
2952:     if (is_null($image)) {
2953:         if (!in_context(ZP_IMAGE))
2954:             return false;
2955:         if (is_null($_zp_current_image))
2956:             return false;
2957:         $image = $_zp_current_image;
2958:     }
2959:     $album = $image->getAlbum();
2960:     $watermark_use_image = getWatermarkParam($image, WATERMARK_FULL);
2961:     if (!empty($watermark_use_image)) {
2962:         $wmt = $watermark_use_image;
2963:     } else {
2964:         $wmt = false;
2965:     }
2966:     $args = array('FULL', NULL, NULL, NULL, NULL, NULL, NULL, (int) getOption('full_image_quality'), NULL, NULL, NULL, $wmt, false, NULL, NULL);
2967:     $cache_file = getImageCacheFilename($album->name, $image->filename, $args);
2968:     $cache_path = SERVERCACHE . $cache_file;
2969:     if ($disposal != 'Download' && OPEN_IMAGE_CACHE && file_exists($cache_path)) {
2970:         return WEBPATH . '/' . CACHEFOLDER . pathurlencode(imgSrcURI($cache_file));
2971:     } else if ($disposal == 'Unprotected') {
2972:         return getImageURI($args, $album->name, $image->filename, $image->filemtime);
2973:     } else {
2974:         $params = '&q=' . getOption('full_image_quality');
2975:         if (!empty($watermark_use_image)) {
2976:             $params .= '&wmk=' . $watermark_use_image;
2977:         }
2978:         if ($disposal) {
2979:             $params .= '&dsp=' . $disposal;
2980:         }
2981:         $params .= '&check=' . sha1(HASH_SEED . serialize($args));
2982:         if (is_array($image->filename)) {
2983:             $album = dirname($image->filename['source']);
2984:             $image = basename($image->filename['source']);
2985:         } else {
2986:             $album = $album->name;
2987:             $image = $image->filename;
2988:         }
2989:         return WEBPATH . '/' . ZENFOLDER . '/full-image.php?a=' . $album . '&i=' . $image . $params;
2990:     }
2991: }
2992: 
2993: /**
2994:  * Returns a link to the current image custom sized to $size
2995:  *
2996:  * @param int $size The size the image is to be
2997:  */
2998: function getSizedImageURL($size) {
2999:     return getCustomImageURL($size);
3000: }
3001: 
3002: /**
3003:  * Returns the url to the image with the dimensions you define with this function.
3004:  *
3005:  * @param int $size the size of the image to have
3006:  * @param int $width width
3007:  * @param int $height height
3008:  * @param int $cropw crop width
3009:  * @param int $croph crop height
3010:  * @param int $cropx crop part x axis
3011:  * @param int $cropy crop part y axis
3012:  * @param bool $thumbStandin set true to inhibit watermarking
3013:  * @param bool $effects image effects (e.g. set gray to force to grayscale)
3014:  * @return string
3015:  *
3016:  * $size, $width, and $height are used in determining the final image size.
3017:  * At least one of these must be provided. If $size is provided, $width and
3018:  * $height are ignored. If both $width and $height are provided, the image
3019:  * will have those dimensions regardless of the original image height/width
3020:  * ratio. (Yes, this means that the image may be distorted!)
3021:  *
3022:  * The $crop* parameters determine the portion of the original image that
3023:  * will be incorporated into the final image.
3024:  *
3025:  * $cropw and $croph "sizes" are typically proportional. That is you can
3026:  * set them to values that reflect the ratio of width to height that you
3027:  * want for the final image. Typically you would set them to the final
3028:  * height and width. These values will always be adjusted so that they are
3029:  * not larger than the original image dimensions.
3030:  *
3031:  * The $cropx and $cropy values represent the offset of the crop from the
3032:  * top left corner of the image. If these values are provided, the $croph
3033:  * and $cropw parameters are treated as absolute pixels not proportions of
3034:  * the image. If cropx and cropy are not provided, the crop will be
3035:  * "centered" in the image.
3036:  *
3037:  * When $cropx and $cropy are not provided the crop is offset from the top
3038:  * left proportionally to the ratio of the final image size and the crop
3039:  * size.
3040:  *
3041:  * Some typical croppings:
3042:  *
3043:  * $size=200, $width=NULL, $height=NULL, $cropw=200, $croph=100,
3044:  * $cropx=NULL, $cropy=NULL produces an image cropped to a 2x1 ratio which
3045:  * will fit in a 200x200 pixel frame.
3046:  *
3047:  * $size=NULL, $width=200, $height=NULL, $cropw=200, $croph=100, $cropx=100,
3048:  * $cropy=10 will will take a 200x100 pixel slice from (10,100) of the
3049:  * picture and create a 200x100 image
3050:  *
3051:  * $size=NULL, $width=200, $height=100, $cropw=200, $croph=120, $cropx=NULL,
3052:  * $cropy=NULL will produce a (distorted) image 200x100 pixels from a 1x0.6
3053:  * crop of the image.
3054:  *
3055:  * $size=NULL, $width=200, $height=NULL, $cropw=180, $croph=120, $cropx=NULL, $cropy=NULL
3056:  * will produce an image that is 200x133 from a 1.5x1 crop that is 5% from the left
3057:  * and 15% from the top of the image.
3058:  *
3059:  */
3060: function getCustomImageURL($size, $width = NULL, $height = NULL, $cropw = NULL, $croph = NULL, $cropx = NULL, $cropy = NULL, $thumbStandin = false, $effects = NULL) {
3061:     global $_zp_current_image;
3062:     if (is_null($_zp_current_image))
3063:         return false;
3064:     return $_zp_current_image->getCustomImage($size, $width, $height, $cropw, $croph, $cropx, $cropy, $thumbStandin, $effects);
3065: }
3066: 
3067: /**
3068:  * Print normal video or custom sized images.
3069:  * Note: a class of 'not_visible' or 'password_protected' will be added as appropriate
3070:  *
3071:  * Notes on cropping:
3072:  *
3073:  * The $crop* parameters determine the portion of the original image that will be incorporated
3074:  * into the final image. The w and h "sizes" are typically proportional. That is you can set them to
3075:  * values that reflect the ratio of width to height that you want for the final image. Typically
3076:  * you would set them to the fincal height and width.
3077:  *
3078:  * @param string $alt Alt text for the url
3079:  * @param int $size size
3080:  * @param int $width width
3081:  * @param int $height height
3082:  * @param int $cropw crop width
3083:  * @param int $croph crop height
3084:  * @param int $cropx crop x axis
3085:  * @param int $cropy crop y axis
3086:  * @param string $class Optional style class
3087:  * @param string $id Optional style id
3088:  * @param bool $thumbStandin set to true to treat as thumbnail
3089:  * @param bool $effects image effects (e.g. set gray to force grayscale)
3090: 
3091:  * */
3092: function printCustomSizedImage($alt, $size, $width = NULL, $height = NULL, $cropw = NULL, $croph = NULL, $cropx = NULL, $cropy = NULL, $class = NULL, $id = NULL, $thumbStandin = false, $effects = NULL) {
3093:     global $_zp_current_image;
3094:     if (is_null($_zp_current_image))
3095:         return;
3096:     if (!$_zp_current_image->getShow()) {
3097:         $class .= " not_visible";
3098:     }
3099:     $album = $_zp_current_image->getAlbum();
3100:     $pwd = $album->getPassword();
3101:     if (!empty($pwd)) {
3102:         $class .= " password_protected";
3103:     }
3104:     if ($size) {
3105:         $dims = getSizeCustomImage($size);
3106:         $sizing = ' width="' . $dims[0] . '" height="' . $dims[1] . '"';
3107:     } else {
3108:         $sizing = '';
3109:         if ($width)
3110:             $sizing .= ' width="' . $width . '"';
3111:         if ($height)
3112:             $sizing .= ' height="' . $height . '"';
3113:     }
3114:     if ($id)
3115:         $id = ' id="' . $id . '"';
3116:     if ($class)
3117:         $id .= ' class="' . $class . '"';
3118:     if (isImagePhoto() || $thumbStandin) {
3119:         $html = '<img src="' . html_encode(pathurlencode(getCustomImageURL($size, $width, $height, $cropw, $croph, $cropx, $cropy, $thumbStandin, $effects))) . '"' .
3120:                         ' alt="' . html_encode($alt) . '"' .
3121:                         $id .
3122:                         $sizing .
3123:                         ' />';
3124:         $html = zp_apply_filter('custom_image_html', $html, $thumbStandin);
3125:         echo $html;
3126:     } else { // better be a plugin
3127:         echo $_zp_current_image->getContent($width, $height);
3128:     }
3129: }
3130: 
3131: /**
3132:  * Returns a link to a un-cropped custom sized version of the current image within the given height and width dimensions.
3133:  * Use for sized images.
3134:  *
3135:  * @param int $width width
3136:  * @param int $height height
3137:  * @return string
3138:  */
3139: function getCustomSizedImageMaxSpace($width, $height) {
3140:     global $_zp_current_image;
3141:     if (is_null($_zp_current_image))
3142:         return false;
3143:     getMaxSpaceContainer($width, $height, $_zp_current_image);
3144:     return getCustomImageURL(NULL, $width, $height);
3145: }
3146: 
3147: /**
3148:  * Returns a link to a un-cropped custom sized version of the current image within the given height and width dimensions.
3149:  * Use for sized thumbnails.
3150:  *
3151:  * @param int $width width
3152:  * @param int $height height
3153:  * @return string
3154:  */
3155: function getCustomSizedImageThumbMaxSpace($width, $height) {
3156:     global $_zp_current_image;
3157:     if (is_null($_zp_current_image))
3158:         return false;
3159:     getMaxSpaceContainer($width, $height, $_zp_current_image, true);
3160:     return getCustomImageURL(NULL, $width, $height, NULL, NULL, NULL, NULL, true);
3161: }
3162: 
3163: /**
3164:  * Creates image thumbnails which will fit un-cropped within the width & height parameters given
3165:  *
3166:  * @param string $alt Alt text for the url
3167:  * @param int $width width
3168:  * @param int $height height
3169:  * @param string $class Optional style class
3170:  * @param string $id Optional style id
3171:  */
3172: function printCustomSizedImageThumbMaxSpace($alt, $width, $height, $class = NULL, $id = NULL) {
3173:     global $_zp_current_image;
3174:     if (is_null($_zp_current_image))
3175:         return;
3176:     getMaxSpaceContainer($width, $height, $_zp_current_image, true);
3177:     printCustomSizedImage($alt, NULL, $width, $height, NULL, NULL, NULL, NULL, $class, $id, true);
3178: }
3179: 
3180: /**
3181:  * Print normal video or un-cropped within the given height and width dimensions. Use for sized images or thumbnails in an album.
3182:  * Note: a class of 'not_visible' or 'password_protected' will be added as appropriate
3183:  *
3184:  * @param string $alt Alt text for the url
3185:  * @param int $width width
3186:  * @param int $height height
3187:  * @param string $class Optional style class
3188:  * @param string $id Optional style id
3189:  */
3190: function printCustomSizedImageMaxSpace($alt, $width, $height, $class = NULL, $id = NULL, $thumb = false) {
3191:     global $_zp_current_image;
3192:     if (is_null($_zp_current_image))
3193:         return;
3194:     getMaxSpaceContainer($width, $height, $_zp_current_image, $thumb);
3195:     printCustomSizedImage($alt, NULL, $width, $height, NULL, NULL, NULL, NULL, $class, $id, $thumb);
3196: }
3197: 
3198: /**
3199:  * Prints link to an image of specific size
3200:  * @param int $size how big
3201:  * @param string $text URL text
3202:  * @param string $title URL title
3203:  * @param string $class optional URL class
3204:  * @param string $id optional URL id
3205:  */
3206: function printSizedImageURL($size, $text, $title, $class = NULL, $id = NULL) {
3207:     printLinkHTML(getSizedImageURL($size), $text, $title, $class, $id);
3208: }
3209: 
3210: /**
3211:  *
3212:  * performs a query and then filters out "illegal" images returning the first "good" image
3213:  * used by the random image functions.
3214:  *
3215:  * @param object $result query result
3216:  * @param string $source album object if this is search within the album
3217:  */
3218: function filterImageQuery($result, $source) {
3219:     if ($result) {
3220:         while ($row = db_fetch_assoc($result)) {
3221:             $image = newImage(null, $row);
3222:    $album = $image->album;
3223:    if ($album->name == $source || $album->checkAccess()) {
3224:                 if (isImagePhoto($image)) {
3225:                     if ($image->checkAccess()) {
3226:                         return $image;
3227:                     }
3228:                 }
3229:             }
3230:         }
3231:         db_free_result($result);
3232:     }
3233:     return NULL;
3234: }
3235: 
3236: /**
3237:  * Returns a randomly selected image from the gallery. (May be NULL if none exists)
3238:  * @param bool $daily set to true and the picture changes only once a day.
3239:  *
3240:  * @return object
3241:  */
3242: function getRandomImages($daily = false) {
3243:     global $_zp_gallery;
3244:     if ($daily) {
3245:         $potd = getSerializedArray(getOption('picture_of_the_day'));
3246:         if (date('Y-m-d', $potd['day']) == date('Y-m-d')) {
3247:             $album = newAlbum($potd['folder'], true, true);
3248:             if ($album->exists) {
3249:                 $image = newImage($album, $potd['filename'], true);
3250:                 if ($image->exists) {
3251:                     return $image;
3252:                 }
3253:             }
3254:         }
3255:     }
3256:     if (zp_loggedin()) {
3257:         $imageWhere = '';
3258:     } else {
3259:    $imageWhere = " AND " . prefix('images') . ".show=1";
3260:     }
3261:     $result = query('SELECT `folder`, `filename` ' .
3262:                     ' FROM ' . prefix('images') . ', ' . prefix('albums') .
3263:                     ' WHERE ' . prefix('albums') . '.folder!="" AND ' . prefix('images') . '.albumid = ' .
3264:                     prefix('albums') . '.id ' . $imageWhere . ' ORDER BY RAND()');
3265: 
3266:     $image = filterImageQuery($result, NULL);
3267:     if ($image) {
3268:         if ($daily) {
3269:             $potd = array('day' => time(), 'folder' => $image->getAlbumName(), 'filename' => $image->getFileName());
3270:             setThemeOption('picture_of_the_day', serialize($potd), NULL, $_zp_gallery->getCurrentTheme());
3271:         }
3272:         return $image;
3273:     }
3274:     return NULL;
3275: }
3276: 
3277: /**
3278:  * Returns  a randomly selected image from the album or its subalbums. (May be NULL if none exists)
3279:  *
3280:  * @param mixed $rootAlbum optional album object/folder from which to get the image.
3281:  * @param bool $daily set to true to change picture only once a day.
3282:  *
3283:  * @return object
3284:  */
3285: function getRandomImagesAlbum($rootAlbum = NULL, $daily = false) {
3286:     global $_zp_current_album, $_zp_gallery;
3287:     if (empty($rootAlbum) && !in_context(ZP_ALBUM)) {
3288:         return null;
3289:     }
3290:     if (empty($rootAlbum)) {
3291:         $album = $_zp_current_album;
3292:     } else {
3293:         if (is_object($rootAlbum)) {
3294:             $album = $rootAlbum;
3295:         } else {
3296:             $album = newAlbum($rootAlbum);
3297:         }
3298:     }
3299:     if ($daily && ($potd = getOption('picture_of_the_day:' . $album->name))) {
3300:         $potd = getSerializedArray($potd);
3301:         if (date('Y-m-d', $potd['day']) == date('Y-m-d')) {
3302:             $rndalbum = newAlbum($potd['folder']);
3303:             $image = newImage($rndalbum, $potd['filename']);
3304:             if ($image->exists)
3305:                 return $image;
3306:         }
3307:     }
3308:     $image = NULL;
3309:     if ($album->isDynamic()) {
3310:         $images = $album->getImages(0);
3311:         shuffle($images);
3312:         while (count($images) > 0) {
3313:             $result = array_pop($images);
3314:             if (Gallery::validImage($result['filename'])) {
3315:                 $image = newImage(newAlbum($result['folder']), $result['filename']);
3316:             }
3317:         }
3318:     } else {
3319:         $albumfolder = $album->getFileName();
3320:         if ($album->isMyItem(LIST_RIGHTS)) {
3321:             $imageWhere = '';
3322:             $albumInWhere = '';
3323:         } else {
3324:             $imageWhere = " AND " . prefix('images') . ".show=1";
3325:             $albumInWhere = prefix('albums') . ".show=1";
3326:         }
3327:         $query = "SELECT id FROM " . prefix('albums') . " WHERE ";
3328:         if ($albumInWhere) {
3329:             $query .= $albumInWhere . ' AND ';
3330:         }
3331:         $query .= "folder LIKE " . db_quote(db_LIKE_escape($albumfolder) . '%');
3332:         $result = query($query);
3333:         if ($result) {
3334:             $albumids = array();
3335:             while ($row = db_fetch_assoc($result)) {
3336:                 $albumids[] = $row['id'];
3337:             }
3338:             if (empty($albumids)) {
3339:                 $albumInWhere = ' AND ' . $albumInWhere;
3340:             } else {
3341:                 $albumInWhere = ' AND ' . prefix('albums') . ".id IN (" . implode(',', $albumids) . ')';
3342:             }
3343:             db_free_result($result);
3344:             $sql = 'SELECT `folder`, `filename` ' .
3345:                             ' FROM ' . prefix('images') . ', ' . prefix('albums') .
3346:                             ' WHERE ' . prefix('albums') . '.folder!="" AND ' . prefix('images') . '.albumid = ' .
3347:                             prefix('albums') . '.id ' . $albumInWhere . $imageWhere . ' ORDER BY RAND()';
3348:             $result = query($sql);
3349:             $image = filterImageQuery($result, $album->name);
3350:         }
3351:     }
3352:     if ($image) {
3353:         if ($daily) {
3354:             $potd = array('day' => time(), 'folder' => $image->getAlbumName(), 'filename' => $image->getFileName());
3355:             setThemeOption('picture_of_the_day:' . $album->name, serialize($potd), NULL, $_zp_gallery->getCurrentTheme());
3356:         }
3357:     }
3358:     return $image;
3359: }
3360: 
3361: /**
3362:  * Puts up random image thumbs from the gallery
3363:  *
3364:  * @param int $number how many images
3365:  * @param string $class optional class
3366:  * @param string $option what you want selected: all for all images, album for selected ones from an album
3367:  * @param mixed $rootAlbum optional album object/folder from which to get the image.
3368:  * @param integer $width the width/cropwidth of the thumb if crop=true else $width is longest size.
3369:  * @param integer $height the height/cropheight of the thumb if crop=true else not used
3370:  * @param bool $crop 'true' (default) if the thumb should be cropped, 'false' if not
3371:  * @param bool $fullimagelink 'false' (default) for the image page link , 'true' for the unprotected full image link (to use Colorbox for example)
3372:  */
3373: function printRandomImages($number = 5, $class = null, $option = 'all', $rootAlbum = '', $width = NULL, $height = NULL, $crop = NULL, $fullimagelink = false) {
3374:     if (is_null($crop) && is_null($width) && is_null($height)) {
3375:         $crop = 2;
3376:     } else {
3377:         if (is_null($width))
3378:             $width = 85;
3379:         if (is_null($height))
3380:             $height = 85;
3381:         if (is_null($crop)) {
3382:             $crop = 1;
3383:         } else {
3384:             $crop = (int) $crop && true;
3385:         }
3386:     }
3387:     if (!empty($class))
3388:         $class = ' class="' . $class . '"';
3389:     echo "<ul" . $class . ">";
3390:     for ($i = 1; $i <= $number; $i++) {
3391:         switch ($option) {
3392:             case "all":
3393:                 $randomImage = getRandomImages();
3394:                 break;
3395:             case "album":
3396:                 $randomImage = getRandomImagesAlbum($rootAlbum);
3397:                 break;
3398:         }
3399:         if (is_object($randomImage) && $randomImage->exists) {
3400:             echo "<li>\n";
3401:             if ($fullimagelink) {
3402:                 $randomImageURL = $randomImage->getFullimageURL();
3403:             } else {
3404:                 $randomImageURL = $randomImage->getLink();
3405:             }
3406:             echo '<a href="' . html_encode($randomImageURL) . '" title="' . sprintf(gettext('View image: %s'), html_encode($randomImage->getTitle())) . '">';
3407:             switch ($crop) {
3408:                 case 0:
3409:                     $sizes = getSizeCustomImage($width, NULL, NULL, NULL, NULL, NULL, NULL, $randomImage);
3410:                     $html = '<img src="' . html_encode(pathurlencode($randomImage->getCustomImage($width, NULL, NULL, NULL, NULL, NULL, NULL, TRUE))) . '" width="' . $sizes[0] . '" height="' . $sizes[1] . '" alt="' . html_encode($randomImage->getTitle()) . '" />' . "\n";
3411:                     break;
3412:                 case 1:
3413:                     $sizes = getSizeCustomImage(NULL, $width, $height, $width, $height, NULL, NULL, $randomImage);
3414:                     $html = '<img src="' . html_encode(pathurlencode($randomImage->getCustomImage(NULL, $width, $height, $width, $height, NULL, NULL, TRUE))) . '" width="' . $sizes[0] . '" height="' . $sizes[1] . '" alt="' . html_encode($randomImage->getTitle()) . '" />' . "\n";
3415:                     break;
3416:                 case 2:
3417:                     $sizes = getSizeDefaultThumb($randomImage);
3418:                     //$html = '<img src="' . html_encode(pathurlencode($randomImage->getThumb())) . '" width="' . $sizes[0] . '" height="' . $sizes[1] . '" alt="' . html_encode($randomImage->getTitle()) . '" />' . "\n";
3419:       $html = $randomImage->filename." (".$randomImage->album->name.")";
3420:                     break;
3421:             }
3422:             echo zp_apply_filter('custom_image_html', $html, false);
3423:             echo "</a>";
3424:             echo "</li>\n";
3425:         } else {
3426:             break;
3427:         }
3428:     }
3429:     echo "</ul>";
3430: }
3431: 
3432: /**
3433:  * Returns a list of tags for context of the page called where called
3434:  *
3435:  * @return string
3436:  * @since 1.1
3437:  */
3438: function getTags() {
3439:     if (in_context(ZP_IMAGE)) {
3440:         global $_zp_current_image;
3441:         return $_zp_current_image->getTags();
3442:     } else if (in_context(ZP_ALBUM)) {
3443:         global $_zp_current_album;
3444:         return $_zp_current_album->getTags();
3445:     } else if (in_context(ZP_ZENPAGE_PAGE)) {
3446:         global $_zp_current_zenpage_page;
3447:         return $_zp_current_zenpage_page->getTags();
3448:     } else if (in_context(ZP_ZENPAGE_NEWS_ARTICLE)) {
3449:         global $_zp_current_zenpage_news;
3450:         return $_zp_current_zenpage_news->getTags();
3451:     }
3452:     return array();
3453: }
3454: 
3455: /**
3456:  * Prints a list of tags, editable by admin
3457:  *
3458:  * @param string $option links by default, if anything else the
3459:  *               tags will not link to all other images with the same tag
3460:  * @param string $preText text to go before the printed tags
3461:  * @param string $class css class to apply to the div surrounding the UL list
3462:  * @param string $separator what charactor shall separate the tags
3463:  * @since 1.1
3464:  */
3465: function printTags($option = 'links', $preText = NULL, $class = NULL, $separator = ', ') {
3466:     global $_zp_current_search;
3467:     if (is_null($class)) {
3468:         $class = 'taglist';
3469:     }
3470:     $singletag = getTags();
3471:     $tagstring = implode(', ', $singletag);
3472:     if ($tagstring === '' or $tagstring === NULL) {
3473:         $preText = '';
3474:     }
3475:     if (in_context(ZP_IMAGE)) {
3476:         $object = "image";
3477:     } else if (in_context(ZP_ALBUM)) {
3478:         $object = "album";
3479:     } else if (in_context(ZP_ZENPAGE_PAGE)) {
3480:         $object = "pages";
3481:     } else if (in_context(ZP_ZENPAGE_NEWS_ARTICLE)) {
3482:         $object = "news";
3483:     }
3484:     if (count($singletag) > 0) {
3485:         if (!empty($preText)) {
3486:             echo "<span class=\"tags_title\">" . $preText . "</span>";
3487:         }
3488:         echo "<ul class=\"" . $class . "\">\n";
3489:         if (is_object($_zp_current_search)) {
3490:             $albumlist = $_zp_current_search->getAlbumList();
3491:         } else {
3492:             $albumlist = NULL;
3493:         }
3494:         $ct = count($singletag);
3495:         $x = 0;
3496:         foreach ($singletag as $atag) {
3497:             if (++$x == $ct) {
3498:                 $separator = "";
3499:             }
3500:             if ($option === "links") {
3501:                 $links1 = "<a href=\"" . html_encode(getSearchURL(search_quote($atag), '', 'tags', 0, array('albums' => $albumlist))) . "\" title=\"" . html_encode($atag) . "\">";
3502:                 $links2 = "</a>";
3503:             } else {
3504:                 $links1 = $links2 = '';
3505:             }
3506:             echo "\t<li>" . $links1 . $atag . $links2 . $separator . "</li>\n";
3507:         }
3508:         echo "</ul>";
3509:     } else {
3510:         echo "$tagstring";
3511:     }
3512: }
3513: 
3514: /**
3515:  * Either prints all of the galleries tgs as a UL list or a cloud
3516:  *
3517:  * @param string $option "cloud" for tag cloud, "list" for simple list
3518:  * @param string $class CSS class
3519:  * @param string $sort "results" for relevance list, "random" for random ordering, otherwise the list is alphabetical
3520:  * @param bool $counter TRUE if you want the tag count within brackets behind the tag
3521:  * @param bool $links set to TRUE to have tag search links included with the tag.
3522:  * @param int $maxfontsize largest font size the cloud should display
3523:  * @param int $maxcount the floor count for setting the cloud font size to $maxfontsize
3524:  * @param int $mincount the minimum count for a tag to appear in the output
3525:  * @param int $limit set to limit the number of tags displayed to the top $numtags
3526:  * @param int $minfontsize minimum font size the cloud should display
3527:  * @param bool $exclude_unassigned True or false if you wish to exclude tags that are not assigne to any item (default: true)
3528:  * @param bool $checkaccess True or false (default: false) if you wish to exclude tags that are assigned to items (or are not assigned at all) the visitor is not allowed to see
3529:  * Beware that this may cause overhead on large sites. Usage of the static_html_cache is strongely recommended then.
3530:  * @since 1.1
3531:  */
3532: function printAllTagsAs($option, $class = '', $sort = NULL, $counter = FALSE, $links = TRUE, $maxfontsize = 2, $maxcount = 50, $mincount = 1, $limit = NULL, $minfontsize = 0.8, $exclude_unassigned = true, $checkaccess = false) {
3533:     global $_zp_current_search;
3534:     $option = strtolower($option);
3535:     if ($class != "") {
3536:         $class = ' class="' . $class . '"';
3537:     }
3538:     $tagcount = getAllTagsCount($exclude_unassigned, $checkaccess);
3539:     if (!is_array($tagcount)) {
3540:         return false;
3541:     }
3542:     switch ($sort) {
3543:         case 'results':
3544:             arsort($tagcount);
3545:             if (!is_null($limit)) {
3546:                 $tagcount = array_slice($tagcount, 0, $limit);
3547:             }
3548:             break;
3549:         case 'random':
3550:             if (!is_null($limit)) {
3551:                 $tagcount = array_slice($tagcount, 0, $limit);
3552:             }
3553:             shuffle_assoc($tagcount);
3554:             break;
3555:         default:
3556:             break;
3557:     }
3558:     ?>
3559:     <ul<?php echo $class; ?>>
3560:         <?php
3561:         if (count($tagcount) > 0) {
3562:             foreach ($tagcount as $key => $val) {
3563:                 if (!$counter) {
3564:                     $counter = "";
3565:                 } else {
3566:                     $counter = " (" . $val . ") ";
3567:                 }
3568:                 if ($option == "cloud") { // calculate font sizes, formula from wikipedia
3569:                     if ($val <= $mincount) {
3570:                         $size = $minfontsize;
3571:                     } else {
3572:                         $size = min(max(round(($maxfontsize * ($val - $mincount)) / ($maxcount - $mincount), 2), $minfontsize), $maxfontsize);
3573:                     }
3574:                     $size = str_replace(',', '.', $size);
3575:                     $size = ' style="font-size:' . $size . 'em;"';
3576:                 } else {
3577:                     $size = '';
3578:                 }
3579:                 if ($val >= $mincount) {
3580:                     if ($links) {
3581:                         if (is_object($_zp_current_search)) {
3582:                             $albumlist = $_zp_current_search->getAlbumList();
3583:                         } else {
3584:                             $albumlist = NULL;
3585:                         }
3586:                         $link = getSearchURL(search_quote($key), '', 'tags', 0, array('albums' => $albumlist));
3587:                         ?>
3588:                         <li>
3589:                             <a href="<?php echo html_encode($link); ?>"<?php echo $size; ?>><?php echo $key . $counter; ?></a>
3590:                         </li>
3591:                         <?php
3592:                     } else {
3593:                         ?>
3594:                         <li<?php echo $size; ?>><?php echo $key . $counter; ?></li>
3595:                         <?php
3596:                     }
3597:                 }
3598:             } // while end
3599:         } else {
3600:             ?>
3601:             <li><?php echo gettext('No popular tags'); ?></li>
3602:             <?php
3603:         }
3604:         ?>
3605:     </ul>
3606:     <?php
3607: }
3608: 
3609: /**
3610:  * Retrieves a list of all unique years & months from the images in the gallery
3611:  *
3612:  * @param string $order set to 'desc' for the list to be in descending order
3613:  * @return array
3614:  */
3615: function getAllDates($order = 'asc') {
3616:     $alldates = array();
3617:     $cleandates = array();
3618:     $sql = "SELECT `date` FROM " . prefix('images');
3619:     if (!zp_loggedin()) {
3620:         $sql .= " WHERE `show` = 1";
3621:     }
3622:     $hidealbums = getNotViewableAlbums();
3623:     if (!is_null($hidealbums)) {
3624:         if (zp_loggedin()) {
3625:             $sql .= ' WHERE ';
3626:         } else {
3627:             $sql .= ' AND ';
3628:         }
3629:         foreach ($hidealbums as $id) {
3630:             $sql .= '`albumid`!=' . $id . ' AND ';
3631:         }
3632:         $sql = substr($sql, 0, -5);
3633:     }
3634:     $result = query($sql);
3635:     if ($result) {
3636:         while ($row = db_fetch_assoc($result)) {
3637:             $alldates[] = $row['date'];
3638:         }
3639:         db_free_result($result);
3640:     }
3641:     foreach ($alldates as $adate) {
3642:         if (!empty($adate)) {
3643:             $cleandates[] = substr($adate, 0, 7) . "-01";
3644:         }
3645:     }
3646:     $datecount = array_count_values($cleandates);
3647:     if ($order == 'desc') {
3648:         krsort($datecount);
3649:     } else {
3650:         ksort($datecount);
3651:     }
3652:     return $datecount;
3653: }
3654: 
3655: /**
3656:  * Prints a compendum of dates and links to a search page that will show results of the date
3657:  *
3658:  * @param string $class optional class
3659:  * @param string $yearid optional class for "year"
3660:  * @param string $monthid optional class for "month"
3661:  * @param string $order set to 'desc' for the list to be in descending order
3662:  */
3663: function printAllDates($class = 'archive', $yearid = 'year', $monthid = 'month', $order = 'asc') {
3664:     global $_zp_current_search, $_zp_gallery_page;
3665:     if (empty($class)) {
3666:         $classactive = 'archive_active';
3667:     } else {
3668:         $classactive = $class . '_active';
3669:         $class = 'class="' . $class . '"';
3670:     }
3671:     if ($_zp_gallery_page == 'search.php') {
3672:         $activedate = getSearchDate('%Y-%m');
3673:     } else {
3674:         $activedate = '';
3675:     }
3676:     if (!empty($yearid)) {
3677:         $yearid = 'class="' . $yearid . '"';
3678:     }
3679:     if (!empty($monthid)) {
3680:         $monthid = 'class="' . $monthid . '"';
3681:     }
3682:     $datecount = getAllDates($order);
3683:     $lastyear = "";
3684:     echo "\n<ul $class>\n";
3685:     $nr = 0;
3686:     while (list($key, $val) = each($datecount)) {
3687:         $nr++;
3688:         if ($key == '0000-00-01') {
3689:             $year = "no date";
3690:             $month = "";
3691:         } else {
3692:             $dt = strftime('%Y-%B', strtotime($key));
3693:             $year = substr($dt, 0, 4);
3694:             $month = substr($dt, 5);
3695:         }
3696: 
3697:         if ($lastyear != $year) {
3698:             $lastyear = $year;
3699:             if ($nr != 1) {
3700:                 echo "</ul>\n</li>\n";
3701:             }
3702:             echo "<li $yearid>$year\n<ul $monthid>\n";
3703:         }
3704:         if (is_object($_zp_current_search)) {
3705:             $albumlist = $_zp_current_search->getAlbumList();
3706:         } else {
3707:             $albumlist = NULL;
3708:         }
3709:         $datekey = substr($key, 0, 7);
3710:         if ($activedate = $datekey) {
3711:             $cl = ' class="' . $classactive . '"';
3712:         } else {
3713:             $cl = '';
3714:         }
3715:         echo '<li' . $cl . '><a href="' . html_encode(getSearchURL('', $datekey, '', 0, array('albums' => $albumlist))) . '">' . $month . ' (' . $val . ')</a></li>' . "\n";
3716:     }
3717:     echo "</ul>\n</li>\n</ul>\n";
3718: }
3719: 
3720: /**
3721:  * Produces the url to a custom page (e.g. one that is not album.php, image.php, or index.php)
3722:  *
3723:  * @param string $linktext Text for the URL
3724:  * @param string $page page name to include in URL
3725:  * @param string $q query string to add to url
3726:  * @return string
3727:  */
3728: function getCustomPageURL($page, $q = '') {
3729:     global $_zp_current_album, $_zp_conf_vars;
3730:     if (array_key_exists($page, $_zp_conf_vars['special_pages'])) {
3731:         $result_r = preg_replace('~^_PAGE_/~', _PAGE_ . '/', $_zp_conf_vars['special_pages'][$page]['rewrite']) . '/';
3732:     } else {
3733:         $result_r = '/' . _PAGE_ . '/' . $page . '/';
3734:     }
3735:     $result = "index.php?p=$page";
3736: 
3737:     if (!empty($q)) {
3738:         $result_r .= "?$q";
3739:         $result .= "&$q";
3740:     }
3741:     return zp_apply_filter('getLink', rewrite_path($result_r, $result), $page . '.php', NULL);
3742: }
3743: 
3744: /**
3745:  * Prints the url to a custom page (e.g. one that is not album.php, image.php, or index.php)
3746:  *
3747:  * @param string $linktext Text for the URL
3748:  * @param string $page page name to include in URL
3749:  * @param string $q query string to add to url
3750:  * @param string $prev text to insert before the URL
3751:  * @param string $next text to follow the URL
3752:  * @param string $class optional class
3753:  */
3754: function printCustomPageURL($linktext, $page, $q = '', $prev = '', $next = '', $class = NULL) {
3755:     if (!is_null($class)) {
3756:         $class = 'class="' . $class . '"';
3757:     }
3758:     echo $prev . "<a href=\"" . html_encode(getCustomPageURL($page, $q)) . "\" $class title=\"" . html_encode($linktext) . "\">" . html_encode($linktext) . "</a>" . $next;
3759: }
3760: 
3761: //*** Search functions *******************************************************
3762: //****************************************************************************
3763: 
3764: /**
3765:  * tests if a search page is an "archive" page
3766:  *
3767:  * @return bool
3768:  */
3769: function isArchive() {
3770:     return isset($_REQUEST['date']);
3771: }
3772: 
3773: /**
3774:  * Returns a search URL
3775:  *
3776:  * @param mixed $words the search words target
3777:  * @param mixed $dates the dates that limit the search
3778:  * @param mixed $fields the fields on which to search
3779:  * @param int $page the page number for the URL
3780:  * @param array $object_list the list of objects to search
3781:  * @return string
3782:  * @since 1.1.3
3783:  */
3784: function getSearchURL($words, $dates, $fields, $page, $object_list = NULL) {
3785:     if (!is_null($object_list)) {
3786:         if (array_key_exists(0, $object_list)) { // handle old form albums list
3787:             internal_deprecations::getSearchURL();
3788:             $object_list = array('albums' => $object_list);
3789:         }
3790:     }
3791:     $urls = '';
3792:     $rewrite = false;
3793:     if (MOD_REWRITE) {
3794:         $rewrite = true;
3795:         if (is_array($object_list)) {
3796:             foreach ($object_list as $obj) {
3797:                 if ($obj) {
3798:                     $rewrite = false;
3799:                     break;
3800:                 }
3801:             }
3802:         }
3803:     }
3804: 
3805:     if ($rewrite) {
3806:         if (empty($dates)) {
3807:             $url = SEO_WEBPATH . '/' . _SEARCH_ . '/';
3808:         } else {
3809:             $url = SEO_WEBPATH . '/' . _ARCHIVE_ . '/';
3810:         }
3811:     } else {
3812:         $url = SEO_WEBPATH . "/index.php?p=search";
3813:     }
3814:     if (!empty($fields) && empty($dates)) {
3815:         if (!is_array($fields)) {
3816:             $fields = explode(',', $fields);
3817:         }
3818:         $temp = $fields;
3819:         if ($rewrite && count($fields) == 1 && array_shift($temp) == 'tags') {
3820:             $url = SEO_WEBPATH . '/' . _TAGS_ . '/';
3821:         } else {
3822:             $search = new SearchEngine();
3823:             $urls = $search->getSearchFieldsText($fields, 'searchfields=');
3824:         }
3825:     }
3826: 
3827:     if (!empty($words)) {
3828:         if (is_array($words)) {
3829:             foreach ($words as $key => $word) {
3830:                 $words[$key] = search_quote($word);
3831:             }
3832:             $words = implode(',', $words);
3833:         }
3834:         $words = strtr($words, array('%' => '__25__', '&' => '__26__', '#' => '__23__', '/' => '__2F__'));
3835:         if ($rewrite) {
3836:             $url .= urlencode($words) . '/';
3837:         } else {
3838:             $url .= "&words=" . urlencode($words);
3839:         }
3840:     }
3841:     if (!empty($dates)) {
3842:         if (is_array($dates)) {
3843:             $dates = implode(',', $dates);
3844:         }
3845:         if ($rewrite) {
3846:             $url .= $dates . '/';
3847:         } else {
3848:             $url .= "&date=$dates";
3849:         }
3850:     }
3851:     if ($page > 1) {
3852:         if ($rewrite) {
3853:             $url .= "$page/";
3854:         } else {
3855:             if ($urls) {
3856:                 $urls .= '&';
3857:             }
3858:             $urls .= "page=$page";
3859:         }
3860:     }
3861:     if (!empty($urls)) {
3862:         if ($rewrite) {
3863:             $url .= '?' . $urls;
3864:         } else {
3865:             $url .= '&' . $urls;
3866:         }
3867:     }
3868:     if (is_array($object_list)) {
3869:         foreach ($object_list as $key => $list) {
3870:             if (!empty($list)) {
3871:                 $url .= '&in' . $key . '=' . html_encode(implode(',', $list));
3872:             }
3873:         }
3874:     }
3875:     return $url;
3876: }
3877: 
3878: /**
3879:  * Prints the search form
3880:  *
3881:  * Search works on a list of tokens entered into the search form.
3882:  *
3883:  * Tokens may be part of boolean expressions using &, |, !, and parens. (Comma is retained as a synonom of | for
3884:  * backwords compatibility.)
3885:  *
3886:  * Tokens may be enclosed in quotation marks to create exact pattern matches or to include the boolean operators and
3887:  * parens as part of the tag..
3888:  *
3889:  * @param string $prevtext text to go before the search form
3890:  * @param string $id css id for the search form, default is 'search'
3891:  * @param string $buttonSource optional path to the image for the button or if not a path to an image,
3892:  *                                          this will be the button hint
3893:  * @param string $buttontext optional text for the button ("Search" will be the default text)
3894:  * @param string $iconsource optional theme based icon for the search fields toggle
3895:  * @param array $query_fields override selection for enabled fields with this list
3896:  * @param array $objects_list optional array of things to search eg. [albums]=>[list], etc.
3897:  *                                                      if the list is simply 0, the objects will be omitted from the search
3898:  * @param string $within set to true to search within current results, false to search fresh
3899:  * @since 1.1.3
3900:  */
3901: function printSearchForm($prevtext = NULL, $id = 'search', $buttonSource = NULL, $buttontext = '', $iconsource = NULL, $query_fields = NULL, $object_list = NULL, $within = NULL) {
3902:     global $_zp_adminJS_loaded, $_zp_current_search;
3903:     $engine = new SearchEngine();
3904:     if (!is_null($_zp_current_search) && !$_zp_current_search->getSearchWords()) {
3905:         $engine->clearSearchWords();
3906:     }
3907:     if (!is_null($object_list)) {
3908:         if (array_key_exists(0, $object_list)) { // handle old form albums list
3909:             trigger_error(gettext('printSearchForm $album_list parameter is deprecated. Pass array("albums"=>array(album, album, ...)) instead.'), E_USER_NOTICE);
3910:             $object_list = array('albums' => $object_list);
3911:         }
3912:     }
3913:     if (empty($buttontext)) {
3914:         $buttontext = gettext("Search");
3915:     }
3916:     $zf = WEBPATH . "/" . ZENFOLDER;
3917:     $searchwords = $engine->codifySearchString();
3918:     if (substr($searchwords, -1, 1) == ',') {
3919:         $searchwords = substr($searchwords, 0, -1);
3920:     }
3921:     if (empty($searchwords)) {
3922:         $within = false;
3923:         $hint = '%s';
3924:     } else {
3925:         $hint = gettext('%s within previous results');
3926:     }
3927:     if (preg_match('!\/(.*)[\.png|\.jpg|\.jpeg|\.gif]$!', $buttonSource)) {
3928:         $buttonSource = 'src="' . $buttonSource . '" alt="' . $buttontext . '"';
3929:         $button = 'title="' . sprintf($hint, $buttontext) . '"';
3930:         $type = 'image';
3931:     } else {
3932:         $type = 'submit';
3933:         if ($buttonSource) {
3934:             $button = 'value="' . $buttontext . '" title="' . sprintf($hint, $buttonSource) . '"';
3935:             $buttonSource = '';
3936:         } else {
3937:             $button = 'value="' . $buttontext . '" title="' . sprintf($hint, $buttontext) . '"';
3938:         }
3939:     }
3940:     if (empty($iconsource)) {
3941:         $iconsource = WEBPATH . '/' . ZENFOLDER . '/images/searchfields_icon.png';
3942:     }
3943:     if (is_null($within)) {
3944:         $within = getOption('search_within');
3945:     }
3946:     if (MOD_REWRITE) {
3947:         $searchurl = SEO_WEBPATH . '/' . _SEARCH_ . '/';
3948:     } else {
3949:         $searchurl = WEBPATH . "/index.php?p=search";
3950:     }
3951:     if (!$within) {
3952:         $engine->clearSearchWords();
3953:     }
3954: 
3955:     $fields = $engine->allowedSearchFields();
3956:     if (!$_zp_adminJS_loaded) {
3957:         $_zp_adminJS_loaded = true;
3958:         ?>
3959:         <script type="text/javascript" src="<?php echo WEBPATH . '/' . ZENFOLDER; ?>/js/admin.js"></script>
3960:         <?php
3961:     }
3962:     ?>
3963:     <div id="<?php echo $id; ?>">
3964:         <!-- search form -->
3965:         <form method="post" action="<?php echo $searchurl; ?>" id="search_form">
3966:             <script type="text/javascript">
3967:             // <!-- <![CDATA[
3968:             var within = <?php echo (int) $within; ?>;
3969:             function search_(way) {
3970:                 within = way;
3971:                 if (way) {
3972:                     $('#search_submit').attr('title', '<?php echo sprintf($hint, $buttontext); ?>');
3973:                 } else {
3974:                     lastsearch = '';
3975:                     $('#search_submit').attr('title', '<?php echo $buttontext; ?>');
3976:                 }
3977:                 $('#search_input').val('');
3978:             }
3979:             $('#search_form').submit(function() {
3980:                 if (within) {
3981:                     var newsearch = $.trim($('#search_input').val());
3982:                     if (newsearch.substring(newsearch.length - 1) == ',') {
3983:                         newsearch = newsearch.substr(0, newsearch.length - 1);
3984:                     }
3985:                     if (newsearch.length > 0) {
3986:                         $('#search_input').val('(<?php echo $searchwords; ?>) AND (' + newsearch + ')');
3987:                     } else {
3988:                         $('#search_input').val('<?php echo $searchwords; ?>');
3989:                     }
3990:                 }
3991:                 return true;
3992:             });
3993:     $(document).ready(function() {
3994:       $( $("#checkall_searchfields") ).on( "click", function() {
3995:         $("#searchextrashow :checkbox").prop("checked", $("#checkall_searchfields").prop("checked") );
3996:       });
3997:     });
3998:             // ]]> -->
3999:             </script>
4000:             <?php echo $prevtext; ?>
4001:             <div>
4002:                 <span class="tagSuggestContainer">
4003:                     <input type="text" name="words" value="" id="search_input" size="10" />
4004:                 </span>
4005:                 <?php if (count($fields) > 1 || $searchwords) { ?>
4006:                     <a href="javascript:toggle('searchextrashow');" ><img src="<?php echo $iconsource; ?>" title="<?php echo gettext('search options'); ?>" alt="<?php echo gettext('fields'); ?>" id="searchfields_icon" /></a>
4007:                 <?php } ?>
4008:                 <input type="<?php echo $type; ?>" <?php echo $button; ?> class="button buttons" id="search_submit" <?php echo $buttonSource; ?> data-role="none" />
4009:                 <?php
4010:                 if (is_array($object_list)) {
4011:                     foreach ($object_list as $key => $list) {
4012:                         ?>
4013:                         <input type="hidden" name="in<?php echo $key ?>" value="<?php
4014:                         if (is_array($list))
4015:                             echo html_encode(implode(',', $list));
4016:                         else
4017:                             echo html_encode($list);
4018:                         ?>" />
4019:                                      <?php
4020:                                  }
4021:                              }
4022:                              ?>
4023:                 <br />
4024:                 <?php
4025:                 if (count($fields) > 1 || $searchwords) {
4026:                     $fields = array_flip($fields);
4027:                     natcasesort($fields);
4028:                     $fields = array_flip($fields);
4029:                     if (is_null($query_fields)) {
4030:                         $query_fields = $engine->parseQueryFields();
4031:                     } else {
4032:                         if (!is_array($query_fields)) {
4033:                             $query_fields = $engine->numericFields($query_fields);
4034:                         }
4035:                     }
4036:                     if (count($query_fields) == 0) {
4037:                         $query_fields = $engine->allowedSearchFields();
4038:                     }
4039:                     ?>
4040:                     <div style="display:none;" id="searchextrashow">
4041:                         <?php
4042:                         if ($searchwords) {
4043:                             ?>
4044:                             <label>
4045:                                 <input type="radio" name="search_within" id="search_within-1" value="1"<?php if ($within) echo ' checked="checked"'; ?> onclick="search_(1);" />
4046:                                 <?php echo gettext('Within'); ?>
4047:                             </label>
4048:                             <label>
4049:                                 <input type="radio" name="search_within" id="search_within-0" value="1"<?php if (!$within) echo ' checked="checked"'; ?> onclick="search_(0);" />
4050:                                 <?php echo gettext('New'); ?>
4051:                             </label>
4052:                             <?php
4053:                         }
4054:                         if (count($fields) > 1) {
4055:                             ?>
4056:                             <ul>
4057:         <li><label><input type="checkbox" name="checkall_searchfields" id="checkall_searchfields" checked="checked">* <?php echo gettext('Check/uncheck all'); ?> *</label></li>
4058:                                 <?php
4059:                                 foreach ($fields as $display => $key) {
4060:                                     echo '<li><label><input id="SEARCH_' . $key . '" name="SEARCH_' . $key . '" type="checkbox"';
4061:                                     if (in_array($key, $query_fields)) {
4062:                                         echo ' checked="checked" ';
4063:                                     }
4064:                                     echo ' value="' . $key . '"  /> ' . $display . "</label></li>" . "\n";
4065:                                 }
4066:                                 ?>
4067:                             </ul>
4068:                             <?php
4069:                         }
4070:                         ?>
4071:                     </div>
4072:                     <?php
4073:                 }
4074:                 ?>
4075:             </div>
4076:         </form>
4077:     </div><!-- end of search form -->
4078:     <?php
4079: }
4080: 
4081: /**
4082:  * Returns the a sanitized version of the search string
4083:  *
4084:  * @return string
4085:  * @since 1.1
4086:  */
4087: function getSearchWords() {
4088:     global $_zp_current_search;
4089:     if (!in_context(ZP_SEARCH))
4090:         return '';
4091:     return stripcslashes($_zp_current_search->codifySearchString());
4092: }
4093: 
4094: /**
4095:  * Returns the date of the search
4096:  *
4097:  * @param string $format formatting of the date, default 'F Y'
4098:  * @return string
4099:  * @since 1.1
4100:  */
4101: function getSearchDate($format = '%B %Y') {
4102:     if (in_context(ZP_SEARCH)) {
4103:         global $_zp_current_search;
4104:         $date = $_zp_current_search->getSearchDate();
4105:         if (empty($date)) {
4106:             return "";
4107:         }
4108:         if ($date == '0000-00') {
4109:             return gettext("no date");
4110:         };
4111:         $dt = strtotime($date . "-01");
4112:         return zpFormattedDate($format, $dt);
4113:     }
4114:     return false;
4115: }
4116: 
4117: /**
4118:  * controls the thumbnail layout of themes.
4119:  *
4120:  * Uses the theme options:
4121:  *  albums_per_row
4122:  *  albums_per_page
4123:  *  images_per_row
4124:  *  images_per_page
4125:  *
4126:  * Computes a normalized images/albums per page and computes the number of
4127:  * images that will fit on the "transitional" page between album thumbs and
4128:  * image thumbs. This function is "internal" and is called from the root
4129:  * index.php script before the theme script is loaded.
4130:  */
4131: function setThemeColumns() {
4132:     global $_zp_current_album, $_firstPageImages, $_oneImagePage;
4133:     $_firstPageImages = false;
4134:     if (($albumColumns = getOption('albums_per_row')) <= 1)
4135:         $albumColumns = false;
4136:     if (($imageColumns = getOption('images_per_row')) <= 1)
4137:         $imageColumns = false;
4138:     $albcount = max(1, getOption('albums_per_page'));
4139:     if (($albumColumns) && (($albcount % $albumColumns) != 0)) {
4140:         setOption('albums_per_page', $albcount = ((floor($albcount / $albumColumns) + 1) * $albumColumns), false);
4141:     }
4142:     $imgcount = max(1, getOption('images_per_page'));
4143:     if (($imageColumns) && (($imgcount % $imageColumns) != 0)) {
4144:         setOption('images_per_page', $imgcount = ((floor($imgcount / $imageColumns) + 1) * $imageColumns), false);
4145:     }
4146:     if ((getOption('thumb_transition') && !$_oneImagePage) && in_context(ZP_ALBUM | ZP_SEARCH) && $albumColumns && $imageColumns) {
4147:         $count = getNumAlbums();
4148:         if ($count == 0) {
4149:             $_firstPageImages = 0;
4150:         }
4151:         $rowssused = ceil(($count % $albcount) / $albumColumns); /* number of album rows unused */
4152:         $leftover = floor(max(1, getOption('images_per_page')) / $imageColumns) - $rowssused;
4153:         $_firstPageImages = max(0, $leftover * $imageColumns); /* number of images that fill the leftover rows */
4154:         if ($_firstPageImages == $imgcount) {
4155:             $_firstPageImages = 0;
4156:         }
4157:     }
4158: }
4159: 
4160: //************************************************************************************************
4161: // album password handling
4162: //************************************************************************************************
4163: 
4164: /**
4165:  * returns the auth type of a guest login
4166:  *
4167:  * @param string $hint
4168:  * @param string $show
4169:  * @return string
4170:  */
4171: function checkForGuest(&$hint = NULL, &$show = NULL) {
4172:     global $_zp_gallery, $_zp_gallery_page, $_zp_current_zenpage_page, $_zp_current_category, $_zp_current_zenpage_news;
4173:     $authType = zp_apply_filter('checkForGuest', NULL);
4174:     if (!is_null($authType))
4175:         return $authType;
4176:     if (in_context(ZP_SEARCH)) { // search page
4177:         $hash = getOption('search_password');
4178:         if (getOption('search_user') != '')
4179:             $show = true;
4180:         $hint = get_language_string(getOption('search_hint'));
4181:         $authType = 'zp_search_auth';
4182:         if (empty($hash)) {
4183:             $hash = $_zp_gallery->getPassword();
4184:             if ($_zp_gallery->getUser() != '')
4185:                 $show = true;
4186:             $hint = $_zp_gallery->getPasswordHint();
4187:             $authType = 'zp_gallery_auth';
4188:         }
4189:         if (!empty($hash) && zp_getCookie($authType) == $hash) {
4190:             return $authType;
4191:         }
4192:     } else if (!is_null($_zp_current_zenpage_news)) {
4193:         $authType = $_zp_current_zenpage_news->checkAccess($hint, $show);
4194:         return $authType;
4195:     } else if (isset($_GET['album'])) { // album page
4196:         list($album, $image) = rewrite_get_album_image('album', 'image');
4197:         if ($authType = checkAlbumPassword($album, $hint)) {
4198:             return $authType;
4199:         } else {
4200:             $alb = newAlbum($album);
4201:             if ($alb->getUser() != '')
4202:                 $show = true;
4203:             return false;
4204:         }
4205:     } else { // other page
4206:         $hash = $_zp_gallery->getPassword();
4207:         if ($_zp_gallery->getUser() != '')
4208:             $show = true;
4209:         $hint = $_zp_gallery->getPasswordHint();
4210:         if (!empty($hash) && zp_getCookie('zp_gallery_auth') == $hash) {
4211:             return 'zp_gallery_auth';
4212:         }
4213:     }
4214:     if (empty($hash))
4215:         return 'zp_public_access';
4216:     return false;
4217: }
4218: 
4219: /**
4220:  * Checks to see if a password is needed
4221:  *
4222:  * Returns true if access is allowed
4223:  *
4224:  * The password protection is hereditary. This normally only impacts direct url access to an object since if
4225:  * you are going down the tree you will be stopped at the first place a password is required.
4226:  *
4227:  *
4228:  * @param string $hint the password hint
4229:  * @param bool $show whether there is a user associated with the password.
4230:  * @return bool
4231:  * @since 1.1.3
4232:  */
4233: function checkAccess(&$hint = NULL, &$show = NULL) {
4234:     global $_zp_current_album, $_zp_current_search, $_zp_gallery, $_zp_gallery_page,
4235:     $_zp_current_zenpage_page, $_zp_current_zenpage_news;
4236:     if (GALLERY_SECURITY != 'public') // only registered users allowed
4237:         $show = true; //    therefore they will need to supply their user id is something fails below
4238: 
4239:     if ($_zp_gallery->isUnprotectedPage(stripSuffix($_zp_gallery_page)))
4240:         return true;
4241:     if (zp_loggedin()) {
4242:         $fail = zp_apply_filter('isMyItemToView', NULL);
4243:         if (!is_null($fail)) { //   filter had something to say about access, honor it
4244:             return $fail;
4245:         }
4246:         switch ($_zp_gallery_page) {
4247:             case 'album.php':
4248:             case 'image.php':
4249:                 if ($_zp_current_album->isMyItem(LIST_RIGHTS)) {
4250:                     return true;
4251:                 }
4252:                 break;
4253:             case 'search.php':
4254:                 if (zp_loggedin(VIEW_SEARCH_RIGHTS)) {
4255:                     return true;
4256:                 }
4257:                 break;
4258:             default:
4259:                 if (zp_loggedin(VIEW_GALLERY_RIGHTS)) {
4260:                     return true;
4261:                 }
4262:                 break;
4263:         }
4264:     }
4265:     if (GALLERY_SECURITY == 'public' && ($access = checkForGuest($hint, $show))) {
4266:         return $access; // public page or a guest is logged in
4267:     }
4268:     return false;
4269: }
4270: 
4271: /**
4272:  * Returns a redirection link for the password form
4273:  *
4274:  * @return string
4275:  */
4276: function getPageRedirect() {
4277:   global $_zp_login_error, $_zp_password_form_printed, $_zp_current_search, $_zp_gallery_page,
4278:   $_zp_current_album, $_zp_current_image, $_zp_current_zenpage_news;
4279:   switch ($_zp_gallery_page) {
4280:     case 'index.php':
4281:       $action = '/index.php';
4282:       break;
4283:     case 'album.php':
4284:       $action = '/index.php?userlog=1&album=' . pathurlencode($_zp_current_album->name);
4285:       break;
4286:     case 'image.php':
4287:       $action = '/index.php?userlog=1&album=' . pathurlencode($_zp_current_album->name) . '&image=' . urlencode($_zp_current_image->filename);
4288:       break;
4289:     case 'pages.php':
4290:       $action = '/index.php?userlog=1&p=pages&title=' . urlencode(getPageTitlelink());
4291:       break;
4292:     case 'news.php':
4293:       $action = '/index.php?userlog=1&p=news';
4294:       if (!is_null($_zp_current_zenpage_news)) {
4295:         $action .= '&title=' . urlencode($_zp_current_zenpage_news->getTitlelink());
4296:       }
4297:       break;
4298:     case 'password.php':
4299:       $action = str_replace(SEO_WEBPATH, '', getRequestURI());
4300:       if ($action == '/' . _PAGE_ . '/password' || $action == '/index.php?p=password') {
4301:         $action = '/index.php';
4302:       }
4303:       break;
4304:     default:
4305:       if (in_context(ZP_SEARCH)) {
4306:         $action = '/index.php?userlog=1&p=search' . $_zp_current_search->getSearchParams();
4307:       } else {
4308:         $action = '/index.php?userlog=1&p=' . substr($_zp_gallery_page, 0, -4);
4309:       }
4310:   }
4311:   return SEO_WEBPATH . $action;
4312: }
4313: 
4314: /**
4315:  * Prints the album password form
4316:  *
4317:  * @param string $hint hint to the password
4318:  * @param bool $showProtected set false to supress the password protected message
4319:  * @param bool $showuser set true to force the user name filed to be present
4320:  * @param string $redirect optional URL to send the user to after successful login
4321:  *
4322:  * @since 1.1.3
4323:  */
4324: function printPasswordForm($_password_hint, $_password_showuser = NULL, $_password_showProtected = true, $_password_redirect = NULL) {
4325:     global $_zp_login_error, $_zp_password_form_printed, $_zp_current_search, $_zp_gallery, $_zp_gallery_page,
4326:     $_zp_current_album, $_zp_current_image, $theme, $_zp_current_zenpage_page, $_zp_authority;
4327:     if ($_zp_password_form_printed)
4328:         return;
4329:     $_zp_password_form_printed = true;
4330: 
4331:     if (is_null($_password_redirect))
4332:         $_password_redirect = getPageRedirect();
4333: 
4334:     if (is_null($_password_showuser))
4335:         $_password_showuser = $_zp_gallery->getUserLogonField();
4336:     ?>
4337:     <div id="passwordform">
4338:         <?php
4339:         if ($_password_showProtected && !$_zp_login_error) {
4340:             ?>
4341:             <p>
4342:                 <?php echo gettext("The page you are trying to view is password protected."); ?>
4343:             </p>
4344:             <?php
4345:         }
4346:         if ($loginlink = zp_apply_filter('login_link', NULL)) {
4347:             $logintext = gettext('login');
4348:             ?>
4349:             <a href="<?php echo $loginlink; ?>" title="<?php echo $logintext; ?>"><?php echo $logintext; ?></a>
4350:             <?php
4351:         } else {
4352:             $_zp_authority->printLoginForm($_password_redirect, false, $_password_showuser, false, $_password_hint);
4353:         }
4354:         ?>
4355:     </div>
4356:     <?php
4357: }
4358: 
4359: /**
4360:  * prints the zenphoto logo and link
4361:  *
4362:  */
4363: function printZenphotoLink() {
4364:     echo gettext("Powered by <a href=\"http://www.zenphoto.org\" title=\"A simpler web album\"><span id=\"zen-part\">zen</span><span id=\"photo-part\">PHOTO</span></a>");
4365: }
4366: 
4367: /**
4368:  * Expose some informations in a HTML comment
4369:  *
4370:  * @param string $obj the path to the page being loaded
4371:  * @param array $plugins list of activated plugins
4372:  * @param string $theme The theme being used
4373:  */
4374: function exposeZenPhotoInformations($obj = '', $plugins = '', $theme = '') {
4375:     global $_zp_filters;
4376:     $a = basename($obj);
4377:     if ($a != 'full-image.php') {
4378:         echo "\n<!-- zenphoto version " . ZENPHOTO_VERSION;
4379:         if (TEST_RELEASE) {
4380:             echo " [" . ZENPHOTO_FULL_RELEASE . "]";
4381:             echo " THEME: " . $theme . " (" . $a . ")";
4382:             $graphics = zp_graphicsLibInfo();
4383:             $graphics = sanitize(str_replace('<br />', ', ', $graphics['Library_desc']), 3);
4384:             echo " GRAPHICS LIB: " . $graphics . " { memory: " . INI_GET('memory_limit') . " }";
4385:             echo ' PLUGINS: ';
4386:             if (count($plugins) > 0) {
4387:                 sort($plugins);
4388:                 foreach ($plugins as $plugin) {
4389:                     echo $plugin . ' ';
4390:                 }
4391:             } else {
4392:                 echo 'none ';
4393:             }
4394:         }
4395:         echo " -->";
4396:     }
4397: }
4398: 
4399: /**
4400:  * Gets the content of a codeblock for an image, album or Zenpage newsarticle or page.
4401:  *
4402:  * The priority for codeblocks will be (based on context)
4403:  *  1: articles
4404:  *  2: pages
4405:  *  3: images
4406:  *  4: albums
4407:  *  5: gallery.
4408:  *
4409:  * This means, for instance, if we are in ZP_ZENPAGE_NEWS_ARTICLE context we will use the news article
4410:  * codeblock even if others are available.
4411:  *
4412:  * Note: Echoing this array's content does not execute it. Also no special chars will be escaped.
4413:  * Use printCodeblock() if you need to execute script code.
4414:  *
4415:  * @param int $number The codeblock you want to get
4416:  * @param mixed $what optonal object for which you want the codeblock
4417:  *
4418:  * @return string
4419:  */
4420: function getCodeblock($number = 1, $object = NULL) {
4421:     global $_zp_current_album, $_zp_current_image, $_zp_current_zenpage_news, $_zp_current_zenpage_page, $_zp_gallery, $_zp_gallery_page;
4422:     if (!$number) {
4423:         setOptionDefault('codeblock_first_tab', 0);
4424:     }
4425:     if (!is_object($object)) {
4426:         if ($_zp_gallery_page == 'index.php') {
4427:             $object = $_zp_gallery;
4428:         }
4429:         if (in_context(ZP_ALBUM)) {
4430:             $object = $_zp_current_album;
4431:         }
4432:         if (in_context(ZP_IMAGE)) {
4433:             $object = $_zp_current_image;
4434:         }
4435:         if (in_context(ZP_ZENPAGE_PAGE)) {
4436:             if ($_zp_current_zenpage_page->checkAccess()) {
4437:                 $object = $_zp_current_zenpage_page;
4438:             }
4439:         }
4440:         if (in_context(ZP_ZENPAGE_NEWS_ARTICLE)) {
4441:             if ($_zp_current_zenpage_news->checkAccess()) {
4442:                 $object = $_zp_current_zenpage_news;
4443:             }
4444:         }
4445:     }
4446:     if (!is_object($object)) {
4447:         return NULL;
4448:     }
4449:     $codeblock = getSerializedArray($object->getcodeblock());
4450:     $codeblock = zp_apply_filter('codeblock', @$codeblock[$number], $object, $number);
4451:     if ($codeblock) {
4452:         $codeblock = applyMacros($codeblock);
4453:     }
4454:     return $codeblock;
4455: }
4456: 
4457: /**
4458:  * Prints the content of a codeblock for an image, album or Zenpage newsarticle or page.
4459:  *
4460:  * @param int $number The codeblock you want to get
4461:  * @param mixed $what optonal object for which you want the codeblock
4462:  *
4463:  * @return string
4464:  */
4465: function printCodeblock($number = 1, $what = NULL) {
4466:     $codeblock = getCodeblock($number, $what);
4467:     if ($codeblock) {
4468:         $context = get_context();
4469:         eval('?>' . $codeblock);
4470:         set_context($context);
4471:     }
4472: }
4473: 
4474: /**
4475:  * Checks for URL page out-of-bounds for "standard" themes
4476:  * Note: This function assumes that an "index" page will display albums
4477:  * and the pagination be determined by them. Any other "index" page strategy needs to be
4478:  * handled by the theme itself.
4479:  *
4480:  * @param boolean $request
4481:  * @param string $gallery_page
4482:  * @param int $page
4483:  * @return boolean will be true if all is well, false if a 404 error should occur
4484:  */
4485: function checkPageValidity($request, $gallery_page, $page) {
4486:     global $_zp_gallery, $_firstPageImages, $_oneImagePage, $_zp_zenpage, $_zp_current_category;
4487:     $count = NULL;
4488:     switch ($gallery_page) {
4489:         case 'album.php':
4490:         case 'search.php':
4491:             $albums_per_page = max(1, getOption('albums_per_page'));
4492:             $pageCount = (int) ceil(getNumAlbums() / $albums_per_page);
4493:             $imageCount = getNumImages();
4494:             if ($_oneImagePage) {
4495:                 if ($_oneImagePage === true) {
4496:                     $imageCount = min(1, $imageCount);
4497:                 } else {
4498:                     $imageCount = 0;
4499:                 }
4500:             }
4501:             $images_per_page = max(1, getOption('images_per_page'));
4502:             $count = ($pageCount + (int) ceil(($imageCount - $_firstPageImages) / $images_per_page));
4503:             break;
4504:         case 'index.php':
4505:             if (galleryAlbumsPerPage() != 0) {
4506:                 $count = (int) ceil($_zp_gallery->getNumAlbums() / galleryAlbumsPerPage());
4507:             }
4508:             break;
4509:         case 'news.php':
4510:             if (in_context(ZP_ZENPAGE_NEWS_CATEGORY)) {
4511:                 $count = count($_zp_current_category->getArticles());
4512:             } else {
4513:                 $count = count($_zp_zenpage->getArticles());
4514:             }
4515:             $count = (int) ceil($count / ZP_ARTICLES_PER_PAGE);
4516:             break;
4517:         default:
4518:             $count = zp_apply_filter('checkPageValidity', NULL, $gallery_page, $page);
4519:             break;
4520:     }
4521:     if ($page > $count) {
4522:         $request = false; //    page is out of range
4523:     }
4524: 
4525:     return $request;
4526: }
4527: 
4528: function print404status($album, $image, $obj) {
4529:     global $_zp_page;
4530:     echo "\n<strong>" . gettext("Zenphoto Error:</strong> the requested object was not found.");
4531:     if (isset($album)) {
4532:         echo '<br />' . sprintf(gettext('Album: %s'), html_encode($album));
4533: 
4534:         if (isset($image)) {
4535:             echo '<br />' . sprintf(gettext('Image: %s'), html_encode($image));
4536:         }
4537:     } else {
4538:         echo '<br />' . sprintf(gettext('Page: %s'), html_encode(substr(basename($obj), 0, -4)));
4539:     }
4540:     if (isset($_zp_page) && $_zp_page > 1) {
4541:         echo '/' . $_zp_page;
4542:     }
4543: }
4544: 
4545: require_once(SERVERPATH . '/' . ZENFOLDER . '/template-filters.php');
4546: ?>
4547: 
Zenphoto doc API documentation generated by ApiGen