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:  * Zenphoto USER credentials handlers
   4:  *
   5:  * An alternate authorization script may be provided to override this script. To do so, make a script that
   6:  * implements the classes declared below. Place the new script inthe <ZENFOLDER>/plugins/alt/ folder. Zenphoto
   7:  * will then will be automatically loaded the alternate script in place of this one.
   8:  *
   9:  * Replacement libraries must implement two classes:
  10:  *      "Authority" class: Provides the methods used for user authorization and management
  11:  *          store an instantiation of this class in $_zp_authority.
  12:  *
  13:  *      Administrator: supports the basic Zenphoto needs for object manipulation of administrators.
  14:  * (You can include this script and extend the classes if that suits your needs.)
  15:  *
  16:  * The global $_zp_current_admin_obj represents the current admin with.
  17:  * The library must instantiate its authority class and store the object in the global $_zp_authority
  18:  * (Note, this library does instantiate the object as described. This is so its classes can
  19:  * be used as parent classes for lib-auth implementations. If auth_zp.php decides to use this
  20:  * library it will instantiate the class and store it into $_zp_authority.
  21:  *
  22:  * The following elements need to be present in any alternate implementation in the
  23:  * array returned by getAdministrators().
  24:  *
  25:  *      In particular, there should be array elements for:
  26:  *              'id' (unique), 'user' (unique), 'pass', 'name', 'email', 'rights', 'valid',
  27:  *              'group', and 'custom_data'
  28:  *
  29:  *      So long as all these indices are populated it should not matter when and where
  30:  *      the data is stored.
  31:  *
  32:  *      Administrator class methods are required for these elements as well.
  33:  *
  34:  *      The getRights() method must define at least the rights defined by the method in
  35:  *      this library.
  36:  *
  37:  *      The checkAuthorization() method should promote the "most privileged" Admin to
  38:  *      ADMIN_RIGHTS to insure that there is some user capable of adding users or
  39:  *      modifying user rights.
  40:  *
  41:  * @package classes
  42:  */
  43: // force UTF-8 Ø
  44: require_once(dirname(__FILE__) . '/classes.php');
  45: 
  46: class Zenphoto_Authority {
  47: 
  48:     var $admin_users = NULL;
  49:     var $admin_groups = NULL;
  50:     var $admin_other = NULL;
  51:     var $admin_all = NULL;
  52:     var $rightsset = NULL;
  53:     protected $master_user = NULL;
  54:     static $preferred_version = 4;
  55:     static $supports_version = 4;
  56:     static $hashList = array('pbkdf2' => 3, 'pbkdf2*' => 2, 'sha1' => 1, 'md5' => 0);
  57: 
  58:     /**
  59:      * class instantiation function
  60:      *
  61:      * @return lib_auth_options
  62:      */
  63:     function __construct() {
  64:         $this->admin_all = $this->admin_groups = $this->admin_users = $this->admin_other = array();
  65:         $sql = 'SELECT * FROM ' . prefix('administrators') . ' ORDER BY `rights` DESC, `id`';
  66:         $admins = query($sql, false);
  67:         if ($admins) {
  68:             while ($user = db_fetch_assoc($admins)) {
  69:                 $this->admin_all[$user['id']] = $user;
  70:                 switch ($user['valid']) {
  71:                     case 1:
  72:                         $this->admin_users[$user['id']] = $user;
  73:                         if (empty($this->master_user))
  74:                             $this->master_user = $user['user'];
  75:                         break;
  76:                     case 0:
  77:                         $this->admin_groups[$user['id']] = $user;
  78:                         break;
  79:                     default:
  80:                         $this->admin_other[$user['id']] = $user;
  81:                         break;
  82:                 }
  83:             }
  84:             db_free_result($admins);
  85:         }
  86:     }
  87: 
  88:     function getMasterUser() {
  89:         return new Zenphoto_Administrator($this->master_user, 1);
  90:     }
  91: 
  92:     function isMasterUser($user) {
  93:         return $user == $this->master_user;
  94:     }
  95: 
  96:     /**
  97:      * Declares options used by lib-auth
  98:      *
  99:      * @return array
 100:      */
 101:     function getOptionsSupported() {
 102:         $encodings = self::$hashList;
 103:         unset($encodings['pbkdf2*']); // don't use this one any more
 104:         if (!function_exists('hash')) {
 105:             unset($encodings['pbkdf2']);
 106:         }
 107:         return array(gettext('Primary album edit')               => array('key'  => 'user_album_edit_default', 'type' => OPTION_TYPE_CHECKBOX,
 108:                                         'desc' => gettext('Check if you want <em>edit rights</em> automatically assigned when a user <em>primary album</em> is created.')),
 109:                         gettext('Minimum password strength') => array('key'  => 'password_strength', 'type' => OPTION_TYPE_CUSTOM,
 110:                                         'desc' => sprintf(gettext('Users must provide passwords a strength of at least %s. The repeat password field will be disabled until this floor is met.'), '<span id="password_strength_display">' . getOption('password_strength') . '</span>')),
 111:                         gettext('Password hash algorithm')   => array('key'              => 'strong_hash', 'type'            => OPTION_TYPE_SELECTOR,
 112:                                         'selections' => $encodings,
 113:                                         'desc'           => sprintf(gettext('The hashing algorithm used by Zenphoto. In order of robustness the choices are %s'), '<code>' . implode('</code> > <code>', array_flip($encodings)) . '</code>'))
 114:         );
 115:     }
 116: 
 117:     /**
 118:      * Dummy for object inheritance purposes
 119:      */
 120:     function handleOption($option, $currentValue) {
 121:         global $_zp_current_admin_obj;
 122:         switch ($option) {
 123:             case 'password_strength':
 124:                 ?>
 125:                 <input type="hidden" size="3" id="password_strength" name="password_strength" value="<?php echo getOption('password_strength'); ?>" />
 126:                 <script type="text/javascript">
 127:                     // <!-- <![CDATA[
 128:                     function sliderColor(strength) {
 129:                         var url = 'url(<?php echo WEBPATH . '/' . ZENFOLDER; ?>/images/strengths/strength' + strength + '.png)';
 130:                         $('#slider-password_strength').css('background-image', url);
 131:                     }
 132:                     $(function() {
 133:                         $("#slider-password_strength").slider({
 134:                 <?php $v = getOption('password_strength'); ?>
 135:                             startValue: <?php echo $v; ?>,
 136:                             value: <?php echo $v; ?>,
 137:                             min: 1,
 138:                             max: 30,
 139:                             slide: function(event, ui) {
 140:                                 $("#password_strength").val(ui.value);
 141:                                 $('#password_strength_display').html(ui.value);
 142:                                 sliderColor(ui.value);
 143:                             }
 144:                         });
 145:                         var strength = $("#slider-password_strength").slider("value");
 146:                         $("#password_strength").val(strength);
 147:                         $('#password_strength_display').html(strength);
 148:                         sliderColor(strength);
 149:                     });
 150:                     // ]]> -->
 151:                 </script>
 152:                 <div id="slider-password_strength"></div>
 153:                 <?php
 154:                 break;
 155:         }
 156:     }
 157: 
 158:     static function getVersion() {
 159:         $v = getOption('libauth_version');
 160:         if (empty($v)) {
 161:             return self::$preferred_version;
 162:         } else {
 163:             return $v;
 164:         }
 165:     }
 166: 
 167:     /**
 168:      * Returns the hash of the zenphoto password
 169:      *
 170:      * @param string $user
 171:      * @param string $pass
 172:      * @return string
 173:      */
 174:     static function passwordHash($user, $pass, $hash_type = NULL) {
 175:         if (is_null($hash_type)) {
 176:             $hash_type = getOption('strong_hash');
 177:         }
 178:         switch ($hash_type) {
 179:             case 1:
 180:                 $hash = sha1($user . $pass . HASH_SEED);
 181:                 break;
 182:             case 2:
 183:                 //  deprecated beause of possible "+" in the text
 184:                 $hash = base64_encode(self::pbkdf2($pass, $user . HASH_SEED));
 185:                 break;
 186:             case 3:
 187:                 $hash = str_replace('+', '-', base64_encode(self::pbkdf2($pass, $user . HASH_SEED)));
 188:                 break;
 189:             default:
 190:                 $hash = md5($user . $pass . HASH_SEED);
 191:                 break;
 192:         }
 193:         if (DEBUG_LOGIN) {
 194:             debugLog("passwordHash($user, $pass, $hash_type)[ " . HASH_SEED . " ]:$hash");
 195:         }
 196:         return $hash;
 197:     }
 198: 
 199:     /**
 200:      * Returns an array of admin users, indexed by the userid and ordered by "privileges"
 201:      *
 202:      * The array contains the id, hashed password, user's name, email, and admin privileges
 203:      *
 204:      * @param string $what: 'all' for everything, 'users' for just users 'groups' for groups and templates
 205:      * @return array
 206:      */
 207:     function getAdministrators($what = 'users') {
 208:         switch ($what) {
 209:             case 'users':
 210:                 return $this->admin_users;
 211:             case 'groups':
 212:                 return $this->admin_groups;
 213:             case 'allusers':
 214:                 return array_merge($this->admin_users, $this->admin_other);
 215:             default:
 216:                 return $this->admin_all;
 217:         }
 218:     }
 219: 
 220:     /**
 221:      * Returns an admin object from the $pat:$criteria
 222:      * @param array $criteria [ match => criteria ]
 223:      * @return Zenphoto_Administrator
 224:      */
 225:     static function getAnAdmin($criteria) {
 226:         $selector = array();
 227:         foreach ($criteria as $match => $value) {
 228:             if (is_numeric($value)) {
 229:                 $selector[] = $match . $value;
 230:             } else {
 231:                 $selector[] = $match . db_quote($value);
 232:             }
 233:         }
 234:         $sql = 'SELECT * FROM ' . prefix('administrators') . ' WHERE ' . implode(' AND ', $selector) . ' LIMIT 1';
 235:         $admin = query_single_row($sql, false);
 236:         if ($admin) {
 237:             return self::newAdministrator($admin['user'], $admin['valid']);
 238:         } else {
 239:             return NULL;
 240:         }
 241:     }
 242: 
 243:     /**
 244:      * Retuns the administration rights of a saved authorization code
 245:      * Will promote an admin to ADMIN_RIGHTS if he is the most privileged admin
 246:      *
 247:      * @param string $authCode the hash code to check
 248:      * @param int $id whom we think this is
 249:      *
 250:      * @return bit
 251:      */
 252:     function checkAuthorization($authCode, $id) {
 253:         global $_zp_current_admin_obj;
 254:         if (DEBUG_LOGIN) {
 255:             debugLogBacktrace("checkAuthorization($authCode, $id)");
 256:         }
 257: 
 258: 
 259:         $admins = $this->getAdministrators();
 260:         if (count($admins) == 0) {
 261:             if (DEBUG_LOGIN) {
 262:                 debugLog("checkAuthorization: no admins");
 263:             }
 264:             $_zp_current_admin_obj = new Zenphoto_Administrator('', 1);
 265:             $_zp_current_admin_obj->set('id', 0);
 266:             $_zp_current_admin_obj->reset = true;
 267:             return ADMIN_RIGHTS;
 268:         }
 269:         if (is_object($_zp_current_admin_obj) && $_zp_current_admin_obj->reset) {
 270:             if (DEBUG_LOGIN) {
 271:                 debugLog("checkAuthorization: reset request");
 272:             }
 273:             return $_zp_current_admin_obj->getRights();
 274:         }
 275: 
 276: 
 277:         $_zp_current_admin_obj = NULL;
 278:         if (empty($authCode))
 279:             return 0; //  so we don't "match" with an empty password
 280:         if (DEBUG_LOGIN) {
 281:             debugLogVar("checkAuthorization: admins", $admins);
 282:         }
 283:         $rights = 0;
 284:         $criteria = array('`pass`=' => $authCode, '`valid`=' => 1);
 285:         if (!empty($id)) {
 286:             $criteria['`id`='] = $id;
 287:         }
 288:         $user = self::getAnAdmin($criteria);
 289:         if (is_object($user)) {
 290:             $_zp_current_admin_obj = $user;
 291:             $rights = $user->getRights();
 292:             if (DEBUG_LOGIN) {
 293:                 debugLog(sprintf('checkAuthorization: from %1$s->%2$X', $authCode, $rights));
 294:             }
 295:             return $rights;
 296:         }
 297:         $_zp_current_admin_obj = NULL;
 298:         if (DEBUG_LOGIN) {
 299:             debugLog("checkAuthorization: no match");
 300:         }
 301:         return 0; // no rights
 302:     }
 303: 
 304:     /**
 305:      * Checks a logon user/password against admins
 306:      *
 307:      * Returns the user object if there is a match
 308:      *
 309:      * @param string $user
 310:      * @param string $pass
 311:      * @return object
 312:      */
 313:     function checkLogon($user, $pass) {
 314:         $userobj = self::getAnAdmin(array('`user`=' => $user, '`valid`=' => 1));
 315:         if ($userobj) {
 316:             $hash = self::passwordHash($user, $pass, $userobj->get('passhash'));
 317:             if ($hash != $userobj->getPass()) {
 318:                 //  maybe not yet updated passhash field
 319:                 foreach (self::$hashList as $hashv) {
 320:                     $hash = self::passwordHash($user, $pass, $hashv);
 321:                     if ($hash == $userobj->getPass()) {
 322:                         break;
 323:                     } else {
 324:                         $hash = -1;
 325:                     }
 326:                 }
 327:                 if ($hash === -1) {
 328:                     $userobj = NULL;
 329:                 }
 330:             }
 331:         } else {
 332:             $hash = -1;
 333:         }
 334: 
 335:         if (DEBUG_LOGIN) {
 336:             if ($userobj) {
 337:                 $rights = sprintf('%X', $userobj->getRights());
 338:             } else {
 339:                 $rights = false;
 340:             }
 341:             debugLog(sprintf('checkLogon(%1$s, %2$s)->%3$s', $user, $hash, $rights));
 342:         }
 343:         return $userobj;
 344:     }
 345: 
 346:     /**
 347:      * Returns the email addresses of the Admin with ADMIN_USERS rights
 348:      *
 349:      * @param bit $rights what kind of admins to retrieve
 350:      * @return array
 351:      */
 352:     function getAdminEmail($rights = NULL) {
 353:         if (is_null($rights)) {
 354:             $rights = ADMIN_RIGHTS;
 355:         }
 356:         $emails = array();
 357:         $admins = $this->getAdministrators();
 358:         foreach ($admins as $user) {
 359:             if (($user['rights'] & $rights) && is_valid_email_zp($user['email'])) {
 360:                 $name = $user['name'];
 361:                 if (empty($name)) {
 362:                     $name = $user['user'];
 363:                 }
 364:                 $emails[$name] = $user['email'];
 365:             }
 366:         }
 367:         return $emails;
 368:     }
 369: 
 370:     /**
 371:      * Migrates credentials
 372:      *
 373:      * @param int $oldversion
 374:      */
 375:     function migrateAuth($to) {
 376:         if ($to > self::$supports_version || $to < self::$preferred_version - 1) {
 377:             trigger_error(sprintf(gettext('Cannot migrate rights to version %1$s (Zenphoto_Authority supports only %2$s and %3$s.)'), $to, self::$supports_version, self::$preferred_version), E_USER_NOTICE);
 378:             return false;
 379:         }
 380:         $success = true;
 381:         $oldversion = self::getVersion();
 382:         setOption('libauth_version', $to);
 383:         $this->admin_users = array();
 384:         $sql = "SELECT * FROM " . prefix('administrators') . "ORDER BY `rights` DESC, `id`";
 385:         $admins = query($sql, false);
 386:         if ($admins) { // something to migrate
 387:             $oldrights = array();
 388:             foreach (self::getRights($oldversion) as $key => $right) {
 389:                 $oldrights[$key] = $right['value'];
 390:             }
 391:             $currentrights = self::getRights($to);
 392:             while ($user = db_fetch_assoc($admins)) {
 393:                 $update = false;
 394:                 $rights = $user['rights'];
 395:                 $newrights = $currentrights['NO_RIGHTS']['value'];
 396:                 foreach ($currentrights as $key => $right) {
 397:                     if ($right['display']) {
 398:                         if (array_key_exists($key, $oldrights) && $rights & $oldrights[$key]) {
 399:                             $newrights = $newrights | $right['value'];
 400:                         }
 401:                     }
 402:                 }
 403:                 if ($oldversion < 4) {
 404:                     $newrights = $newrights | $currentrights['USER_RIGHTS']['value'];
 405:                 }
 406:                 if ($to >= 3 && $oldversion < 3) {
 407:                     if ($rights & $oldrights['VIEW_ALL_RIGHTS']) {
 408:                         $updaterights = $currentrights['ALL_ALBUMS_RIGHTS']['value'] | $currentrights['ALL_PAGES_RIGHTS']['value'] |
 409:                                         $currentrights['ALL_NEWS_RIGHTS']['value'] | $currentrights['VIEW_SEARCH_RIGHTS']['value'] |
 410:                                         $currentrights['VIEW_GALLERY_RIGHTS']['value'] | $currentrights['VIEW_FULLIMAGE_RIGHTS']['value'];
 411:                         $newrights = $newrights | $updaterights;
 412:                     }
 413:                 }
 414:                 if ($oldversion >= 3 && $to < 3) {
 415:                     if ($oldrights['ALL_ALBUMS_RIGHTS'] || $oldrights['ALL_PAGES_RIGHTS'] || $oldrights['ALL_NEWS_RIGHTS']) {
 416:                         $newrights = $newrights | $currentrights['VIEW_ALL_RIGHTS']['value'];
 417:                     }
 418:                 }
 419:                 if ($oldversion == 1) { // need to migrate zenpage rights
 420:                     if ($rights & $oldrights['ZENPAGE_RIGHTS']) {
 421:                         $newrights = $newrights | $currentrights['ZENPAGE_PAGES_RIGHTS'] | $currentrights['ZENPAGE_NEWS_RIGHTS'] | $currentrights['FILES_RIGHTS'];
 422:                     }
 423:                 }
 424:                 if ($to >= 3) {
 425:                     if ($newrights & $currentrights['ADMIN_RIGHTS']['value']) {
 426:                         $newrights = $currentrights['ALL_RIGHTS']['value'];
 427:                     } else {
 428:                         if ($newrights & $currentrights['MANAGE_ALL_ALBUM_RIGHTS']['value']) {
 429:                             // these are lock-step linked!
 430:                             $newrights = $newrights | $currentrights['ALBUM_RIGHTS']['value'];
 431:                         }
 432:                         if ($newrights & $currentrights['MANAGE_ALL_NEWS_RIGHTS']['value']) {
 433:                             // these are lock-step linked!
 434:                             $newrights = $newrights | $currentrights['ZENPAGE_NEWS_RIGHTS']['value'];
 435:                         }
 436:                         if ($newrights & $currentrights['MANAGE_ALL_PAGES_RIGHTS']['value']) {
 437:                             // these are lock-step linked!
 438:                             $newrights = $newrights | $currentrights['ZENPAGE_PAGES_RIGHTS']['value'];
 439:                         }
 440:                     }
 441:                 }
 442: 
 443:                 $sql = 'UPDATE ' . prefix('administrators') . ' SET `rights`=' . $newrights . ' WHERE `id`=' . $user['id'];
 444:                 $success = $success && query($sql);
 445:             } // end loop
 446:             db_free_result($admins);
 447:         }
 448:         return $success;
 449:     }
 450: 
 451:     /**
 452:      * Updates a field in admin record(s)
 453:      *
 454:      * @param string $update name of the field
 455:      * @param mixed $value what to store
 456:      * @param array $constraints on the update [ field<op>,value ]
 457:      * @return mixed Query result
 458:      */
 459:     static function updateAdminField($update, $value, $constraints) {
 460:         $where = '';
 461:         foreach ($constraints as $field => $clause) {
 462:             if (!empty($where))
 463:                 $where .= ' AND ';
 464:             if (is_numeric($clause)) {
 465:                 $where .= $field . $clause;
 466:             } else {
 467:                 $where .= $field . db_quote($clause);
 468:             }
 469:         }
 470:         if (is_null($value)) {
 471:             $value = 'NULL';
 472:         } else {
 473:             $value = db_quote($value);
 474:         }
 475:         $sql = 'UPDATE ' . prefix('administrators') . ' SET `' . $update . '`=' . $value . ' WHERE ' . $where;
 476:         $result = query($sql);
 477:         return $result;
 478:     }
 479: 
 480:     /**
 481:      * Instantiates and returns administrator object
 482:      * @param $name
 483:      * @param $valid
 484:      * @return object
 485:      */
 486:     static function newAdministrator($name, $valid = 1) {
 487:         $user = new Zenphoto_Administrator($name, $valid);
 488:         return $user;
 489:     }
 490: 
 491:     /**
 492:      * Returns an array of the rights definitions for $version (default returns current version rights)
 493:      *
 494:      * @param $version
 495:      */
 496:     static function getRights($version = NULL) {
 497:         if (empty($version)) {
 498:             $v = self::getVersion();
 499:         } else {
 500:             $v = $version;
 501:         }
 502:         switch ($v) {
 503:             case 1:
 504:                 $rightsset = array('NO_RIGHTS'                               => array('value' => 2, 'name' => gettext('No rights'), 'set' => '', 'display' => false, 'hint' => ''),
 505:                                 'OVERVIEW_RIGHTS'                    => array('value' => 4, 'name' => gettext('Overview'), 'set' => '', 'display' => true, 'hint' => ''),
 506:                                 'VIEW_ALL_RIGHTS'                    => array('value' => 8, 'name' => gettext('View all'), 'set' => '', 'display' => true, 'hint' => ''),
 507:                                 'UPLOAD_RIGHTS'                      => array('value' => 16, 'name' => gettext('Upload'), 'set' => '', 'display' => true, 'hint' => ''),
 508:                                 'POST_COMMENT_RIGHTS'            => array('value' => 32, 'name' => gettext('Post comments'), 'set' => '', 'display' => true, 'hint' => ''),
 509:                                 'COMMENT_RIGHTS'                     => array('value' => 64, 'name' => gettext('Comments'), 'set' => '', 'display' => true, 'hint' => ''),
 510:                                 'ALBUM_RIGHTS'                       => array('value' => 256, 'name' => gettext('Album'), 'set' => '', 'display' => true, 'hint' => ''),
 511:                                 'MANAGE_ALL_ALBUM_RIGHTS'    => array('value' => 512, 'name' => gettext('Manage all albums'), 'set' => '', 'display' => true, 'hint' => ''),
 512:                                 'THEMES_RIGHTS'                      => array('value' => 1024, 'name' => gettext('Themes'), 'set' => '', 'display' => true, 'hint' => ''),
 513:                                 'ZENPAGE_RIGHTS'                     => array('value' => 2049, 'name' => gettext('Zenpage'), 'set' => '', 'display' => true, 'hint' => ''),
 514:                                 'TAGS_RIGHTS'                            => array('value' => 4096, 'name' => gettext('Tags'), 'set' => '', 'display' => true, 'hint' => ''),
 515:                                 'OPTIONS_RIGHTS'                     => array('value' => 8192, 'name' => gettext('Options'), 'set' => '', 'display' => true, 'hint' => ''),
 516:                                 'ADMIN_RIGHTS'                       => array('value' => 65536, 'name' => gettext('Admin'), 'set' => '', 'display' => true, 'hint' => ''));
 517:                 break;
 518:             case 2:
 519:                 $rightsset = array('NO_RIGHTS'                               => array('value' => 1, 'name' => gettext('No rights'), 'set' => '', 'display' => false, 'hint' => ''),
 520:                                 'OVERVIEW_RIGHTS'                    => array('value' => pow(2, 2), 'name' => gettext('Overview'), 'set' => gettext('Gallery'), 'display' => true, 'hint' => gettext('Users with this right may view the admin overview page.')),
 521:                                 'VIEW_ALL_RIGHTS'                    => array('value' => pow(2, 4), 'name' => gettext('View all'), 'set' => gettext('Gallery'), 'display' => true, 'hint' => gettext('Users with this right may view all of the gallery regardless of protection of the page. Without this right, the user can view only public ones and those checked in his managed object lists or as granted by View Search or View Gallery.')),
 522:                                 'UPLOAD_RIGHTS'                      => array('value' => pow(2, 6), 'name' => gettext('Upload'), 'set' => gettext('Gallery'), 'display' => true, 'hint' => gettext('Users with this right may upload to the albums for which they have management rights.')),
 523:                                 'POST_COMMENT_RIGHTS'            => array('value' => pow(2, 8), 'name' => gettext('Post comments'), 'set' => gettext('Gallery'), 'display' => true, 'hint' => gettext('When the comment_form plugin is used for comments and its "Only members can comment" option is set, only users with this right may post comments.')),
 524:                                 'COMMENT_RIGHTS'                     => array('value' => pow(2, 10), 'name' => gettext('Comments'), 'set' => gettext('Gallery'), 'display' => true, 'hint' => gettext('Users with this right may make comments tab changes.')),
 525:                                 'ALBUM_RIGHTS'                       => array('value' => pow(2, 12), 'name' => gettext('Albums'), 'set' => gettext('Albums'), 'display' => true, 'hint' => gettext('Users with this right may access the “albums” tab to make changes.')),
 526:                                 'ZENPAGE_PAGES_RIGHTS'       => array('value' => pow(2, 14), 'name' => gettext('Pages'), 'set' => gettext('Pages'), 'display' => true, 'hint' => gettext('Users with this right may edit and manage Zenpage pages.')),
 527:                                 'ZENPAGE_NEWS_RIGHTS'            => array('value' => pow(2, 16), 'name' => gettext('News'), 'set' => gettext('News'), 'display' => true, 'hint' => gettext('Users with this right may edit and manage Zenpage articles and categories.')),
 528:                                 'FILES_RIGHTS'                       => array('value' => pow(2, 18), 'name' => gettext('Files'), 'set' => gettext('Gallery'), 'display' => true, 'hint' => gettext('Allows the user access to the “filemanager” located on the upload: files sub-tab.')),
 529:                                 'MANAGE_ALL_PAGES_RIGHTS'    => array('value' => pow(2, 20), 'name' => gettext('Manage all pages'), 'set' => gettext('Pages'), 'display' => true, 'hint' => gettext('Users who do not have “Admin” rights normally are restricted to manage only objects to which they have been assigned. This right allows them to manage any Zenpage page.')),
 530:                                 'MANAGE_ALL_NEWS_RIGHTS'     => array('value' => pow(2, 22), 'name' => gettext('Manage all news'), 'set' => gettext('News'), 'display' => true, 'hint' => gettext('Users who do not have “Admin” rights normally are restricted to manage only objects to which they have been assigned. This right allows them to manage any Zenpage news article or category.')),
 531:                                 'MANAGE_ALL_ALBUM_RIGHTS'    => array('value' => pow(2, 24), 'name' => gettext('Manage all albums'), 'set' => gettext('Albums'), 'display' => true, 'hint' => gettext('Users who do not have “Admin” rights normally are restricted to manage only objects to which they have been assigned. This right allows them to manage any album in the gallery.')),
 532:                                 'THEMES_RIGHTS'                      => array('value' => pow(2, 26), 'name' => gettext('Themes'), 'set' => gettext('Gallery'), 'display' => true, 'hint' => gettext('Users with this right may make themes related changes. These are limited to the themes associated with albums checked in their managed albums list.')),
 533:                                 'TAGS_RIGHTS'                            => array('value' => pow(2, 28), 'name' => gettext('Tags'), 'set' => gettext('General'), 'display' => true, 'hint' => gettext('Users with this right may make additions and changes to the set of tags.')),
 534:                                 'OPTIONS_RIGHTS'                     => array('value' => pow(2, 29), 'name' => gettext('Options'), 'set' => gettext('General'), 'display' => true, 'hint' => gettext('Users with this right may make changes on the options tabs.')),
 535:                                 'ADMIN_RIGHTS'                       => array('value' => pow(2, 30), 'name' => gettext('Admin'), 'set' => gettext('General'), 'display' => true, 'hint' => gettext('The master privilege. A user with "Admin" can do anything. (No matter what his other rights might indicate!)')));
 536:                 break;
 537:             case 3:
 538:                 $rightsset = array('NO_RIGHTS'                               => array('value' => 1, 'name' => gettext('No rights'), 'set' => '', 'display' => false, 'hint' => ''),
 539:                                 'OVERVIEW_RIGHTS'                    => array('value' => pow(2, 2), 'name' => gettext('Overview'), 'set' => gettext('General'), 'display' => true, 'hint' => gettext('Users with this right may view the admin overview page.')),
 540:                                 'VIEW_GALLERY_RIGHTS'            => array('value' => pow(2, 4), 'name' => gettext('View gallery'), 'set' => gettext('Gallery'), 'display' => true, 'hint' => gettext('Users with this right may view otherwise protected generic gallery pages.')),
 541:                                 'VIEW_SEARCH_RIGHTS'             => array('value' => pow(2, 5), 'name' => gettext('View search'), 'set' => gettext('Gallery'), 'display' => true, 'hint' => gettext('Users with this right may view search pages even if password protected.')),
 542:                                 'VIEW_FULLIMAGE_RIGHTS'      => array('value' => pow(2, 6), 'name' => gettext('View fullimage'), 'set' => gettext('Albums'), 'display' => true, 'hint' => gettext('Users with this right may view all full sized (raw) images.')),
 543:                                 'ALL_NEWS_RIGHTS'                    => array('value' => pow(2, 7), 'name' => gettext('Access all'), 'set' => gettext('News'), 'display' => true, 'hint' => gettext('Users with this right have access to all zenpage news articles.')),
 544:                                 'ALL_PAGES_RIGHTS'               => array('value' => pow(2, 8), 'name' => gettext('Access all'), 'set' => gettext('Pages'), 'display' => true, 'hint' => gettext('Users with this right have access to all zenpage pages.')),
 545:                                 'ALL_ALBUMS_RIGHTS'              => array('value' => pow(2, 9), 'name' => gettext('Access all'), 'set' => gettext('Albums'), 'display' => true, 'hint' => gettext('Users with this right have access to all albums.')),
 546:                                 'VIEW_UNPUBLISHED_RIGHTS'    => array('value' => pow(2, 10), 'name' => gettext('View unpublished'), 'set' => gettext('Albums'), 'display' => true, 'hint' => gettext('Users with this right will see all unpublished items.')),
 547:                                 'POST_COMMENT_RIGHTS'            => array('value' => pow(2, 11), 'name' => gettext('Post comments'), 'set' => gettext('Gallery'), 'display' => true, 'hint' => gettext('When the comment_form plugin is used for comments and its "Only members can comment" option is set, only users with this right may post comments.')),
 548:                                 'COMMENT_RIGHTS'                     => array('value' => pow(2, 12), 'name' => gettext('Comments'), 'set' => gettext('Gallery'), 'display' => true, 'hint' => gettext('Users with this right may make comments tab changes.')),
 549:                                 'UPLOAD_RIGHTS'                      => array('value' => pow(2, 13), 'name' => gettext('Upload'), 'set' => gettext('Albums'), 'display' => true, 'hint' => gettext('Users with this right may upload to the albums for which they have management rights.')),
 550:                                 'ZENPAGE_NEWS_RIGHTS'            => array('value' => pow(2, 15), 'name' => gettext('News'), 'set' => gettext('News'), 'display' => false, 'hint' => gettext('Users with this right may edit and manage Zenpage articles and categories.')),
 551:                                 'ZENPAGE_PAGES_RIGHTS'       => array('value' => pow(2, 16), 'name' => gettext('Pages'), 'set' => gettext('Pages'), 'display' => false, 'hint' => gettext('Users with this right may edit and manage Zenpage pages.')),
 552:                                 'FILES_RIGHTS'                       => array('value' => pow(2, 17), 'name' => gettext('Files'), 'set' => gettext('Gallery'), 'display' => true, 'hint' => gettext('Allows the user access to the “filemanager” located on the upload: files sub-tab.')),
 553:                                 'ALBUM_RIGHTS'                       => array('value' => pow(2, 18), 'name' => gettext('Albums'), 'set' => gettext('Albums'), 'display' => false, 'hint' => gettext('Users with this right may access the “albums” tab to make changes.')),
 554:                                 'MANAGE_ALL_NEWS_RIGHTS'     => array('value' => pow(2, 21), 'name' => gettext('Manage all'), 'set' => gettext('News'), 'display' => true, 'hint' => gettext('Users who do not have “Admin” rights normally are restricted to manage only objects to which they have been assigned. This right allows them to manage any Zenpage news article or category.')),
 555:                                 'MANAGE_ALL_PAGES_RIGHTS'    => array('value' => pow(2, 22), 'name' => gettext('Manage all'), 'set' => gettext('Pages'), 'display' => true, 'hint' => gettext('Users who do not have “Admin” rights normally are restricted to manage only objects to which they have been assigned. This right allows them to manage any Zenpage page.')),
 556:                                 'MANAGE_ALL_ALBUM_RIGHTS'    => array('value' => pow(2, 23), 'name' => gettext('Manage all'), 'set' => gettext('Albums'), 'display' => true, 'hint' => gettext('Users who do not have “Admin” rights normally are restricted to manage only objects to which they have been assigned. This right allows them to manage any album in the gallery.')),
 557:                                 'THEMES_RIGHTS'                      => array('value' => pow(2, 26), 'name' => gettext('Themes'), 'set' => gettext('Gallery'), 'display' => true, 'hint' => gettext('Users with this right may make themes related changes. These are limited to the themes associated with albums checked in their managed albums list.')),
 558:                                 'TAGS_RIGHTS'                            => array('value' => pow(2, 28), 'name' => gettext('Tags'), 'set' => gettext('Gallery'), 'display' => true, 'hint' => gettext('Users with this right may make additions and changes to the set of tags.')),
 559:                                 'OPTIONS_RIGHTS'                     => array('value' => pow(2, 29), 'name' => gettext('Options'), 'set' => gettext('General'), 'display' => true, 'hint' => gettext('Users with this right may make changes on the options tabs.')),
 560:                                 'ADMIN_RIGHTS'                       => array('value' => pow(2, 30), 'name' => gettext('Admin'), 'set' => gettext('General'), 'display' => true, 'hint' => gettext('The master privilege. A user with "Admin" can do anything. (No matter what his other rights might indicate!)')));
 561:                 break;
 562:             case 4:
 563:                 $rightsset = array('NO_RIGHTS'                               => array('value' => 1, 'name' => gettext('No rights'), 'set' => '', 'display' => false, 'hint' => ''),
 564:                                 'OVERVIEW_RIGHTS'                    => array('value' => pow(2, 2), 'name' => gettext('Overview'), 'set' => gettext('General'), 'display' => true, 'hint' => gettext('Users with this right may view the admin overview page.')),
 565:                                 'USER_RIGHTS'                            => array('value' => pow(2, 3), 'name' => gettext('User'), 'set' => gettext('General'), 'display' => true, 'hint' => gettext('Users must have this right to change their credentials.')),
 566:                                 'VIEW_GALLERY_RIGHTS'            => array('value' => pow(2, 5), 'name' => gettext('View gallery'), 'set' => gettext('Gallery'), 'display' => true, 'hint' => gettext('Users with this right may view otherwise protected generic gallery pages.')),
 567:                                 'VIEW_SEARCH_RIGHTS'             => array('value' => pow(2, 6), 'name' => gettext('View search'), 'set' => gettext('Gallery'), 'display' => true, 'hint' => gettext('Users with this right may view search pages even if password protected.')),
 568:                                 'VIEW_FULLIMAGE_RIGHTS'      => array('value' => pow(2, 7), 'name' => gettext('View fullimage'), 'set' => gettext('Albums'), 'display' => true, 'hint' => gettext('Users with this right may view all full sized (raw) images.')),
 569:                                 'ALL_NEWS_RIGHTS'                    => array('value' => pow(2, 8), 'name' => gettext('Access all'), 'set' => gettext('News'), 'display' => true, 'hint' => gettext('Users with this right have access to all zenpage news articles.')),
 570:                                 'ALL_PAGES_RIGHTS'               => array('value' => pow(2, 9), 'name' => gettext('Access all'), 'set' => gettext('Pages'), 'display' => true, 'hint' => gettext('Users with this right have access to all zenpage pages.')),
 571:                                 'ALL_ALBUMS_RIGHTS'              => array('value' => pow(2, 10), 'name' => gettext('Access all'), 'set' => gettext('Albums'), 'display' => true, 'hint' => gettext('Users with this right have access to all albums.')),
 572:                                 'VIEW_UNPUBLISHED_RIGHTS'    => array('value' => pow(2, 11), 'name' => gettext('View unpublished'), 'set' => gettext('Albums'), 'display' => true, 'hint' => gettext('Users with this right will see all unpublished items.')),
 573:                                 'POST_COMMENT_RIGHTS'            => array('value' => pow(2, 13), 'name' => gettext('Post comments'), 'set' => gettext('Gallery'), 'display' => true, 'hint' => gettext('When the comment_form plugin is used for comments and its "Only members can comment" option is set, only users with this right may post comments.')),
 574:                                 'COMMENT_RIGHTS'                     => array('value' => pow(2, 14), 'name' => gettext('Comments'), 'set' => gettext('Gallery'), 'display' => true, 'hint' => gettext('Users with this right may make comments tab changes.')),
 575:                                 'UPLOAD_RIGHTS'                      => array('value' => pow(2, 15), 'name' => gettext('Upload'), 'set' => gettext('Albums'), 'display' => true, 'hint' => gettext('Users with this right may upload to the albums for which they have management rights.')),
 576:                                 'ZENPAGE_NEWS_RIGHTS'            => array('value' => pow(2, 17), 'name' => gettext('News'), 'set' => gettext('News'), 'display' => false, 'hint' => gettext('Users with this right may edit and manage Zenpage articles and categories.')),
 577:                                 'ZENPAGE_PAGES_RIGHTS'       => array('value' => pow(2, 18), 'name' => gettext('Pages'), 'set' => gettext('Pages'), 'display' => false, 'hint' => gettext('Users with this right may edit and manage Zenpage pages.')),
 578:                                 'FILES_RIGHTS'                       => array('value' => pow(2, 19), 'name' => gettext('Files'), 'set' => gettext('Gallery'), 'display' => true, 'hint' => gettext('Allows the user access to the “filemanager” located on the upload: files sub-tab.')),
 579:                                 'ALBUM_RIGHTS'                       => array('value' => pow(2, 20), 'name' => gettext('Albums'), 'set' => gettext('Albums'), 'display' => false, 'hint' => gettext('Users with this right may access the “albums” tab to make changes.')),
 580:                                 'MANAGE_ALL_NEWS_RIGHTS'     => array('value' => pow(2, 21), 'name' => gettext('Manage all'), 'set' => gettext('News'), 'display' => true, 'hint' => gettext('Users who do not have “Admin” rights normally are restricted to manage only objects to which they have been assigned. This right allows them to manage any Zenpage news article or category.')),
 581:                                 'MANAGE_ALL_PAGES_RIGHTS'    => array('value' => pow(2, 22), 'name' => gettext('Manage all'), 'set' => gettext('Pages'), 'display' => true, 'hint' => gettext('Users who do not have “Admin” rights normally are restricted to manage only objects to which they have been assigned. This right allows them to manage any Zenpage page.')),
 582:                                 'MANAGE_ALL_ALBUM_RIGHTS'    => array('value' => pow(2, 23), 'name' => gettext('Manage all'), 'set' => gettext('Albums'), 'display' => true, 'hint' => gettext('Users who do not have “Admin” rights normally are restricted to manage only objects to which they have been assigned. This right allows them to manage any album in the gallery.')),
 583:                                 'CODEBLOCK_RIGHTS'               => array('value' => pow(2, 25), 'name' => gettext('Codeblock'), 'set' => gettext('General'), 'display' => true, 'hint' => gettext('Users with this right may edit Codeblocks.')),
 584:                                 'THEMES_RIGHTS'                      => array('value' => pow(2, 26), 'name' => gettext('Themes'), 'set' => gettext('Gallery'), 'display' => true, 'hint' => gettext('Users with this right may make themes related changes. These are limited to the themes associated with albums checked in their managed albums list.')),
 585:                                 'TAGS_RIGHTS'                            => array('value' => pow(2, 28), 'name' => gettext('Tags'), 'set' => gettext('Gallery'), 'display' => true, 'hint' => gettext('Users with this right may make additions and changes to the set of tags.')),
 586:                                 'OPTIONS_RIGHTS'                     => array('value' => pow(2, 29), 'name' => gettext('Options'), 'set' => gettext('General'), 'display' => true, 'hint' => gettext('Users with this right may make changes on the options tabs.')),
 587:                                 'ADMIN_RIGHTS'                       => array('value' => pow(2, 30), 'name' => gettext('Admin'), 'set' => gettext('General'), 'display' => true, 'hint' => gettext('The master privilege. A user with "Admin" can do anything. (No matter what his other rights might indicate!)')));
 588:                 break;
 589:         }
 590:         $allrights = 0;
 591:         foreach ($rightsset as $key => $right) {
 592:             $allrights = $allrights | $right['value'];
 593:         }
 594:         $rightsset['ALL_RIGHTS'] = array('value' => $allrights, 'name' => gettext('All rights'), 'display' => false);
 595:         $rightsset['DEFAULT_RIGHTS'] = array('value' => $rightsset['OVERVIEW_RIGHTS']['value'] + $rightsset['POST_COMMENT_RIGHTS']['value'], 'name' => gettext('Default rights'), 'display' => false);
 596:         if (isset($rightsset['VIEW_ALL_RIGHTS']['value'])) {
 597:             $rightsset['DEFAULT_RIGHTS']['value'] = $rightsset['DEFAULT_RIGHTS']['value'] | $rightsset['VIEW_ALL_RIGHTS']['value'];
 598:         } else {
 599:             $rightsset['DEFAULT_RIGHTS']['value'] = $rightsset['DEFAULT_RIGHTS'] | $rightsset['ALL_ALBUMS_RIGHTS']['value'] |
 600:                             $rightsset['ALL_PAGES_RIGHTS']['value'] | $rightsset['ALL_NEWS_RIGHTS']['value'] |
 601:                             $rightsset['VIEW_SEARCH_RIGHTS']['value'] | $rightsset['VIEW_GALLERY_RIGHTS']['value'];
 602:         }
 603:         $rightsset = sortMultiArray($rightsset, 'value', true, false, false);
 604:         return $rightsset;
 605:     }
 606: 
 607:     static function getResetTicket($user, $pass) {
 608:         $req = time();
 609:         $ref = sha1($req . $user . $pass);
 610:         $time = bin2hex(rc4('ticket' . HASH_SEED, $req));
 611:         return $time . $ref;
 612:     }
 613: 
 614:     function validateTicket($ticket, $user) {
 615:         global $_zp_current_admin_obj;
 616:         $admins = $this->getAdministrators();
 617:         foreach ($admins as $tuser) {
 618:             if ($tuser['user'] == $user) {
 619:                 if ($tuser['rights'] & USER_RIGHTS) {
 620:                     $request_date = rc4('ticket' . HASH_SEED, pack("H*", $time = substr($ticket, 0, 20)));
 621:                     $ticket = substr($ticket, 20);
 622:                     $ref = sha1($request_date . $user . $tuser['pass']);
 623:                     if ($ref === $ticket) {
 624:                         if (time() <= ($request_date + (3 * 24 * 60 * 60))) {
 625:                             // limited time offer
 626:                             $_zp_current_admin_obj = new Zenphoto_Administrator($user, 1);
 627:                             $_zp_current_admin_obj->reset = true;
 628:                         }
 629:                     }
 630:                     break;
 631:                 }
 632:             }
 633:         }
 634:     }
 635: 
 636:     /**
 637:      * Set log-in cookie for a user
 638:      * @param object $user
 639:      */
 640:     static function logUser($user) {
 641:         $user->set('lastloggedin', $user->get('loggedin'));
 642:         $user->set('loggedin', date('Y-m-d H:i:s'));
 643:         $user->save();
 644:         zp_setCookie("zp_user_auth", $user->getPass() . '.' . $user->getID(), NULL, NULL, secureServer());
 645:     }
 646: 
 647:     /**
 648:      * User authentication support
 649:      */
 650:     function handleLogon() {
 651:         global $_zp_current_admin_obj, $_zp_login_error, $_zp_captcha, $_zp_loggedin;
 652:         if (isset($_POST['login'])) {
 653:             $post_user = sanitize(@$_POST['user']);
 654:             $post_pass = sanitize(@$_POST['pass'], 0);
 655:             $_zp_loggedin = false;
 656: 
 657:             switch (@$_POST['password']) {
 658:                 default:
 659:                     $user = self::checkLogon($post_user, $post_pass);
 660:                     if ($user) {
 661:                         $_zp_loggedin = $user->getRights();
 662:                     }
 663:                     $_zp_loggedin = zp_apply_filter('admin_login_attempt', $_zp_loggedin, $post_user, $post_pass);
 664:                     if ($_zp_loggedin) {
 665:                         self::logUser($user);
 666:                         $_zp_current_admin_obj = $user;
 667:                     } else {
 668:                         zp_clearCookie("zp_user_auth"); // Clear the cookie, just in case
 669:                         $_zp_login_error = 1;
 670:                     }
 671:                     break;
 672:                 case 'challenge':
 673:                     $user = self::getAnAdmin(array('`user`=' => $post_user, '`valid`=' => 1));
 674:                     if (is_object($user)) {
 675:                         $info = $user->getChallengePhraseInfo();
 676:                         if ($post_pass && $info['response'] == $post_pass) {
 677:                             $ref = self::getResetTicket($post_user, $user->getPass());
 678:                             header('location:' . WEBPATH . '/' . ZENFOLDER . '/admin-users.php?ticket=' . $ref . '&user=' . $post_user);
 679:                             exitZP();
 680:                         }
 681:                     }
 682:                     if ( !empty($info['challenge']) && !empty($_POST['pass'])) { $_zp_login_error = gettext('Sorry, that is not the answer.'); }
 683:                     $_REQUEST['logon_step'] = 'challenge';
 684:                     break;
 685:                 case 'captcha':
 686:                     if ($_zp_captcha->checkCaptcha(trim(@$_POST['code']), sanitize(@$_POST['code_h'], 3))) {
 687:                         require_once(dirname(__FILE__) . '/load_objectClasses.php'); // be sure that the plugins are loaded for the mail handler
 688:                         if (empty($post_user)) {
 689:                             $requestor = gettext('You are receiving this e-mail because of a password reset request on your Zenphoto gallery.');
 690:                         } else {
 691:                             $requestor = sprintf(gettext("You are receiving this e-mail because of a password reset request on your Zenphoto gallery from a user who tried to log in as %s."), $post_user);
 692:                         }
 693:                         $admins = $this->getAdministrators();
 694:                         $mails = array();
 695:                         $user = NULL;
 696:                         foreach ($admins as $key => $tuser) {
 697:                             if (!empty($tuser['email'])) {
 698:                                 if (!empty($post_user) && ($tuser['user'] == $post_user || $tuser['email'] == $post_user)) {
 699:                                     $name = $tuser['name'];
 700:                                     if (empty($name)) {
 701:                                         $name = $tuser['user'];
 702:                                     }
 703:                                     $mails[$name] = $tuser['email'];
 704:                                     $user = $tuser;
 705:                                     unset($admins[$key]); // drop him from alternate list.
 706:                                 } else {
 707:                                     if (!($tuser['rights'] & ADMIN_RIGHTS)) {
 708:                                         unset($admins[$key]); // eliminate any peons from the list
 709:                                     }
 710:                                 }
 711:                             } else {
 712:                                 unset($admins[$key]); // we want to ignore groups and users with no email address here!
 713:                             }
 714:                         }
 715: 
 716:                         $cclist = array();
 717:                         foreach ($admins as $tuser) {
 718:                             $name = $tuser['name'];
 719:                             if (empty($name)) {
 720:                                 $name = $tuser['user'];
 721:                             }
 722:                             if (is_null($user)) {
 723:                                 $user = $tuser;
 724:                                 $mails[$name] = $tuser['email'];
 725:                             } else {
 726:                                 $cclist[$name] = $tuser['email'];
 727:                             }
 728:                         }
 729:                         if (is_null($user)) {
 730:                             $_zp_login_error = gettext('There was no one to which to send the reset request.');
 731:                         } else {
 732:                             $ref = self::getResetTicket($user['user'], $user['pass']);
 733:                             $msg = "\n" . $requestor .
 734:                                             "\n" . sprintf(gettext("To reset your Zenphoto Admin passwords visit: %s"), FULLWEBPATH . "/" . ZENFOLDER . "/admin-users.php?ticket=$ref&user=" . $user['user']) .
 735:                                             "\n" . gettext("If you do not wish to reset your passwords just ignore this message. This ticket will automatically expire in 3 days.");
 736:                             $err_msg = zp_mail(gettext("The Zenphoto information you requested"), $msg, $mails, $cclist);
 737:                             if (empty($err_msg)) {
 738:                                 $_zp_login_error = 2;
 739:                             } else {
 740:                                 $_zp_login_error = $err_msg;
 741:                             }
 742:                         }
 743:                     } else {
 744:                         $_zp_login_error = gettext('Your input did not match the captcha');
 745:                         $_REQUEST['logon_step'] = 'captcha';
 746:                     }
 747:                     break;
 748:             }
 749:         }
 750:         return $_zp_loggedin;
 751:     }
 752: 
 753:     /**
 754:      *
 755:      * returns an array of the active "password" cookies
 756:      *
 757:      * NOTE: this presumes the general form of an authrization cookie is:
 758:      * zp_xxxxx_auth{_dddd) where xxxxx is the authority (e.g. gallery, image, search, ...)
 759:      * and dddd if present is the object id.
 760:      *
 761:      */
 762:     static function getAuthCookies() {
 763:         $candidates = array();
 764:         if (isset($_COOKIE)) {
 765:             $candidates = $_COOKIE;
 766:         }
 767:         if (isset($_SESSION)) {
 768:             $candidates = array_merge($candidates, $_SESSION);
 769:         }
 770:         foreach ($candidates as $key => $candidate) {
 771:             if (strpos($key, '_auth') === false) {
 772:                 unset($candidates[$key]);
 773:             }
 774:         }
 775:         return $candidates;
 776:     }
 777: 
 778:     /**
 779:      * Cleans up on logout
 780:      *
 781:      */
 782:     static function handleLogout() {
 783:         global $_zp_loggedin, $_zp_pre_authorization, $_zp_current_admin_obj;
 784:         foreach (self::getAuthCookies() as $cookie => $value) {
 785:             zp_clearCookie($cookie);
 786:         }
 787:         $_zp_loggedin = false;
 788:         $_zp_pre_authorization = array();
 789:         return zp_apply_filter('zp_logout', NULL, $_zp_current_admin_obj);
 790:     }
 791: 
 792:     /**
 793:      * Checks saved cookies to see if a user is logged in
 794:      */
 795:     function checkCookieCredentials() {
 796:         list($auth, $id) = explode('.', zp_getCookie('zp_user_auth') . '.');
 797:         $loggedin = $this->checkAuthorization($auth, $id);
 798:         $loggedin = zp_apply_filter('authorization_cookie', $loggedin, $auth, $id);
 799:         if ($loggedin) {
 800:             return $loggedin;
 801:         } else {
 802:             zp_clearCookie("zp_user_auth");
 803:             return NULL;
 804:         }
 805:     }
 806: 
 807:     /**
 808:      * Print the login form for ZP. This will take into account whether mod_rewrite is enabled or not.
 809:      *
 810:      * @param string $redirect URL to return to after login
 811:      * @param bool $logo set to true to display the ADMIN zenphoto logo.
 812:      * @param bool $showUserField set to true to display the user input
 813:      * @param bool $showCaptcha set to false to not display the forgot password captcha.
 814:      * @param string $hint optional hint for the password
 815:      *
 816:      */
 817:     function printLoginForm($redirect = null, $logo = true, $showUserField = true, $showCaptcha = true, $hint = '') {
 818:         global $_zp_login_error, $_zp_captcha, $_zp_gallery;
 819:         if (is_null($redirect)) {
 820:             $redirect = getRequestURI();
 821:         }
 822: 
 823:         if (isset($_POST['user'])) {
 824:             $requestor = sanitize($_POST['user'], 3);
 825:         } else {
 826:             $requestor = '';
 827:         }
 828:         if (empty($requestor)) {
 829:             if (isset($_GET['ref'])) {
 830:                 $requestor = sanitize($_GET['ref']);
 831:             }
 832:         }
 833:         $alt_handlers = zp_apply_filter('alt_login_handler', array());
 834:         $star = false;
 835:         $mails = array();
 836:         $info = array('challenge' => '', 'response' => '');
 837:         if (!empty($requestor)) {
 838:             $admin = self::getAnAdmin(array('`user`=' => $requestor, '`valid`=' => 1));
 839:             if (is_object($admin)) {
 840:                 if ($admin->getEmail()) {
 841:                     $star = $showCaptcha;
 842:                 }
 843:                 $info = $admin->getChallengePhraseInfo();
 844:             }
 845:         }
 846:         if (!$star) {
 847:             $admins = $this->getAdministrators();
 848:             while (count($admins) > 0) {
 849:                 $user = array_shift($admins);
 850:                 if ($user['email']) {
 851:                     $star = $showCaptcha;
 852:                 }
 853:             }
 854:         }
 855:         $whichForm = sanitize(@$_REQUEST['logon_step']);
 856:         ?>
 857:         <div id="loginform">
 858:             <?php
 859:             if ($logo) {
 860:                 ?>
 861:                 <p>
 862:                     <img src="<?php echo WEBPATH . '/' . ZENFOLDER; ?>/images/zen-logo.png" title="ZenPhoto" alt="ZenPhoto" />
 863:                 </p>
 864:                 <?php
 865:             }
 866:             switch ($_zp_login_error) {
 867:                 case 1:
 868:                     ?>
 869:                     <div class="errorbox" id="message"><h2><?php echo gettext("There was an error logging in."); ?></h2>
 870:                         <?php
 871:                         if ($showUserField) {
 872:                             echo gettext("Check your username and password and try again.");
 873:                         } else {
 874:                             echo gettext("Check password and try again.");
 875:                         }
 876:                         ?>
 877:                     </div>
 878:                     <?php
 879:                     break;
 880:                 case 2:
 881:                     ?>
 882:                     <div class="messagebox fade-message">
 883:                         <h2><?php echo gettext("A reset request has been sent."); ?></h2>
 884:                     </div>
 885:                     <?php
 886:                     break;
 887:                 default:
 888:                     if (!empty($_zp_login_error)) {
 889:                         ?>
 890:                         <div class="errorbox fade-message">
 891:                             <h2><?php echo $_zp_login_error; ?></h2>
 892:                         </div>
 893:                         <?php
 894:                     }
 895:                     break;
 896:             }
 897:             switch ($whichForm) {
 898:                 case 'challenge':
 899:                     ?>
 900:                     <form name="login" action="<?php echo WEBPATH . '/' . ZENFOLDER; ?>/admin.php" method="post">
 901:                         <fieldset id="logon_box">
 902:                             <input type="hidden" name="login" value="1" />
 903:                             <input type="hidden" name="password" value="challenge" />
 904:                             <input type="hidden" name="redirect" value="<?php echo html_encode(pathurlencode($redirect)); ?>" />
 905:                             <fieldset>
 906:                                 <legend><?php echo gettext('User') ?></legend>
 907:                                 <input class="textfield" name="user" id="user" type="text" size="35" value="<?php echo html_encode($requestor); ?>" />
 908:                             </fieldset>
 909:                             <?php
 910:                             if ($requestor && $admin) {
 911:                                 if (!empty($info['challenge'])) {
 912:                                 ?>
 913:                                 <p class="logon_form_text"><?php echo gettext('Supply the correct response to the question below and you will be directed to a page where you can change your password.'); ?>
 914:                                 <?php if ( $admin->getEmail() ) { echo gettext('<br />You may also use the link below to request a reset by e-mail.'); } ?>
 915:                                 </p>
 916:                                 <fieldset><legend><?php echo gettext('Challenge question:') ?></legend>
 917:                                     <?php
 918:                                     echo html_encode($info['challenge']);
 919:                                     ?>
 920:                                 </fieldset>
 921:                                 <fieldset><legend><?php echo gettext('Your response') ?></legend>
 922:                                     <input class="textfield" name="pass" id="pass" type="text" size="35" />
 923:                                 </fieldset>
 924:                                 <br />
 925:                                 <?php } else {
 926:                                         if ( !$admin->getEmail() ) { ?>
 927:                                             <fieldset><p class="logon_form_text errorbox"><?php echo gettext('A password reset is not possible.'); ?></p></fieldset>
 928:                                     <?php } else { ?>
 929:                                             <p class="logon_form_text"><?php echo gettext('Please request a reset by e-mail by clicking the link below.'); ?></p>
 930:                                 <?php
 931:                                     }
 932:                                 }
 933:                             } else {
 934:                                 ?>
 935:                                 <p class="logon_form_text">
 936:                                     <?php
 937:                                     echo gettext('Enter your User ID and press <code>Refresh</code> to get your challenge question and/or get a link to request a reset by e-mail.');
 938:                                     ?>
 939:                                 </p>
 940:                                 <?php
 941:                             }
 942:                             ?>
 943:                             <div class="buttons">
 944:                                 <button type="submit" value="<?php echo gettext("Submit"); ?>"<?php if (!$info['challenge']) echo ' disabled="disabled"'; ?> ><img src="<?php echo WEBPATH . '/' . ZENFOLDER; ?>/images/pass.png" alt="" /><?php echo gettext("Submit"); ?></button>
 945:                                 <button type="button" value="<?php echo gettext("Refresh"); ?>" id="challenge_refresh" onclick="javascript:launchScript('<?php echo WEBPATH . '/' . ZENFOLDER; ?>/admin.php', ['logon_step=challenge', 'ref=' + $('#user').val()]);" ><img src="<?php echo WEBPATH . '/' . ZENFOLDER; ?>/images/refresh.png" alt="" /><?php echo gettext("Refresh"); ?></button>
 946:                                 <button type="button" value="<?php echo gettext("Return"); ?>" onclick="javascript:launchScript('<?php echo WEBPATH . '/' . ZENFOLDER; ?>/admin.php', ['logon_step=', 'ref=' + $('#user').val()]);" ><img src="<?php echo WEBPATH . '/' . ZENFOLDER; ?>/images/refresh.png" alt="" /><?php echo gettext("Return"); ?></button>
 947:                             </div>
 948:                             <br class="clearall" />
 949:                         </fieldset>
 950:                         <br />
 951:                         <?php
 952:                         if ( $star && (!empty($requestor) && $admin->getEmail()) ) {
 953:                             ?>
 954:                             <p class="logon_link">
 955:                                 <a href="javascript:launchScript('<?php echo WEBPATH . '/' . ZENFOLDER; ?>/admin.php',['logon_step=captcha', 'ref='+$('#user').val()]);" >
 956:                                     <?php echo gettext('Request reset by e-mail'); ?>
 957:                                 </a>
 958:                             </p>
 959:                             <?php
 960:                         }
 961:                         ?>
 962:                     </form>
 963:                     <?php
 964:                     break;
 965:                 default:
 966:                     Zenphoto_Authority::printPasswordFormJS();
 967:                     if (empty($alt_handlers)) {
 968:                         $legend = gettext('Login');
 969:                     } else {
 970:                         ?>
 971:                         <script type="text/javascript">
 972:                             // <!-- <![CDATA[
 973:                             var handlers = [];
 974:                     <?php
 975:                     $list = '<select id="logon_choices" onchange="changeHandler(handlers[$(this).val()]);">' .
 976:                                     '<option value="0">' . html_encode(get_language_string($_zp_gallery->getTitle())) . '</option>';
 977:                     $c = 0;
 978:                     foreach ($alt_handlers as $handler => $details) {
 979:                         $c++;
 980:                         $details['params'][] = 'redirect=' . $redirect;
 981:                         if (!empty($requestor)) {
 982:                             $details['params'][] = 'requestor=' . $requestor;
 983:                         }
 984:                         echo "handlers[" . $c . "]=['" . $details['script'] . "','" . implode("','", $details['params']) . "'];";
 985: 
 986:                         $list .= '<option value="' . $c . '">' . $handler . '</option>';
 987:                     }
 988:                     $list .= '</select>';
 989:                     $legend = sprintf(gettext('Logon using:%s'), $list);
 990:                     ?>
 991:                             function changeHandler(handler) {
 992:                                 handler.push('user=' + $('#user').val());
 993:                                 var script = handler.shift();
 994:                                 launchScript(script, handler);
 995:                             }
 996:                             // ]]> -->
 997:                         </script>
 998:                         <?php
 999:                     }
1000:                     $redirect = zp_apply_filter('login_redirect_link', $redirect);
1001:                     ?>
1002:                     <form name="login" action="<?php echo html_encode(pathurlencode($redirect)); ?>" method="post">
1003:                         <input type="hidden" name="login" value="1" />
1004:                         <input type="hidden" name="password" value="1" />
1005:                         <input type="hidden" name="redirect" value="<?php echo html_encode(pathurlencode($redirect)); ?>" />
1006:                         <fieldset id="logon_box"><legend><?php echo $legend; ?></legend>
1007:                             <?php
1008:                             if ($showUserField) { //    requires a "user" field
1009:                                 ?>
1010:                                 <fieldset><legend><?php echo gettext("User"); ?></legend>
1011:                                     <input class="textfield" name="user" id="user" type="text" size="35" value="<?php echo html_encode($requestor); ?>" />
1012:                                 </fieldset>
1013:                                 <?php
1014:                             }
1015:                             ?>
1016:                             <fieldset><legend><?php echo gettext("Password"); ?></legend>
1017:                                 <input class="textfield" name="pass" id="pass" type="password" size="35" /><br />
1018:                                 <label><input type="checkbox" name="disclose_password" id="disclose_password" onclick="togglePassword('');" /><?php echo gettext('Show password') ?></label>
1019:                             </fieldset>
1020:                             <br />
1021:                             <div class="buttons">
1022:                                 <button type="submit" value="<?php echo gettext("Log in"); ?>" ><img src="<?php echo WEBPATH . '/' . ZENFOLDER; ?>/images/pass.png" alt="" /><?php echo gettext("Log in"); ?></button>
1023:                                 <button type="reset" value="<?php echo gettext("Reset"); ?>" ><img src="<?php echo WEBPATH . '/' . ZENFOLDER; ?>/images/reset.png" alt="" /><?php echo gettext("Reset"); ?></button>
1024:                             </div>
1025:                             <br class="clearall" />
1026:                         </fieldset>
1027:                     </form>
1028:                     <?php
1029:                     if ($hint) {
1030:                         echo '<p>' . $hint . '</p>';
1031:                     }
1032:                     if ($showUserField && OFFSET_PATH != 2) {
1033:                         ?>
1034:                         <p class="logon_link">
1035:                             <a href="javascript:launchScript('<?php echo WEBPATH . '/' . ZENFOLDER; ?>/admin.php',['logon_step=challenge', 'ref='+$('#user').val()]);" >
1036:                                 <?php echo gettext('I forgot my <strong>User ID</strong>/<strong>Password</strong>'); ?>
1037:                             </a>
1038:                         </p>
1039:                         <?php
1040:                     }
1041:                     break;
1042:                 case 'captcha':
1043:                     $captcha = $_zp_captcha->getCaptcha(NULL);
1044:                     ?>
1045:                     <form name="login" action="<?php echo WEBPATH . '/' . ZENFOLDER; ?>/admin.php" method="post">
1046:                         <?php if (isset($captcha['hidden'])) echo $captcha['hidden']; ?>
1047:                         <input type="hidden" name="login" value="1" />
1048:                         <input type="hidden" name="password" value="captcha" />
1049:                         <input type="hidden" name="redirect" value="<?php echo html_encode(pathurlencode($redirect)); ?>" />
1050:                         <fieldset id="logon_box">
1051:                             <fieldset><legend><?php echo gettext('User'); ?></legend>
1052:                                 <input class="textfield" name="user" id="user" type="text" value="<?php echo html_encode($requestor); ?>" />
1053:                             </fieldset>
1054:                             <?php if (isset($captcha['html'])) echo $captcha['html']; ?>
1055:                             <?php
1056:                             if (isset($captcha['input'])) {
1057:                                 ?>
1058:                                 <fieldset><legend><?php echo gettext("Enter CAPTCHA"); ?></legend>
1059:                                     <?php echo $captcha['input']; ?>
1060:                                 </fieldset>
1061:                                 <?php
1062:                             }
1063:                             ?>
1064:                             <br />
1065:                             <div class="buttons">
1066:                                 <button type="submit" value="<?php echo gettext("Request"); ?>" ><img src="<?php echo WEBPATH . '/' . ZENFOLDER; ?>/images/pass.png" alt="" /><?php echo gettext("Request password reset"); ?></button>
1067:                                 <button type="button" value="<?php echo gettext("Return"); ?>" onclick="javascript:launchScript('<?php echo WEBPATH . '/' . ZENFOLDER; ?>/admin.php', ['logon_step=', 'ref=' + $('#user').val()]);" ><img src="<?php echo WEBPATH . '/' . ZENFOLDER; ?>/images/refresh.png" alt="" /><?php echo gettext("Return"); ?></button>
1068:                             </div>
1069:                             <br class="clearall" />
1070:                         </fieldset>
1071:                     </form>
1072:                     <?php
1073:                     break;
1074:             }
1075:             ?>
1076:         </div>
1077:         <?php
1078:     }
1079: 
1080:     /**
1081:      *
1082:      * Javascript for password change input handling
1083:      */
1084:     static function printPasswordFormJS() {
1085:         ?>
1086:         <script type="text/javascript">
1087:             // <!-- <![CDATA[
1088:             function passwordStrength(id) {
1089:                 var inputa = '#pass' + id;
1090:                 var inputb = '#pass_r' + id;
1091:                 var displaym = '#match' + id;
1092:                 var displays = '#strength' + id;
1093:                 var numeric = 0;
1094:                 var special = 0;
1095:                 var upper = 0;
1096:                 var lower = 0;
1097:                 var str = $(inputa).val();
1098:                 var len = str.length;
1099:                 var strength = 0;
1100:                 for (c = 0; c < len; c++) {
1101:                     if (str[c].match(/[0-9]/)) {
1102:                         numeric++;
1103:                     } else if (str[c].match(/[^A-Za-z0-9]/)) {
1104:                         special++;
1105:                     } else if (str[c].toUpperCase() == str[c]) {
1106:                         upper++;
1107:                     } else {
1108:                         lower++;
1109:                     }
1110:                 }
1111:                 if (upper != len) {
1112:                     upper = upper * 2;
1113:                 }
1114:                 if (lower == len) {
1115:                     lower = lower * 0.75;
1116:                 }
1117:                 if (numeric != len) {
1118:                     numeric = numeric * 4;
1119:                 }
1120:                 if (special != len) {
1121:                     special = special * 5;
1122:                 }
1123:                 len = Math.max(0, (len - 6) * .35);
1124:                 strength = Math.min(30, Math.round(upper + lower + numeric + special + len));
1125:                 if (str.length == 0) {
1126:                     $(displays).css('color', 'black');
1127:                     $(displays).html('<?php echo gettext('Password'); ?>');
1128:                     $(inputa).css('background-image', 'none');
1129:                 } else {
1130:                     if (strength < 15) {
1131:                         $(displays).css('color', '#ff0000');
1132:                         $(displays).html('<?php echo gettext('password strength weak'); ?>');
1133:                     } else if (strength < 25) {
1134:                         $(displays).css('color', '#ff0000');
1135:                         $(displays).html('<?php echo gettext('password strength good'); ?>');
1136:                     } else {
1137:                         $(displays).css('color', '#008000');
1138:                         $(displays).html('<?php echo gettext('password strength strong'); ?>');
1139:                     }
1140:                     if (strength < <?php echo (int) getOption('password_strength'); ?>) {
1141:                         $(inputb).prop('disabled',true);
1142:                         $(displays).css('color', '#ff0000');
1143:                         $(displays).html('<?php echo gettext('password strength too weak'); ?>');
1144:                     } else {
1145:       $(inputb).parent().removeClass('ui-state-disabled');
1146:       $(inputb).prop('disabled',false);  
1147:                         passwordMatch(id);
1148:                     }
1149:                     var url = 'url(<?php echo WEBPATH . '/' . ZENFOLDER; ?>/images/strengths/strength' + strength + '.png)';
1150:                     $(inputa).css('background-image', url);
1151:                     $(inputa).css('background-size', '100%');
1152:                 }
1153:             }
1154: 
1155:             function passwordMatch(id) {
1156:                 var inputa = '#pass' + id;
1157:                 var inputb = '#pass_r' + id;
1158:                 var display = '#match' + id;
1159:                 if ($('#disclose_password' + id).prop('checked')) {
1160:                     if ($(inputa).val() === $(inputb).val()) {
1161:                         if ($(inputa).val().trim() !== '') {
1162:                             $(display).css('color', '#008000');
1163:                             $(display).html('<?php echo gettext('passwords match'); ?>');
1164:                         }
1165:                     } else {
1166:                         $(display).css('color', '#ff0000');
1167:                         $(display).html('<?php echo gettext('passwords do not match'); ?>');
1168:                     }
1169:                 }
1170:             }
1171: 
1172:             function passwordClear(id) {
1173:                 var inputa = '#pass' + id;
1174:                 var inputb = '#pass_r' + id;
1175:                 if ($(inputa).val().trim() === '') {
1176:                     $(inputa).val('');
1177:                 }
1178:                 if ($(inputb).val().trim() === '') {
1179:                     $(inputb).val('');
1180:                 }
1181:             }
1182:             function togglePassword(id) {
1183:                 if ($('#pass' + id).attr('type') == 'password') {
1184:                     var oldp = $('#pass' + id);
1185:                     var newp = oldp.clone();
1186:                     newp.attr('type', 'text');
1187:                     newp.insertAfter(oldp);
1188:                     oldp.remove();
1189:                     $('.password_field_' + id).hide();
1190:                 } else {
1191:                     var oldp = $('#pass' + id);
1192:                     var newp = oldp.clone();
1193:                     newp.attr('type', 'password');
1194:                     newp.insertAfter(oldp);
1195:                     oldp.remove();
1196:                     $('.password_field_' + id).show();
1197:                 }
1198:             }
1199:             // ]]> -->
1200:         </script>
1201:         <?php
1202:     }
1203: 
1204:     static function printPasswordForm($id = '', $pad = false, $disable = NULL, $required = false, $flag = '') {
1205:         if ($pad) {
1206:             $x = '          ';
1207:         } else {
1208:             $x = '';
1209:         }
1210:         ?>
1211:         <input type="hidden" name="passrequired<?php echo $id; ?>" id="passrequired-<?php echo $id; ?>" value="<?php echo (int) $required; ?>" />
1212:         <p>
1213:             <label for="pass<?php echo $id; ?>" id="strength<?php echo $id; ?>"><?php echo gettext("Password") . $flag; ?></label>
1214:             <input type="password" size="<?php echo TEXT_INPUT_SIZE; ?>"
1215:                          name="pass<?php echo $id ?>" value="<?php echo $x; ?>"
1216:                          id="pass<?php echo $id; ?>"
1217:                          onchange="$('#passrequired-<?php echo $id; ?>').val(1);"
1218:                          onclick="passwordClear('<?php echo $id; ?>');"
1219:                          onkeyup="passwordStrength('<?php echo $id; ?>');"
1220:                          <?php echo $disable; ?> />
1221:         </p>
1222:         <p>
1223:             <label for="disclose_password<?php echo $id; ?>"><?php echo gettext('Show password'); ?></label>
1224:             <input type="checkbox" name="disclose_password<?php echo $id; ?>" id="disclose_password<?php echo $id; ?>" onclick="passwordClear('<?php echo $id; ?>');
1225:                     togglePassword('<?php echo $id; ?>');">
1226:         </p>
1227:         <p class="password_field_<?php echo $id; ?>">
1228:             <label for="pass_r<?php echo $id; ?>" id="match<?php echo $id; ?>"><?php echo gettext("Repeat password") . $flag; ?></label>
1229:             <input type="password" size="<?php echo TEXT_INPUT_SIZE; ?>"
1230:                          name="pass_r<?php echo $id ?>" value="<?php echo $x; ?>"
1231:                          id="pass_r<?php echo $id; ?>" disabled="disabled"
1232:                          onchange="$('#passrequired-<?php echo $id; ?>').val(1);"
1233:                          onkeydown="passwordClear('<?php echo $id; ?>');"
1234:                          onkeyup="passwordMatch('<?php echo $id; ?>');" />
1235:         </p>
1236:         <?php
1237:     }
1238: 
1239:     /** PBKDF2 Implementation (described in RFC 2898)
1240:      *
1241:      *  @param string p password
1242:      *  @param string s salt
1243:      *  @param int c iteration count (use 1000 or higher)
1244:      *  @param int kl derived key length
1245:      *  @param string a hash algorithm
1246:      *
1247:      *  @return string derived key
1248:      */
1249:     static function pbkdf2($p, $s, $c = 1000, $kl = 32, $a = 'sha256') {
1250:         $hl = strlen(hash($a, null, true)); # Hash length
1251:         $kb = ceil($kl / $hl); # Key blocks to compute
1252:         $dk = ''; # Derived key
1253:         # Create key
1254:         for ($block = 1; $block <= $kb; $block++) {
1255:             # Initial hash for this block
1256:             $ib = $b = hash_hmac($a, $s . pack('N', $block), $p, true);
1257:             # Perform block iterations
1258:             for ($i = 1; $i < $c; $i++)
1259:             # XOR each iterate
1260:                 $ib ^= ($b = hash_hmac($a, $b, $p, true));
1261:             $dk .= $ib; # Append iterated block
1262:         }
1263:         # Return derived key of correct length
1264:         return substr($dk, 0, $kl);
1265:     }
1266:     
1267:     /**
1268:      * Checks if the email address being set is already used by another user
1269:      * 
1270:      * @param string $email_to_check email address to check
1271:      * @param type $current_user user id of the user trying to set this email address
1272:      * @return boolean
1273:      */
1274:     function checkUniqueMailaddress($email_to_check, $current_user) {
1275:         $all_users = $this->getAdministrators('users');
1276:         foreach ($all_users as $user) {
1277:             if ($user['user'] != $current_user && $user['email'] == $email_to_check) {
1278:                 return true;
1279:             }
1280:         }
1281:         return false;
1282:     }
1283: 
1284: }
1285: 
1286: class Zenphoto_Administrator extends PersistentObject {
1287: 
1288:     /**
1289:      * This is a simple class so that we have a convienient "handle" for manipulating Administrators.
1290:      *
1291:      * NOTE: one should use the Zenphoto_Authority newAdministrator() method rather than directly instantiating
1292:      * an administrator object
1293:      *
1294:      */
1295:     var $objects = NULL;
1296:     var $master = false; // will be set to true if this is the inherited master user
1297:     var $msg = NULL; // a means of storing error messages from filter processing
1298:     var $logout_link = true; // for a Zenphoto logout
1299:     var $reset = false; // if true the user was setup by a "reset password" event
1300:     var $passhash; // the hash algorithm used in creating the password
1301: 
1302:     /**
1303:      * Constructor for an Administrator
1304:      *
1305:      * @param string $user.
1306:      * @param int $valid used to signal kind of admin object
1307:      * @return Administrator
1308:      */
1309: 
1310:     function __construct($user, $valid) {
1311:         global $_zp_authority;
1312:         $this->passhash = (int) getOption('strong_hash');
1313:         $this->instantiate('administrators', array('user' => $user, 'valid' => $valid), NULL, false, empty($user));
1314:         if (empty($user)) {
1315:             $this->set('id', -1);
1316:         }
1317:         if ($valid) {
1318:             $rights = $this->getRights();
1319:             $new_rights = 0;
1320:             if ($_zp_authority->isMasterUser($user)) {
1321:                 $new_rights = ALL_RIGHTS;
1322:                 $this->master = true;
1323:             } else {
1324:                 // make sure that the "hidden" gateway rights are set for managing objects
1325:                 if ($rights & MANAGE_ALL_ALBUM_RIGHTS) {
1326:                     $new_rights = $new_rights | ALBUM_RIGHTS;
1327:                 }
1328:                 if ($rights & MANAGE_ALL_NEWS_RIGHTS) {
1329:                     $new_rights = $new_rights | ZENPAGE_PAGES_RIGHTS;
1330:                 }
1331:                 if ($rights & MANAGE_ALL_PAGES_RIGHTS) {
1332:                     $new_rights = $new_rights | ZENPAGE_NEWS_RIGHTS;
1333:                 }
1334:                 $this->getObjects();
1335:                 foreach ($this->objects as $object) {
1336:                     switch ($object['type']) {
1337:                         case 'album':
1338:                             if ($object['edit'] && MANAGED_OBJECT_RIGHTS_EDIT) {
1339:                                 $new_rights = $new_rights | ALBUM_RIGHTS;
1340:                             }
1341:                             break;
1342:                         case 'pages':
1343:                             $new_rights = $new_rights | ZENPAGE_PAGES_RIGHTS;
1344:                             break;
1345:                         case 'news':
1346:                             $new_rights = $new_rights | ZENPAGE_NEWS_RIGHTS;
1347:                             break;
1348:                     }
1349:                 }
1350:             }
1351:             if($this->getGroup()) {
1352:                 $this->preservePrimeAlbum();
1353:             }
1354:             if ($new_rights) {
1355:                 $this->setRights($rights | $new_rights);
1356:             }
1357:         }
1358:     }
1359: 
1360:     /**
1361:      * Returns the unformatted date
1362:      *
1363:      * @return date
1364:      */
1365:     function getDateTime() {
1366:         return $this->get('date');
1367:     }
1368: 
1369:     /**
1370:      * Stores the date
1371:      *
1372:      * @param string $datetime formatted date
1373:      */
1374:     function setDateTime($datetime) {
1375:         $this->set('date', $datetime);
1376:     }
1377: 
1378:     function getID() {
1379:         return $this->get('id');
1380:     }
1381: 
1382:     /**
1383:      * Hashes and stores the password
1384:      * @param $pwd
1385:      */
1386:     function setPass($pwd) {
1387:         $hash_type = getOption('strong_hash');
1388:         $pwd = Zenphoto_Authority::passwordHash($this->getUser(), $pwd, $hash_type);
1389:         $this->set('pass', $pwd);
1390:         $this->set('passupdate', date('Y-m-d H:i:s'));
1391:         $this->set('passhash', $hash_type);
1392:         return $this->get('pass');
1393:     }
1394: 
1395:     /**
1396:      * Returns stored password hash
1397:      */
1398:     function getPass() {
1399:         return $this->get('pass');
1400:     }
1401: 
1402:     /**
1403:      * Stores the user name
1404:      */
1405:     function setName($admin_n) {
1406:         $this->set('name', $admin_n);
1407:     }
1408: 
1409:     /**
1410:      * Returns the user name
1411:      */
1412:     function getName() {
1413:         return $this->get('name');
1414:     }
1415: 
1416:     /**
1417:      * Stores the user email
1418:      */
1419:     function setEmail($admin_e) {
1420:         $this->set('email', $admin_e);
1421:     }
1422: 
1423:     /**
1424:      * Returns the user email
1425:      */
1426:     function getEmail() {
1427:         return $this->get('email');
1428:     }
1429: 
1430:     /**
1431:      * Stores user rights
1432:      */
1433:     function setRights($rights) {
1434:         $this->set('rights', $rights);
1435:     }
1436: 
1437:     /**
1438:      * Returns user rights
1439:      */
1440:     function getRights() {
1441:         return $this->get('rights');
1442:     }
1443: 
1444:     /**
1445:      * Returns local copy of managed objects.
1446:      */
1447:     function setObjects($objects) {
1448:         $this->objects = $objects;
1449:     }
1450: 
1451:     /**
1452:      * Saves local copy of managed objects.
1453:      * NOTE: The database is NOT updated by this, the user object MUST be saved to
1454:      * cause an update
1455:      */
1456:     function getObjects($what = NULL) {
1457:         if (is_null($this->objects)) {
1458:             if ($this->transient) {
1459:                 $this->objects = array();
1460:             } else {
1461:                 $this->objects = populateManagedObjectsList(NULL, $this->getID());
1462:             }
1463:         }
1464:         if (empty($what)) {
1465:             return $this->objects;
1466:         }
1467:         $result = array();
1468:         foreach ($this->objects as $object) {
1469:             if ($object['type'] == $what) {
1470:                 $result[get_language_string($object['name'])] = $object['data'];
1471:             }
1472:         }
1473:         return $result;
1474:     }
1475: 
1476:     /**
1477:      * Stores custom data
1478:      */
1479:     function setCustomData($custom_data) {
1480:         $this->set('custom_data', $custom_data);
1481:     }
1482: 
1483:     /**
1484:      * Returns custom data
1485:      */
1486:     function getCustomData() {
1487:         return $this->get('custom_data');
1488:     }
1489: 
1490:     /**
1491:      * Sets the "valid" flag. Valid is 1 for users, 0 for groups and templates
1492:      */
1493:     function setValid($valid) {
1494:         $this->set('valid', $valid);
1495:     }
1496: 
1497:     /**
1498:      * Returns the valid flag
1499:      */
1500:     function getValid() {
1501:         return $this->get('valid');
1502:     }
1503: 
1504:     /**
1505:      * Sets the user's group.
1506:      * NOTE this does NOT set rights, etc. that must be done separately
1507:      */
1508:     function setGroup($group) {
1509:         $this->set('group', $group);
1510:     }
1511: 
1512:     /**
1513:      * Returns user's group
1514:      */
1515:     function getGroup() {
1516:         return $this->get('group');
1517:     }
1518: 
1519:     /**
1520:      * Sets the user's user id
1521:      */
1522:     function setUser($user) {
1523:         $this->set('user', $user);
1524:     }
1525: 
1526:     /**
1527:      * Returns user's user id
1528:      */
1529:     function getUser() {
1530:         return $this->get('user');
1531:     }
1532: 
1533:     /**
1534:      * Sets the users quota
1535:      */
1536:     function setQuota($v) {
1537:         $this->set('quota', $v);
1538:     }
1539: 
1540:     /**
1541:      * Returns the users quota
1542:      */
1543:     function getQuota() {
1544:         return $this->get('quota');
1545:     }
1546: 
1547:     /**
1548:      * Returns the user's prefered language
1549:      */
1550:     function getLanguage() {
1551:         return $this->get('language');
1552:     }
1553: 
1554:     /**
1555:      * Sets the user's preferec language
1556:      */
1557:     function setLanguage($locale) {
1558:         $this->set('language', $locale);
1559:     }
1560: 
1561:     /**
1562:      * Uptates the database with all changes
1563:      */
1564:     function save() {
1565:         global $_zp_gallery;
1566:         if (DEBUG_LOGIN) {
1567:             debugLogVar("Zenphoto_Administrator->save()", $this);
1568:         }
1569:         $objects = $this->getObjects();
1570:         if (is_null($this->get('date'))) {
1571:             $this->set('date', date('Y-m-d H:i:s'));
1572:         }
1573:         parent::save();
1574:         $id = $this->getID();
1575:         if (is_array($objects)) {
1576:             $sql = "DELETE FROM " . prefix('admin_to_object') . ' WHERE `adminid`=' . $id;
1577:             $result = query($sql, false);
1578:             foreach ($objects as $object) {
1579:                 if (array_key_exists('edit', $object)) {
1580:                     $edit = $object['edit'] | 32767 & ~(MANAGED_OBJECT_RIGHTS_EDIT | MANAGED_OBJECT_RIGHTS_UPLOAD | MANAGED_OBJECT_RIGHTS_VIEW);
1581:                 } else {
1582:                     $edit = 32767;
1583:                 }
1584:                 switch ($object['type']) {
1585:                     case 'album':
1586:                         $album = newAlbum($object['data']);
1587:                         $albumid = $album->getID();
1588:                         $sql = "INSERT INTO " . prefix('admin_to_object') . " (adminid, objectid, type, edit) VALUES ($id, $albumid, 'albums', $edit)";
1589:                         $result = query($sql);
1590:                         break;
1591:                     case 'pages':
1592:                         $sql = 'SELECT * FROM ' . prefix('pages') . ' WHERE `titlelink`=' . db_quote($object['data']);
1593:                         $result = query_single_row($sql);
1594:                         if (is_array($result)) {
1595:                             $objectid = $result['id'];
1596:                             $sql = "INSERT INTO " . prefix('admin_to_object') . " (adminid, objectid, type, edit) VALUES ($id, $objectid, 'pages', $edit)";
1597:                             $result = query($sql);
1598:                         }
1599:                         break;
1600:                     case 'news':
1601:                         $sql = 'SELECT * FROM ' . prefix('news_categories') . ' WHERE `titlelink`=' . db_quote($object['data']);
1602:                         $result = query_single_row($sql);
1603:                         if (is_array($result)) {
1604:                             $objectid = $result['id'];
1605:                             $sql = "INSERT INTO " . prefix('admin_to_object') . " (adminid, objectid, type, edit) VALUES ($id, $objectid, 'news', $edit)";
1606:                             $result = query($sql);
1607:                         }
1608:                         break;
1609:                 }
1610:             }
1611:         }
1612:     }
1613: 
1614:     /**
1615:      * Removes a user from the system
1616:      */
1617:     function remove() {
1618:         zp_apply_filter('remove_user', $this);
1619:         $album = $this->getAlbum();
1620:         $id = $this->getID();
1621:         if (parent::remove()) {
1622:             if (!empty($album)) { //    Remove users album as well
1623:                 $album->remove();
1624:             }
1625:             $sql = "DELETE FROM " . prefix('admin_to_object') . " WHERE `adminid`=$id";
1626:             $result = query($sql);
1627:         } else {
1628:             return false;
1629:         }
1630:         return $result;
1631:     }
1632: 
1633:     /**
1634:      * Returns the user's "prime" album. See setAlbum().
1635:      */
1636:     function getAlbum() {
1637:         $id = $this->get('prime_album');
1638:         if (!empty($id)) {
1639:             $sql = 'SELECT `folder` FROM ' . prefix('albums') . ' WHERE `id`=' . $id;
1640:             $result = query_single_row($sql);
1641:             if ($result) {
1642:                 $album = newAlbum($result['folder']);
1643:                 return $album;
1644:             }
1645:         }
1646:         return false;
1647:     }
1648: 
1649:     /**
1650:      * Records the "prime album" of a user. Prime albums are linked to the user and
1651:      * removed if the user is removed.
1652:      */
1653:     function setAlbum($album) {
1654:         if ($album) {
1655:             $this->set('prime_album', $album->getID());
1656:         } else {
1657:             $this->set('prime_album', NULL);
1658:         }
1659:     }
1660: 
1661:     /**
1662:      * Data to support other credential systems integration
1663:      */
1664:     function getCredentials() {
1665:         return getSerializedArray($this->get('other_credentials'));
1666:     }
1667: 
1668:     function setCredentials($cred) {
1669:         $this->set('other_credentials', serialize($cred));
1670:     }
1671: 
1672:     /**
1673:      * Creates a "prime" album for the user. Album name is based on the userid
1674:      */
1675:     function createPrimealbum($new = true, $name = NULL) {
1676:         //  create his album
1677:         $t = 0;
1678:         $ext = '';
1679:         if (is_null($name)) {
1680:             $filename = internalToFilesystem(str_replace(array('<', '>', ':', '"' . '/' . '\\', '|', '?', '*'), '_', seoFriendly($this->getUser())));
1681:         } else {
1682:             $filename = internalToFilesystem(str_replace(array('<', '>', ':', '"' . '/' . '\\', '|', '?', '*'), '_', $name));
1683:         }
1684:         while ($new && file_exists(ALBUM_FOLDER_SERVERPATH . $filename . $ext)) {
1685:             $t++;
1686:             $ext = '-' . $t;
1687:         }
1688:         $path = ALBUM_FOLDER_SERVERPATH . $filename . $ext;
1689:         $albumname = filesystemToInternal($filename . $ext);
1690:         if (@mkdir_recursive($path, FOLDER_MOD)) {
1691:             $album = newAlbum($albumname);
1692:             if ($title = $this->getName()) {
1693:                 $album->setTitle($title);
1694:             }
1695:             $album->save();
1696:             $this->setAlbum($album);
1697:             $this->setRights($this->getRights() | ALBUM_RIGHTS);
1698:             if (getOption('user_album_edit_default')) {
1699:                 $subrights = MANAGED_OBJECT_RIGHTS_EDIT;
1700:             } else {
1701:                 $subrights = 0;
1702:             }
1703:             if ($this->getRights() & UPLOAD_RIGHTS) {
1704:                 $subrights = $subrights | MANAGED_OBJECT_RIGHTS_UPLOAD;
1705:             }
1706:             $objects = $this->getObjects();
1707:             $objects[] = array('data' => $albumname, 'name' => $albumname, 'type' => 'album', 'edit' => $subrights);
1708:             $this->setObjects($objects);
1709:         }
1710:     }
1711: 
1712:     function getChallengePhraseInfo() {
1713:         $info = $this->get('challenge_phrase');
1714:         if ($info) {
1715:             return getSerializedArray($info);
1716:         } else {
1717:             return array('challenge' => '', 'response' => '');
1718:         }
1719:     }
1720: 
1721:     function setChallengePhraseInfo($challenge, $response) {
1722:         $this->set('challenge_phrase', serialize(array('challenge' => $challenge, 'response' => $response)));
1723:     }
1724: 
1725:     /**
1726:      *
1727:      * returns the last time the user has logged on
1728:      */
1729:     function getLastLogon() {
1730:         return $this->get('lastloggedin');
1731:     }
1732:     
1733:     /**
1734:      * Preserves the user's prime album as managed album even if he is in a group the album is actually set as managed
1735:      */
1736:     function preservePrimeAlbum() {
1737:         $primeAlbum = $this->getAlbum();
1738:         if (is_object($primeAlbum)) {
1739:             $primealbum_name = $primeAlbum->name;
1740:             $objects = $this->getObjects();
1741:             $primealbum_managed = false;
1742:             foreach ($objects as $key => $val) {
1743:                 if ($val['type'] == 'album' && $val['name'] == $primealbum_name) {
1744:                     $primealbum_managed = true;
1745:                     break;
1746:                 }
1747:             }
1748:             if (!$primealbum_managed) {
1749:                 $objects[] = array(
1750:                         'data' => $primealbum_name,
1751:                         'name' => $primealbum_name,
1752:                         'type' => 'album',
1753:                         'edit' => 32765
1754:                 );
1755:             }
1756:             $this->setObjects($objects);
1757:         }
1758:     }
1759: 
1760: }
1761: ?>
1762: 
Zenphoto doc API documentation generated by ApiGen