JOOMLA中国
  • Joomla中国首页
  • 社区
  • 教程
  • 应用市场
  • B计划
Joomla! Framework TM
  • Namespace
  • Class
  • Tree
  • Deprecated

Namespaces

  • Composer
    • Autoload
  • Joomla
    • Application
      • Cli
        • Output
          • Processor
      • Web
    • Data
    • DI
      • Exception
    • Event
    • Filter
    • Input
    • Ldap
    • Registry
      • Format
    • Session
      • Storage
    • String
    • Uri
    • Utilities
  • None
  • PasswordCompat
    • binary
  • PHP
  • Psr
    • Log
  • Symfony
    • Component
      • Yaml
        • Exception
    • Polyfill
      • Util

Classes

  • CallbackFilterIterator
  • ComposerAutoloaderInit205c915b9c7d3e718e7c95793ee67ffe
  • easyparse
  • EasyPeasyICS
  • FOFAutoloaderComponent
  • FOFAutoloaderFof
  • FOFConfigDomainDispatcher
  • FOFConfigDomainTables
  • FOFConfigDomainViews
  • FOFConfigProvider
  • FOFController
  • FOFDatabase
  • FOFDatabaseDriver
  • FOFDatabaseDriverJoomla
  • FOFDatabaseDriverMysql
  • FOFDatabaseDriverMysqli
  • FOFDatabaseDriverOracle
  • FOFDatabaseDriverPdo
  • FOFDatabaseDriverPdomysql
  • FOFDatabaseDriverPostgresql
  • FOFDatabaseDriverSqlazure
  • FOFDatabaseDriverSqlite
  • FOFDatabaseDriverSqlsrv
  • FOFDatabaseFactory
  • FOFDatabaseInstaller
  • FOFDatabaseIterator
  • FOFDatabaseIteratorAzure
  • FOFDatabaseIteratorMysql
  • FOFDatabaseIteratorMysqli
  • FOFDatabaseIteratorOracle
  • FOFDatabaseIteratorPdo
  • FOFDatabaseIteratorPdomysql
  • FOFDatabaseIteratorPostgresql
  • FOFDatabaseIteratorSqlite
  • FOFDatabaseIteratorSqlsrv
  • FOFDatabaseQuery
  • FOFDatabaseQueryElement
  • FOFDatabaseQueryMysql
  • FOFDatabaseQueryMysqli
  • FOFDatabaseQueryOracle
  • FOFDatabaseQueryPdo
  • FOFDatabaseQueryPdomysql
  • FOFDatabaseQueryPostgresql
  • FOFDatabaseQuerySqlazure
  • FOFDatabaseQuerySqlite
  • FOFDatabaseQuerySqlsrv
  • FOFDispatcher
  • FOFDownload
  • FOFDownloadAdapterAbstract
  • FOFDownloadAdapterCurl
  • FOFDownloadAdapterFopen
  • FOFEncryptAes
  • FOFEncryptAesAbstract
  • FOFEncryptAesMcrypt
  • FOFEncryptAesOpenssl
  • FOFEncryptBase32
  • FOFEncryptRandval
  • FOFEncryptTotp
  • FOFForm
  • FOFFormFieldAccesslevel
  • FOFFormFieldActions
  • FOFFormFieldButton
  • FOFFormFieldCachehandler
  • FOFFormFieldCalendar
  • FOFFormFieldCaptcha
  • FOFFormFieldCheckbox
  • FOFFormFieldCheckboxes
  • FOFFormFieldComponents
  • FOFFormFieldEditor
  • FOFFormFieldEmail
  • FOFFormFieldGroupedbutton
  • FOFFormFieldGroupedlist
  • FOFFormFieldHidden
  • FOFFormFieldImage
  • FOFFormFieldImagelist
  • FOFFormFieldInteger
  • FOFFormFieldLanguage
  • FOFFormFieldList
  • FOFFormFieldMedia
  • FOFFormFieldModel
  • FOFFormFieldOrdering
  • FOFFormFieldPassword
  • FOFFormFieldPlugins
  • FOFFormFieldPublished
  • FOFFormFieldRadio
  • FOFFormFieldRelation
  • FOFFormFieldRules
  • FOFFormFieldSelectrow
  • FOFFormFieldSessionhandler
  • FOFFormFieldSpacer
  • FOFFormFieldSql
  • FOFFormFieldTag
  • FOFFormFieldTel
  • FOFFormFieldText
  • FOFFormFieldTextarea
  • FOFFormFieldTimezone
  • FOFFormFieldTitle
  • FOFFormFieldUrl
  • FOFFormFieldUser
  • FOFFormFieldUsergroup
  • FOFFormHeader
  • FOFFormHeaderAccesslevel
  • FOFFormHeaderField
  • FOFFormHeaderFielddate
  • FOFFormHeaderFieldfilterable
  • FOFFormHeaderFieldsearchable
  • FOFFormHeaderFieldselectable
  • FOFFormHeaderFieldsql
  • FOFFormHeaderFilterdate
  • FOFFormHeaderFilterfilterable
  • FOFFormHeaderFiltersearchable
  • FOFFormHeaderFilterselectable
  • FOFFormHeaderFiltersql
  • FOFFormHeaderLanguage
  • FOFFormHeaderModel
  • FOFFormHeaderOrdering
  • FOFFormHeaderPublished
  • FOFFormHeaderRowselect
  • FOFFormHelper
  • FOFHalDocument
  • FOFHalLink
  • FOFHalLinks
  • FOFHalRenderJson
  • FOFInflector
  • FOFInput
  • FOFIntegrationJoomlaFilesystem
  • FOFIntegrationJoomlaPlatform
  • FOFLayoutFile
  • FOFLayoutHelper
  • FOFLess
  • FOFLessFormatterClassic
  • FOFLessFormatterCompressed
  • FOFLessFormatterJoomla
  • FOFLessFormatterLessjs
  • FOFLessParser
  • FOFModel
  • FOFModelBehavior
  • FOFModelBehaviorAccess
  • FOFModelBehaviorEmptynonzero
  • FOFModelBehaviorEnabled
  • FOFModelBehaviorFilters
  • FOFModelBehaviorLanguage
  • FOFModelBehaviorPrivate
  • FOFModelDispatcherBehavior
  • FOFModelField
  • FOFModelFieldBoolean
  • FOFModelFieldDate
  • FOFModelFieldNumber
  • FOFModelFieldText
  • FOFPlatform
  • FOFPlatformFilesystem
  • FOFQueryAbstract
  • FOFRenderAbstract
  • FOFRenderJoomla
  • FOFRenderJoomla3
  • FOFRenderStrapper
  • FOFStringUtils
  • FOFTable
  • FOFTableBehavior
  • FOFTableBehaviorAssets
  • FOFTableBehaviorContenthistory
  • FOFTableBehaviorTags
  • FOFTableDispatcherBehavior
  • FOFTableNested
  • FOFTableRelations
  • FOFTemplateUtils
  • FOFToolbar
  • FOFUtilsArray
  • FOFUtilsCacheCleaner
  • FOFUtilsConfigHelper
  • FOFUtilsFilescheck
  • FOFUtilsIniParser
  • FOFUtilsInstallscript
  • FOFUtilsIp
  • FOFUtilsObject
  • FOFUtilsObservableDispatcher
  • FOFUtilsObservableEvent
  • FOFUtilsPhpfunc
  • FOFUtilsTimer
  • FOFUtilsUpdate
  • FOFUtilsUpdateCollection
  • FOFUtilsUpdateExtension
  • FOFUtilsUpdateJoomla
  • FOFView
  • FOFViewCsv
  • FOFViewForm
  • FOFViewHtml
  • FOFViewJson
  • FOFViewRaw
  • idna_convert
  • JAccess
  • JAccessRule
  • JAccessRules
  • JAccessWrapperAccess
  • JAdapter
  • JAdapterInstance
  • JApplication
  • JApplicationAdministrator
  • JApplicationBase
  • JApplicationCli
  • JApplicationCms
  • JApplicationDaemon
  • JApplicationHelper
  • JApplicationSite
  • JApplicationWeb
  • JApplicationWebRouter
  • JApplicationWebRouterBase
  • JApplicationWebRouterRest
  • JArchive
  • JArchiveBzip2
  • JArchiveGzip
  • JArchiveTar
  • JArchiveWrapperArchive
  • JArchiveZip
  • JArrayHelper
  • JAssociationExtensionHelper
  • JAuthentication
  • JAuthenticationHelper
  • JAuthenticationResponse
  • JBrowser
  • JBuffer
  • JButton
  • JCache
  • JCacheController
  • JCacheControllerCallback
  • JCacheControllerOutput
  • JCacheControllerPage
  • JCacheControllerView
  • JCacheStorage
  • JCacheStorageApc
  • JCacheStorageApcu
  • JCacheStorageCachelite
  • JCacheStorageFile
  • JCacheStorageHelper
  • JCacheStorageMemcache
  • JCacheStorageMemcached
  • JCacheStorageRedis
  • JCacheStorageWincache
  • JCacheStorageXcache
  • JCaptcha
  • JCategories
  • JCategoryNode
  • JClassLoader
  • JCli
  • JClientFtp
  • JClientHelper
  • JClientLdap
  • JClientWrapperHelper
  • JComponentHelper
  • JComponentRecord
  • JComponentRouterBase
  • JComponentRouterLegacy
  • JComponentRouterRulesMenu
  • JComponentRouterRulesNomenu
  • JComponentRouterRulesStandard
  • JComponentRouterView
  • JComponentRouterViewconfiguration
  • JControllerAdmin
  • JControllerBase
  • JControllerForm
  • JControllerLegacy
  • JCrypt
  • JCryptCipher3Des
  • JCryptCipherBlowfish
  • JCryptCipherCrypto
  • JCryptCipherMcrypt
  • JCryptCipherRijndael256
  • JCryptCipherSimple
  • JCryptKey
  • JCryptPasswordSimple
  • JDaemon
  • JDatabase
  • JDatabaseDriver
  • JDatabaseDriverMysql
  • JDatabaseDriverMysqli
  • JDatabaseDriverOracle
  • JDatabaseDriverPdo
  • JDatabaseDriverPdomysql
  • JDatabaseDriverPostgresql
  • JDatabaseDriverSqlazure
  • JDatabaseDriverSqlite
  • JDatabaseDriverSqlsrv
  • JDatabaseExporter
  • JDatabaseExporterMysql
  • JDatabaseExporterMysqli
  • JDatabaseExporterPdomysql
  • JDatabaseExporterPostgresql
  • JDatabaseFactory
  • JDatabaseImporter
  • JDatabaseImporterMysql
  • JDatabaseImporterMysqli
  • JDatabaseImporterPdomysql
  • JDatabaseImporterPostgresql
  • JDatabaseInterface
  • JDatabaseIterator
  • JDatabaseIteratorMysql
  • JDatabaseIteratorMysqli
  • JDatabaseIteratorOracle
  • JDatabaseIteratorPdo
  • JDatabaseIteratorPdomysql
  • JDatabaseIteratorPostgresql
  • JDatabaseIteratorSqlazure
  • JDatabaseIteratorSqlite
  • JDatabaseIteratorSqlsrv
  • JDatabaseMysql
  • JDatabaseMysqli
  • JDatabaseQuery
  • JDatabaseQueryElement
  • JDatabaseQueryLimitable
  • JDatabaseQueryMysql
  • JDatabaseQueryMysqli
  • JDatabaseQueryOracle
  • JDatabaseQueryPdo
  • JDatabaseQueryPdomysql
  • JDatabaseQueryPostgresql
  • JDatabaseQueryPreparable
  • JDatabaseQuerySqlazure
  • JDatabaseQuerySqlite
  • JDatabaseQuerySqlsrv
  • JDatabaseSqlazure
  • JDatabaseSqlsrv
  • JDate
  • JDispatcher
  • JDocument
  • JDocumentError
  • JDocumentFeed
  • JDocumentHtml
  • JDocumentImage
  • JDocumentJson
  • JDocumentOpensearch
  • JDocumentRaw
  • JDocumentRenderer
  • JDocumentRendererAtom
  • JDocumentRendererComponent
  • JDocumentRendererFeedAtom
  • JDocumentRendererFeedRss
  • JDocumentRendererHead
  • JDocumentRendererHtmlComponent
  • JDocumentRendererHtmlHead
  • JDocumentRendererHtmlMessage
  • JDocumentRendererHtmlModule
  • JDocumentRendererHtmlModules
  • JDocumentRendererMessage
  • JDocumentRendererModule
  • JDocumentRendererModules
  • JDocumentRendererRSS
  • JDocumentXml
  • JEditor
  • JError
  • JErrorPage
  • JEvent
  • JEventDispatcher
  • JExtension
  • JFacebook
  • JFacebookAlbum
  • JFacebookCheckin
  • JFacebookComment
  • JFacebookEvent
  • JFacebookGroup
  • JFacebookLink
  • JFacebookNote
  • JFacebookOAuth
  • JFacebookObject
  • JFacebookPhoto
  • JFacebookPost
  • JFacebookStatus
  • JFacebookUser
  • JFacebookVideo
  • JFactory
  • JFeed
  • JFeedEnclosure
  • JFeedEntry
  • JFeedFactory
  • JFeedImage
  • JFeedItem
  • JFeedLink
  • JFeedParser
  • JFeedParserAtom
  • JFeedParserRss
  • JFeedParserRssItunes
  • JFeedParserRssMedia
  • JFeedPerson
  • JFile
  • JFilesystemHelper
  • JFilesystemPatcher
  • JFilesystemWrapperFile
  • JFilesystemWrapperFolder
  • JFilesystemWrapperPath
  • JFilterInput
  • JFilterOutput
  • JFilterWrapperOutput
  • JFolder
  • JForm
  • JFormField
  • JFormFieldAccessLevel
  • JFormFieldAliastag
  • JFormFieldAuthor
  • JFormFieldCacheHandler
  • JFormFieldCalendar
  • JFormFieldCaptcha
  • JFormFieldCategory
  • JFormFieldCheckbox
  • JFormFieldCheckboxes
  • JFormFieldChromeStyle
  • JFormFieldColor
  • JFormFieldCombo
  • JFormFieldComponentlayout
  • JFormFieldComponents
  • JFormFieldContenthistory
  • JFormFieldContentlanguage
  • JFormFieldContenttype
  • JFormFieldDatabaseConnection
  • JFormFieldEditor
  • JFormFieldEMail
  • JFormFieldFile
  • JFormFieldFileList
  • JFormFieldFolderList
  • JFormFieldFrontend_Language
  • JFormFieldGroupedList
  • JFormFieldHeadertag
  • JFormFieldHelpsite
  • JFormFieldHidden
  • JFormFieldImageList
  • JFormFieldInteger
  • JFormFieldLanguage
  • JFormFieldLastvisitDateRange
  • JFormFieldLimitbox
  • JFormFieldList
  • JFormFieldMedia
  • JFormFieldMenu
  • JFormFieldMenuitem
  • JFormFieldMeter
  • JFormFieldModulelayout
  • JFormFieldModuleOrder
  • JFormFieldModulePosition
  • JFormFieldModuletag
  • JFormFieldNote
  • JFormFieldNumber
  • JFormFieldOrdering
  • JFormFieldPassword
  • JFormFieldPlugin_Status
  • JFormFieldPlugins
  • JFormFieldPredefinedList
  • JFormFieldRadio
  • JFormFieldRange
  • JFormFieldRegistrationDateRange
  • JFormFieldRepeatable
  • JFormFieldRules
  • JFormFieldSessionHandler
  • JFormFieldSpacer
  • JFormFieldSQL
  • JFormFieldStatus
  • JFormFieldSubform
  • JFormFieldTag
  • JFormFieldTel
  • JFormFieldTemplatestyle
  • JFormFieldText
  • JFormFieldTextarea
  • JFormFieldTimezone
  • JFormFieldUrl
  • JFormFieldUser
  • JFormFieldUserActive
  • JFormFieldUsergroup
  • JFormFieldUserGroupList
  • JFormFieldUserState
  • JFormHelper
  • JFormRule
  • JFormRuleBoolean
  • JFormRuleCalendar
  • JFormRuleCaptcha
  • JFormRuleColor
  • JFormRuleEmail
  • JFormRuleEquals
  • JFormRuleNotequals
  • JFormRuleNumber
  • JFormRuleOptions
  • JFormRulePassword
  • JFormRuleRules
  • JFormRuleTel
  • JFormRuleUrl
  • JFormRuleUsername
  • JFormWrapperHelper
  • JFTP
  • JGithub
  • JGithubAccount
  • JGithubCommits
  • JGithubForks
  • JGithubHooks
  • JGithubHttp
  • JGithubMeta
  • JGithubMilestones
  • JGithubObject
  • JGithubPackage
  • JGithubPackageActivity
  • JGithubPackageActivityEvents
  • JGithubPackageActivityNotifications
  • JGithubPackageActivityStarring
  • JGithubPackageActivityWatching
  • JGithubPackageAuthorization
  • JGithubPackageData
  • JGithubPackageDataBlobs
  • JGithubPackageDataCommits
  • JGithubPackageDataRefs
  • JGithubPackageDataTags
  • JGithubPackageDataTrees
  • JGithubPackageGists
  • JGithubPackageGistsComments
  • JGithubPackageGitignore
  • JGithubPackageIssues
  • JGithubPackageIssuesAssignees
  • JGithubPackageIssuesComments
  • JGithubPackageIssuesEvents
  • JGithubPackageIssuesLabels
  • JGithubPackageIssuesMilestones
  • JGithubPackageMarkdown
  • JGithubPackageOrgs
  • JGithubPackageOrgsMembers
  • JGithubPackageOrgsTeams
  • JGithubPackagePulls
  • JGithubPackagePullsComments
  • JGithubPackageRepositories
  • JGithubPackageRepositoriesCollaborators
  • JGithubPackageRepositoriesComments
  • JGithubPackageRepositoriesCommits
  • JGithubPackageRepositoriesContents
  • JGithubPackageRepositoriesDownloads
  • JGithubPackageRepositoriesForks
  • JGithubPackageRepositoriesHooks
  • JGithubPackageRepositoriesKeys
  • JGithubPackageRepositoriesMerging
  • JGithubPackageRepositoriesStatistics
  • JGithubPackageRepositoriesStatuses
  • JGithubPackageSearch
  • JGithubPackageUsers
  • JGithubPackageUsersEmails
  • JGithubPackageUsersFollowers
  • JGithubPackageUsersKeys
  • JGithubRefs
  • JGithubStatuses
  • JGoogle
  • JGoogleAuth
  • JGoogleAuthOauth2
  • JGoogleData
  • JGoogleDataAdsense
  • JGoogleDataCalendar
  • JGoogleDataPicasa
  • JGoogleDataPicasaAlbum
  • JGoogleDataPicasaPhoto
  • JGoogleDataPlus
  • JGoogleDataPlusActivities
  • JGoogleDataPlusComments
  • JGoogleDataPlusPeople
  • JGoogleEmbed
  • JGoogleEmbedAnalytics
  • JGoogleEmbedMaps
  • JGrid
  • JHelp
  • JHelper
  • JHelperContent
  • JHelperContenthistory
  • JHelperMedia
  • JHelperRoute
  • JHelperTags
  • JHelperUsergroups
  • JHtml
  • JHtmlAccess
  • JHtmlActionsDropdown
  • JHtmlBatch
  • JHtmlBehavior
  • JHtmlBootstrap
  • JHtmlCategory
  • JHtmlContent
  • JHtmlContentLanguage
  • JHtmlDate
  • JHtmlDebug
  • JHtmlDropdown
  • JHtmlEmail
  • JHtmlForm
  • JHtmlFormbehavior
  • JHtmlGrid
  • JHtmlIcons
  • JHtmlJGrid
  • JHtmlJquery
  • JHtmlLinks
  • JHtmlList
  • JHtmlMenu
  • JHtmlNumber
  • JHtmlRules
  • JHtmlSearchtools
  • JHtmlSelect
  • JHtmlSidebar
  • JHtmlSliders
  • JHtmlSortablelist
  • JHtmlString
  • JHtmlTabs
  • JHtmlTag
  • JHtmlTel
  • JHtmlUser
  • JHttp
  • JHttpFactory
  • JHttpResponse
  • JHttpTransportCurl
  • JHttpTransportSocket
  • JHttpTransportStream
  • JHttpWrapperFactory
  • JImage
  • JImageFilter
  • JImageFilterBackgroundfill
  • JImageFilterBrightness
  • JImageFilterContrast
  • JImageFilterEdgedetect
  • JImageFilterEmboss
  • JImageFilterGrayscale
  • JImageFilterNegate
  • JImageFilterSketchy
  • JImageFilterSmooth
  • JInput
  • JInputCli
  • JInputCookie
  • JInputFiles
  • JInputJSON
  • JInstaller
  • JInstallerAdapter
  • JInstallerAdapterComponent
  • JInstallerAdapterFile
  • JInstallerAdapterLanguage
  • JInstallerAdapterLibrary
  • JInstallerAdapterModule
  • JInstallerAdapterPackage
  • JInstallerAdapterPlugin
  • JInstallerAdapterTemplate
  • JInstallerComponent
  • JInstallerExtension
  • JInstallerFile
  • JInstallerHelper
  • JInstallerLanguage
  • JInstallerLibrary
  • JInstallerManifest
  • JInstallerManifestLibrary
  • JInstallerManifestPackage
  • JInstallerModule
  • JInstallerPackage
  • JInstallerPlugin
  • JInstallerScript
  • JInstallerTemplate
  • JKeychain
  • JLanguage
  • JLanguageAssociations
  • JLanguageHelper
  • JLanguageMultilang
  • JLanguageStemmer
  • JLanguageStemmerPorteren
  • JLanguageTransliterate
  • JLanguageWrapperHelper
  • JLanguageWrapperText
  • JLanguageWrapperTransliterate
  • JLayoutBase
  • JLayoutFile
  • JLayoutHelper
  • JLDAP
  • JLess
  • JLessFormatterJoomla
  • JLibraryHelper
  • JLinkedin
  • JLinkedinCommunications
  • JLinkedinCompanies
  • JLinkedinGroups
  • JLinkedinJobs
  • JLinkedinOauth
  • JLinkedinObject
  • JLinkedinPeople
  • JLinkedinStream
  • JLoader
  • JLog
  • JLogEntry
  • JLogger
  • JLogLogger
  • JLogLoggerCallback
  • JLogLoggerDatabase
  • JLogLoggerEcho
  • JLogLoggerFormattedtext
  • JLogLoggerMessagequeue
  • JLogLoggerSyslog
  • JLogLoggerW3c
  • JMail
  • JMailHelper
  • JMailWrapperHelper
  • JMediawiki
  • JMediawikiCategories
  • JMediawikiHttp
  • JMediawikiImages
  • JMediawikiLinks
  • JMediawikiObject
  • JMediawikiPages
  • JMediawikiSearch
  • JMediawikiSites
  • JMediawikiUsers
  • JMenu
  • JMenuAdministrator
  • JMenuItem
  • JMenuSite
  • JMicrodata
  • JModelAdmin
  • JModelBase
  • JModelDatabase
  • JModelForm
  • JModelItem
  • JModelLegacy
  • JModelList
  • JModuleHelper
  • JNode
  • JOAuth1Client
  • JOAuth2Client
  • JObject
  • JObservable
  • JObserver
  • JObserverMapper
  • JObserverUpdater
  • JObserverWrapperMapper
  • JOpenSearchImage
  • JOpenSearchUrl
  • JOpenstreetmap
  • JOpenstreetmapChangesets
  • JOpenstreetmapElements
  • JOpenstreetmapGps
  • JOpenstreetmapInfo
  • JOpenstreetmapOauth
  • JOpenstreetmapObject
  • JOpenstreetmapUser
  • JPagination
  • JPaginationObject
  • JPath
  • JPathway
  • JPathwaySite
  • JPlatform
  • JPlugin
  • JPluginHelper
  • JProfiler
  • JRequest
  • JResponse
  • JResponseJson
  • JRoute
  • JRouter
  • JRouterAdministrator
  • JRouterSite
  • JRouteWrapperRoute
  • JRule
  • JRules
  • JSchemaChangeitem
  • JSchemaChangeitemMysql
  • JSchemaChangeitemPostgresql
  • JSchemaChangeitemSqlsrv
  • JSchemaChangeset
  • JSearchHelper
  • JSession
  • JSessionHandlerJoomla
  • JSessionHandlerNative
  • JSessionStorage
  • JSessionStorageApc
  • JSessionStorageDatabase
  • JSessionStorageMemcache
  • JSessionStorageMemcached
  • JSessionStorageNone
  • JSessionStorageWincache
  • JSessionStorageXcache
  • JSimplecrypt
  • JSimplepieFactory
  • JStream
  • JStreamString
  • JString
  • JStringController
  • JStringPunycode
  • JStringWrapperNormalise
  • JStringWrapperPunycode
  • JTable
  • JTableAsset
  • JTableCategory
  • JTableContent
  • JTableContenthistory
  • JTableContenttype
  • JTableCorecontent
  • JTableExtension
  • JTableInterface
  • JTableLanguage
  • JTableMenu
  • JTableMenuType
  • JTableModule
  • JTableNested
  • JTableObserver
  • JTableObserverContenthistory
  • JTableObserverTags
  • JTableSession
  • JTableUcm
  • JTableUpdate
  • JTableUpdatesite
  • JTableUser
  • JTableUsergroup
  • JTableViewlevel
  • JText
  • JToolbar
  • JToolbarButton
  • JToolbarButtonConfirm
  • JToolbarButtonCustom
  • JToolbarButtonHelp
  • JToolbarButtonLink
  • JToolbarButtonPopup
  • JToolbarButtonSeparator
  • JToolbarButtonSlider
  • JToolbarButtonStandard
  • JTree
  • JTwitter
  • JTwitterBlock
  • JTwitterDirectmessages
  • JTwitterFavorites
  • JTwitterFriends
  • JTwitterHelp
  • JTwitterLists
  • JTwitterOAuth
  • JTwitterObject
  • JTwitterPlaces
  • JTwitterProfile
  • JTwittersearch
  • JTwitterStatuses
  • JTwitterTrends
  • JTwitterUsers
  • JUcmBase
  • JUcmContent
  • JUcmType
  • JUpdate
  • JUpdateAdapter
  • JUpdater
  • JUpdaterCollection
  • JUpdaterExtension
  • JUri
  • JUser
  • JUserHelper
  • JUserWrapperHelper
  • JUtility
  • JVersion
  • JViewBase
  • JViewCategories
  • JViewCategory
  • JViewCategoryfeed
  • JViewHtml
  • JViewLegacy
  • JWeb
  • JWebClient
  • JXMLElement
  • lessc
  • lessc_formatter_classic
  • lessc_formatter_compressed
  • lessc_formatter_lessjs
  • lessc_parser
  • lessify
  • Net_IDNA_php4
  • nodecounter
  • ntlm_sasl_client_class
  • PHPMailer
  • PHPMailerOAuth
  • PHPMailerOAuthGoogle
  • POP3
  • SimplePie
  • SimplePie_Author
  • SimplePie_Autoloader
  • SimplePie_Cache
  • SimplePie_Cache_DB
  • SimplePie_Cache_File
  • SimplePie_Cache_Memcache
  • SimplePie_Cache_MySQL
  • SimplePie_Caption
  • SimplePie_Category
  • SimplePie_Content_Type_Sniffer
  • SimplePie_Copyright
  • SimplePie_Core
  • SimplePie_Credit
  • SimplePie_Decode_HTML_Entities
  • SimplePie_Enclosure
  • SimplePie_File
  • SimplePie_gzdecode
  • SimplePie_HTTP_Parser
  • SimplePie_IRI
  • SimplePie_Item
  • SimplePie_Locator
  • SimplePie_Misc
  • SimplePie_Net_IPv6
  • SimplePie_Parse_Date
  • SimplePie_Parser
  • SimplePie_Rating
  • SimplePie_Registry
  • SimplePie_Restriction
  • SimplePie_Sanitize
  • SimplePie_Source
  • SimplePie_XML_Declaration_Parser
  • SMTP
  • tagparse
  • TypeError

Interfaces

  • FOFConfigDomainInterface
  • FOFDatabaseInterface
  • FOFDatabaseQueryLimitable
  • FOFDatabaseQueryPreparable
  • FOFDownloadInterface
  • FOFEncryptAesInterface
  • FOFEncryptRandvalinterface
  • FOFFormField
  • FOFHalRenderInterface
  • FOFPlatformFilesystemInterface
  • FOFPlatformInterface
  • JArchiveExtractable
  • JAssociationExtensionInterface
  • JCacheException
  • JComponentRouterInterface
  • JComponentRouterRulesInterface
  • JController
  • JCryptCipher
  • JCryptPassword
  • JFeedParserNamespace
  • JHttpTransport
  • JLayout
  • JModel
  • JObservableInterface
  • JObserverInterface
  • JObserverUpdaterInterface
  • JSessionHandlerInterface
  • JsonSerializable
  • JUcm
  • JView
  • SimplePie_Cache_Base

Exceptions

  • Error
  • JAccessExceptionNotallowed
  • JCacheExceptionConnecting
  • JCacheExceptionUnsupported
  • JComponentExceptionMissing
  • JDatabaseException
  • JDatabaseExceptionConnecting
  • JDatabaseExceptionExecuting
  • JDatabaseExceptionUnsupported
  • JException
  • JSessionExceptionUnsupported
  • LogException
  • phpmailerException
  • SimplePie_Exception

Constants

  • JERROR_CALLBACK_NOT_CALLABLE
  • JERROR_ILLEGAL_MODE
  • JERROR_ILLEGAL_OPTIONS
  • JREQUEST_ALLOWHTML
  • JREQUEST_ALLOWRAW
  • JREQUEST_NOTRIM
  • JROUTER_MODE_RAW
  • JROUTER_MODE_SEF

Functions

  • __autoload
  • array_column
  • boolval
  • composerRequire205c915b9c7d3e718e7c95793ee67ffe
  • gzopen
  • gzseek
  • gztell
  • hash_equals
  • hash_pbkdf2
  • HTMLFilter
  • jexit
  • jimport
  • json_last_error_msg
  • ldap_escape
  • password_get_info
  • password_hash
  • password_needs_rehash
  • password_verify
  • PHPMailerAutoload
  • random_bytes
  • random_int
  • RandomCompat_intval
  • RandomCompat_strlen
  • RandomCompat_substr
  • tln_body2div
  • tln_casenormalize
  • tln_deent
  • tln_defang
  • tln_findnxreg
  • tln_findnxstr
  • tln_fixatts
  • tln_fixstyle
  • tln_fixurl
  • tln_getnxtag
  • tln_sanitize
  • tln_skipspace
  • tln_tagprint
  • tln_unspace
  • utf8_accents_to_ascii
  • utf8_bad_explain
  • utf8_bad_find
  • utf8_bad_findall
  • utf8_bad_identify
  • utf8_bad_replace
  • utf8_bad_strip
  • utf8_byte_position
  • utf8_compliant
  • utf8_from_unicode
  • utf8_ireplace
  • utf8_is_ascii
  • utf8_is_ascii_ctrl
  • utf8_is_valid
  • utf8_is_word_chars
  • utf8_locate_current_chr
  • utf8_locate_next_chr
  • utf8_ltrim
  • utf8_ord
  • utf8_rtrim
  • utf8_specials_pattern
  • utf8_str_pad
  • utf8_str_split
  • utf8_strcasecmp
  • utf8_strcspn
  • utf8_strip_ascii_ctrl
  • utf8_strip_non_ascii
  • utf8_strip_non_ascii_ctrl
  • utf8_strip_specials
  • utf8_stristr
  • utf8_strlen
  • utf8_strpos
  • utf8_strrev
  • utf8_strrpos
  • utf8_strspn
  • utf8_strtolower
  • utf8_strtoupper
  • utf8_substr
  • utf8_substr_replace
  • utf8_to_unicode
  • utf8_trim
  • utf8_ucfirst
  • utf8_ucwords
  • utf8_ucwords_callback
   1 <?php
   2 /**
   3  * @package     Joomla.Platform
   4  * @subpackage  Table
   5  *
   6  * @copyright   Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved.
   7  * @license     GNU General Public License version 2 or later; see LICENSE
   8  */
   9 
  10 defined('JPATH_PLATFORM') or die;
  11 
  12 jimport('joomla.filesystem.path');
  13 
  14 /**
  15  * Abstract Table class
  16  *
  17  * Parent class to all tables.
  18  *
  19  * @since  11.1
  20  * @tutorial  Joomla.Platform/jtable.cls
  21  */
  22 abstract class JTable extends JObject implements JObservableInterface, JTableInterface
  23 {
  24     /**
  25      * Include paths for searching for JTable classes.
  26      *
  27      * @var    array
  28      * @since  12.1
  29      */
  30     private static $_includePaths = array();
  31 
  32     /**
  33      * Name of the database table to model.
  34      *
  35      * @var    string
  36      * @since  11.1
  37      */
  38     protected $_tbl = '';
  39 
  40     /**
  41      * Name of the primary key field in the table.
  42      *
  43      * @var    string
  44      * @since  11.1
  45      */
  46     protected $_tbl_key = '';
  47 
  48     /**
  49      * Name of the primary key fields in the table.
  50      *
  51      * @var    array
  52      * @since  12.2
  53      */
  54     protected $_tbl_keys = array();
  55 
  56     /**
  57      * JDatabaseDriver object.
  58      *
  59      * @var    JDatabaseDriver
  60      * @since  11.1
  61      */
  62     protected $_db;
  63 
  64     /**
  65      * Should rows be tracked as ACL assets?
  66      *
  67      * @var    boolean
  68      * @since  11.1
  69      */
  70     protected $_trackAssets = false;
  71 
  72     /**
  73      * The rules associated with this record.
  74      *
  75      * @var    JAccessRules  A JAccessRules object.
  76      * @since  11.1
  77      */
  78     protected $_rules;
  79 
  80     /**
  81      * Indicator that the tables have been locked.
  82      *
  83      * @var    boolean
  84      * @since  11.1
  85      */
  86     protected $_locked = false;
  87 
  88     /**
  89      * Indicates that the primary keys autoincrement.
  90      *
  91      * @var    boolean
  92      * @since  12.3
  93      */
  94     protected $_autoincrement = true;
  95 
  96     /**
  97      * Generic observers for this JTable (Used e.g. for tags Processing)
  98      *
  99      * @var    JObserverUpdater
 100      * @since  3.1.2
 101      */
 102     protected $_observers;
 103 
 104     /**
 105      * Array with alias for "special" columns such as ordering, hits etc etc
 106      *
 107      * @var    array
 108      * @since  3.4.0
 109      */
 110     protected $_columnAlias = array();
 111 
 112     /**
 113      * An array of key names to be json encoded in the bind function
 114      *
 115      * @var    array
 116      * @since  3.3
 117      */
 118     protected $_jsonEncode = array();
 119 
 120     /**
 121      * Object constructor to set table and key fields.  In most cases this will
 122      * be overridden by child classes to explicitly set the table and key fields
 123      * for a particular database table.
 124      *
 125      * @param   string           $table  Name of the table to model.
 126      * @param   mixed            $key    Name of the primary key field in the table or array of field names that compose the primary key.
 127      * @param   JDatabaseDriver  $db     JDatabaseDriver object.
 128      *
 129      * @since   11.1
 130      */
 131     public function __construct($table, $key, $db)
 132     {
 133         // Set internal variables.
 134         $this->_tbl = $table;
 135 
 136         // Set the key to be an array.
 137         if (is_string($key))
 138         {
 139             $key = array($key);
 140         }
 141         elseif (is_object($key))
 142         {
 143             $key = (array) $key;
 144         }
 145 
 146         $this->_tbl_keys = $key;
 147 
 148         if (count($key) == 1)
 149         {
 150             $this->_autoincrement = true;
 151         }
 152         else
 153         {
 154             $this->_autoincrement = false;
 155         }
 156 
 157         // Set the singular table key for backwards compatibility.
 158         $this->_tbl_key = $this->getKeyName();
 159 
 160         $this->_db = $db;
 161 
 162         // Initialise the table properties.
 163         $fields = $this->getFields();
 164 
 165         if ($fields)
 166         {
 167             foreach ($fields as $name => $v)
 168             {
 169                 // Add the field if it is not already present.
 170                 if (!property_exists($this, $name))
 171                 {
 172                     $this->$name = null;
 173                 }
 174             }
 175         }
 176 
 177         // If we are tracking assets, make sure an access field exists and initially set the default.
 178         if (property_exists($this, 'asset_id'))
 179         {
 180             $this->_trackAssets = true;
 181         }
 182 
 183         // If the access property exists, set the default.
 184         if (property_exists($this, 'access'))
 185         {
 186             $this->access = (int) JFactory::getConfig()->get('access');
 187         }
 188 
 189         // Implement JObservableInterface:
 190         // Create observer updater and attaches all observers interested by $this class:
 191         $this->_observers = new JObserverUpdater($this);
 192         JObserverMapper::attachAllObservers($this);
 193     }
 194 
 195     /**
 196      * Implement JObservableInterface:
 197      * Adds an observer to this instance.
 198      * This method will be called fron the constructor of classes implementing JObserverInterface
 199      * which is instanciated by the constructor of $this with JObserverMapper::attachAllObservers($this)
 200      *
 201      * @param   JObserverInterface|JTableObserver  $observer  The observer object
 202      *
 203      * @return  void
 204      *
 205      * @since   3.1.2
 206      */
 207     public function attachObserver(JObserverInterface $observer)
 208     {
 209         $this->_observers->attachObserver($observer);
 210     }
 211 
 212     /**
 213      * Gets the instance of the observer of class $observerClass
 214      *
 215      * @param   string  $observerClass  The observer class-name to return the object of
 216      *
 217      * @return  JTableObserver|null
 218      *
 219      * @since   3.1.2
 220      */
 221     public function getObserverOfClass($observerClass)
 222     {
 223         return $this->_observers->getObserverOfClass($observerClass);
 224     }
 225 
 226     /**
 227      * Get the columns from database table.
 228      *
 229      * @param   bool  $reload  flag to reload cache
 230      *
 231      * @return  mixed  An array of the field names, or false if an error occurs.
 232      *
 233      * @since   11.1
 234      * @throws  UnexpectedValueException
 235      */
 236     public function getFields($reload = false)
 237     {
 238         static $cache = null;
 239 
 240         if ($cache === null || $reload)
 241         {
 242             // Lookup the fields for this table only once.
 243             $name   = $this->_tbl;
 244             $fields = $this->_db->getTableColumns($name, false);
 245 
 246             if (empty($fields))
 247             {
 248                 throw new UnexpectedValueException(sprintf('No columns found for %s table', $name));
 249             }
 250 
 251             $cache = $fields;
 252         }
 253 
 254         return $cache;
 255     }
 256 
 257     /**
 258      * Static method to get an instance of a JTable class if it can be found in the table include paths.
 259      *
 260      * To add include paths for searching for JTable classes see JTable::addIncludePath().
 261      *
 262      * @param   string  $type    The type (name) of the JTable class to get an instance of.
 263      * @param   string  $prefix  An optional prefix for the table class name.
 264      * @param   array   $config  An optional array of configuration values for the JTable object.
 265      *
 266      * @return  JTable|boolean   A JTable object if found or boolean false on failure.
 267      *
 268      * @since   11.1
 269      */
 270     public static function getInstance($type, $prefix = 'JTable', $config = array())
 271     {
 272         // Sanitize and prepare the table class name.
 273         $type       = preg_replace('/[^A-Z0-9_\.-]/i', '', $type);
 274         $tableClass = $prefix . ucfirst($type);
 275 
 276         // Only try to load the class if it doesn't already exist.
 277         if (!class_exists($tableClass))
 278         {
 279             // Search for the class file in the JTable include paths.
 280             jimport('joomla.filesystem.path');
 281 
 282             $paths = self::addIncludePath();
 283             $pathIndex = 0;
 284 
 285             while (!class_exists($tableClass) && $pathIndex < count($paths))
 286             {
 287                 if ($tryThis = JPath::find($paths[$pathIndex++], strtolower($type) . '.php'))
 288                 {
 289                     // Import the class file.
 290                     include_once $tryThis;
 291                 }
 292             }
 293 
 294             if (!class_exists($tableClass))
 295             {
 296                 /*
 297                 * If unable to find the class file in the JTable include paths. Return false.
 298                 * The warning JLIB_DATABASE_ERROR_NOT_SUPPORTED_FILE_NOT_FOUND has been removed in 3.6.3.
 299                 * In 4.0 an Exception (type to be determined) will be thrown.
 300                 * For more info see https://github.com/joomla/joomla-cms/issues/11570
 301                 */
 302 
 303                 return false;
 304             }
 305         }
 306 
 307         // If a database object was passed in the configuration array use it, otherwise get the global one from JFactory.
 308         $db = isset($config['dbo']) ? $config['dbo'] : JFactory::getDbo();
 309 
 310         // Instantiate a new table class and return it.
 311         return new $tableClass($db);
 312     }
 313 
 314     /**
 315      * Add a filesystem path where JTable should search for table class files.
 316      *
 317      * @param   array|string  $path  A filesystem path or array of filesystem paths to add.
 318      *
 319      * @return  array  An array of filesystem paths to find JTable classes in.
 320      *
 321      * @since   11.1
 322      */
 323     public static function addIncludePath($path = null)
 324     {
 325         // If the internal paths have not been initialised, do so with the base table path.
 326         if (empty(self::$_includePaths))
 327         {
 328             self::$_includePaths = array(__DIR__);
 329         }
 330 
 331         // Convert the passed path(s) to add to an array.
 332         settype($path, 'array');
 333 
 334         // If we have new paths to add, do so.
 335         if (!empty($path))
 336         {
 337             // Check and add each individual new path.
 338             foreach ($path as $dir)
 339             {
 340                 // Sanitize path.
 341                 $dir = trim($dir);
 342 
 343                 // Add to the front of the list so that custom paths are searched first.
 344                 if (!in_array($dir, self::$_includePaths))
 345                 {
 346                     array_unshift(self::$_includePaths, $dir);
 347                 }
 348             }
 349         }
 350 
 351         return self::$_includePaths;
 352     }
 353 
 354     /**
 355      * Method to compute the default name of the asset.
 356      * The default name is in the form table_name.id
 357      * where id is the value of the primary key of the table.
 358      *
 359      * @return  string
 360      *
 361      * @since   11.1
 362      */
 363     protected function _getAssetName()
 364     {
 365         $keys = array();
 366 
 367         foreach ($this->_tbl_keys as $k)
 368         {
 369             $keys[] = (int) $this->$k;
 370         }
 371 
 372         return $this->_tbl . '.' . implode('.', $keys);
 373     }
 374 
 375     /**
 376      * Method to return the title to use for the asset table.
 377      *
 378      * In tracking the assets a title is kept for each asset so that there is some context available in a unified access manager.
 379      * Usually this would just return $this->title or $this->name or whatever is being used for the primary name of the row.
 380      * If this method is not overridden, the asset name is used.
 381      *
 382      * @return  string  The string to use as the title in the asset table.
 383      *
 384      * @since   11.1
 385      */
 386     protected function _getAssetTitle()
 387     {
 388         return $this->_getAssetName();
 389     }
 390 
 391     /**
 392      * Method to get the parent asset under which to register this one.
 393      *
 394      * By default, all assets are registered to the ROOT node with ID, which will default to 1 if none exists.
 395      * An extended class can define a table and ID to lookup.  If the asset does not exist it will be created.
 396      *
 397      * @param   JTable   $table  A JTable object for the asset parent.
 398      * @param   integer  $id     Id to look up
 399      *
 400      * @return  integer
 401      *
 402      * @since   11.1
 403      */
 404     protected function _getAssetParentId(JTable $table = null, $id = null)
 405     {
 406         // For simple cases, parent to the asset root.
 407         /** @var JTableAsset $assets */
 408         $assets = self::getInstance('Asset', 'JTable', array('dbo' => $this->getDbo()));
 409         $rootId = $assets->getRootId();
 410 
 411         if (!empty($rootId))
 412         {
 413             return $rootId;
 414         }
 415 
 416         return 1;
 417     }
 418 
 419     /**
 420      * Method to append the primary keys for this table to a query.
 421      *
 422      * @param   JDatabaseQuery  $query  A query object to append.
 423      * @param   mixed           $pk     Optional primary key parameter.
 424      *
 425      * @return  void
 426      *
 427      * @since   12.3
 428      */
 429     public function appendPrimaryKeys($query, $pk = null)
 430     {
 431         if (is_null($pk))
 432         {
 433             foreach ($this->_tbl_keys as $k)
 434             {
 435                 $query->where($this->_db->quoteName($k) . ' = ' . $this->_db->quote($this->$k));
 436             }
 437         }
 438         else
 439         {
 440             if (is_string($pk))
 441             {
 442                 $pk = array($this->_tbl_key => $pk);
 443             }
 444 
 445             $pk = (object) $pk;
 446 
 447             foreach ($this->_tbl_keys as $k)
 448             {
 449                 $query->where($this->_db->quoteName($k) . ' = ' . $this->_db->quote($pk->$k));
 450             }
 451         }
 452     }
 453 
 454     /**
 455      * Method to get the database table name for the class.
 456      *
 457      * @return  string  The name of the database table being modeled.
 458      *
 459      * @since   11.1
 460      */
 461     public function getTableName()
 462     {
 463         return $this->_tbl;
 464     }
 465 
 466     /**
 467      * Method to get the primary key field name for the table.
 468      *
 469      * @param   boolean  $multiple  True to return all primary keys (as an array) or false to return just the first one (as a string).
 470      *
 471      * @return  mixed  Array of primary key field names or string containing the first primary key field.
 472      *
 473      * @since   11.1
 474      */
 475     public function getKeyName($multiple = false)
 476     {
 477         // Count the number of keys
 478         if (count($this->_tbl_keys))
 479         {
 480             if ($multiple)
 481             {
 482                 // If we want multiple keys, return the raw array.
 483                 return $this->_tbl_keys;
 484             }
 485             else
 486             {
 487                 // If we want the standard method, just return the first key.
 488                 return $this->_tbl_keys[0];
 489             }
 490         }
 491 
 492         return '';
 493     }
 494 
 495     /**
 496      * Method to get the JDatabaseDriver object.
 497      *
 498      * @return  JDatabaseDriver  The internal database driver object.
 499      *
 500      * @since   11.1
 501      */
 502     public function getDbo()
 503     {
 504         return $this->_db;
 505     }
 506 
 507     /**
 508      * Method to set the JDatabaseDriver object.
 509      *
 510      * @param   JDatabaseDriver  $db  A JDatabaseDriver object to be used by the table object.
 511      *
 512      * @return  boolean  True on success.
 513      *
 514      * @since   11.1
 515      */
 516     public function setDbo($db)
 517     {
 518         $this->_db = $db;
 519 
 520         return true;
 521     }
 522 
 523     /**
 524      * Method to set rules for the record.
 525      *
 526      * @param   mixed  $input  A JAccessRules object, JSON string, or array.
 527      *
 528      * @return  void
 529      *
 530      * @since   11.1
 531      */
 532     public function setRules($input)
 533     {
 534         if ($input instanceof JAccessRules)
 535         {
 536             $this->_rules = $input;
 537         }
 538         else
 539         {
 540             $this->_rules = new JAccessRules($input);
 541         }
 542     }
 543 
 544     /**
 545      * Method to get the rules for the record.
 546      *
 547      * @return  JAccessRules object
 548      *
 549      * @since   11.1
 550      */
 551     public function getRules()
 552     {
 553         return $this->_rules;
 554     }
 555 
 556     /**
 557      * Method to reset class properties to the defaults set in the class
 558      * definition. It will ignore the primary key as well as any private class
 559      * properties (except $_errors).
 560      *
 561      * @return  void
 562      *
 563      * @since   11.1
 564      */
 565     public function reset()
 566     {
 567         // Get the default values for the class from the table.
 568         foreach ($this->getFields() as $k => $v)
 569         {
 570             // If the property is not the primary key or private, reset it.
 571             if (!in_array($k, $this->_tbl_keys) && (strpos($k, '_') !== 0))
 572             {
 573                 $this->$k = $v->Default;
 574             }
 575         }
 576 
 577         // Reset table errors
 578         $this->_errors = array();
 579     }
 580 
 581     /**
 582      * Method to bind an associative array or object to the JTable instance.This
 583      * method only binds properties that are publicly accessible and optionally
 584      * takes an array of properties to ignore when binding.
 585      *
 586      * @param   array|object  $src     An associative array or object to bind to the JTable instance.
 587      * @param   array|string  $ignore  An optional array or space separated list of properties to ignore while binding.
 588      *
 589      * @return  boolean  True on success.
 590      *
 591      * @since   11.1
 592      * @throws  InvalidArgumentException
 593      */
 594     public function bind($src, $ignore = array())
 595     {
 596         // JSON encode any fields required
 597         if (!empty($this->_jsonEncode))
 598         {
 599             foreach ($this->_jsonEncode as $field)
 600             {
 601                 if (isset($src[$field]) && is_array($src[$field]))
 602                 {
 603                     $src[$field] = json_encode($src[$field]);
 604                 }
 605             }
 606         }
 607 
 608         // Check if the source value is an array or object
 609         if (!is_object($src) && !is_array($src))
 610         {
 611             throw new InvalidArgumentException(
 612                 sprintf(
 613                     'Could not bind the data source in %1$s::bind(), the source must be an array or object but a "%2$s" was given.',
 614                     get_class($this),
 615                     gettype($src)
 616                 )
 617             );
 618         }
 619 
 620         // If the source value is an object, get its accessible properties.
 621         if (is_object($src))
 622         {
 623             $src = get_object_vars($src);
 624         }
 625 
 626         // If the ignore value is a string, explode it over spaces.
 627         if (!is_array($ignore))
 628         {
 629             $ignore = explode(' ', $ignore);
 630         }
 631 
 632         // Bind the source value, excluding the ignored fields.
 633         foreach ($this->getProperties() as $k => $v)
 634         {
 635             // Only process fields not in the ignore array.
 636             if (!in_array($k, $ignore))
 637             {
 638                 if (isset($src[$k]))
 639                 {
 640                     $this->$k = $src[$k];
 641                 }
 642             }
 643         }
 644 
 645         return true;
 646     }
 647 
 648     /**
 649      * Method to load a row from the database by primary key and bind the fields to the JTable instance properties.
 650      *
 651      * @param   mixed    $keys   An optional primary key value to load the row by, or an array of fields to match.
 652      *                           If not set the instance property value is used.
 653      * @param   boolean  $reset  True to reset the default values before loading the new row.
 654      *
 655      * @return  boolean  True if successful. False if row not found.
 656      *
 657      * @since   11.1
 658      * @throws  InvalidArgumentException
 659      * @throws  RuntimeException
 660      * @throws  UnexpectedValueException
 661      */
 662     public function load($keys = null, $reset = true)
 663     {
 664         // Implement JObservableInterface: Pre-processing by observers
 665         $this->_observers->update('onBeforeLoad', array($keys, $reset));
 666 
 667         if (empty($keys))
 668         {
 669             $empty = true;
 670             $keys  = array();
 671 
 672             // If empty, use the value of the current key
 673             foreach ($this->_tbl_keys as $key)
 674             {
 675                 $empty      = $empty && empty($this->$key);
 676                 $keys[$key] = $this->$key;
 677             }
 678 
 679             // If empty primary key there's is no need to load anything
 680             if ($empty)
 681             {
 682                 return true;
 683             }
 684         }
 685         elseif (!is_array($keys))
 686         {
 687             // Load by primary key.
 688             $keyCount = count($this->_tbl_keys);
 689 
 690             if ($keyCount)
 691             {
 692                 if ($keyCount > 1)
 693                 {
 694                     throw new InvalidArgumentException('Table has multiple primary keys specified, only one primary key value provided.');
 695                 }
 696 
 697                 $keys = array($this->getKeyName() => $keys);
 698             }
 699             else
 700             {
 701                 throw new RuntimeException('No table keys defined.');
 702             }
 703         }
 704 
 705         if ($reset)
 706         {
 707             $this->reset();
 708         }
 709 
 710         // Initialise the query.
 711         $query = $this->_db->getQuery(true)
 712             ->select('*')
 713             ->from($this->_tbl);
 714         $fields = array_keys($this->getProperties());
 715 
 716         foreach ($keys as $field => $value)
 717         {
 718             // Check that $field is in the table.
 719             if (!in_array($field, $fields))
 720             {
 721                 throw new UnexpectedValueException(sprintf('Missing field in database: %s &#160; %s.', get_class($this), $field));
 722             }
 723             // Add the search tuple to the query.
 724             $query->where($this->_db->quoteName($field) . ' = ' . $this->_db->quote($value));
 725         }
 726 
 727         $this->_db->setQuery($query);
 728 
 729         $row = $this->_db->loadAssoc();
 730 
 731         // Check that we have a result.
 732         if (empty($row))
 733         {
 734             $result = false;
 735         }
 736         else
 737         {
 738             // Bind the object with the row and return.
 739             $result = $this->bind($row);
 740         }
 741 
 742         // Implement JObservableInterface: Post-processing by observers
 743         $this->_observers->update('onAfterLoad', array(&$result, $row));
 744 
 745         return $result;
 746     }
 747 
 748     /**
 749      * Method to perform sanity checks on the JTable instance properties to ensure they are safe to store in the database.
 750      *
 751      * Child classes should override this method to make sure the data they are storing in the database is safe and as expected before storage.
 752      *
 753      * @return  boolean  True if the instance is sane and able to be stored in the database.
 754      *
 755      * @since   11.1
 756      */
 757     public function check()
 758     {
 759         return true;
 760     }
 761 
 762     /**
 763      * Method to store a row in the database from the JTable instance properties.
 764      *
 765      * If a primary key value is set the row with that primary key value will be updated with the instance property values.
 766      * If no primary key value is set a new row will be inserted into the database with the properties from the JTable instance.
 767      *
 768      * @param   boolean  $updateNulls  True to update fields even if they are null.
 769      *
 770      * @return  boolean  True on success.
 771      *
 772      * @since   11.1
 773      */
 774     public function store($updateNulls = false)
 775     {
 776         $result = true;
 777 
 778         $k = $this->_tbl_keys;
 779 
 780         // Implement JObservableInterface: Pre-processing by observers
 781         $this->_observers->update('onBeforeStore', array($updateNulls, $k));
 782 
 783         $currentAssetId = 0;
 784 
 785         if (!empty($this->asset_id))
 786         {
 787             $currentAssetId = $this->asset_id;
 788         }
 789 
 790         // The asset id field is managed privately by this class.
 791         if ($this->_trackAssets)
 792         {
 793             unset($this->asset_id);
 794         }
 795 
 796         // If a primary key exists update the object, otherwise insert it.
 797         if ($this->hasPrimaryKey())
 798         {
 799             $this->_db->updateObject($this->_tbl, $this, $this->_tbl_keys, $updateNulls);
 800         }
 801         else
 802         {
 803             $this->_db->insertObject($this->_tbl, $this, $this->_tbl_keys[0]);
 804         }
 805 
 806         // If the table is not set to track assets return true.
 807         if ($this->_trackAssets)
 808         {
 809             if ($this->_locked)
 810             {
 811                 $this->_unlock();
 812             }
 813 
 814             /*
 815              * Asset Tracking
 816              */
 817             $parentId = $this->_getAssetParentId();
 818             $name     = $this->_getAssetName();
 819             $title    = $this->_getAssetTitle();
 820 
 821             /** @var JTableAsset $asset */
 822             $asset = self::getInstance('Asset', 'JTable', array('dbo' => $this->getDbo()));
 823             $asset->loadByName($name);
 824 
 825             // Re-inject the asset id.
 826             $this->asset_id = $asset->id;
 827 
 828             // Check for an error.
 829             $error = $asset->getError();
 830 
 831             if ($error)
 832             {
 833                 $this->setError($error);
 834 
 835                 return false;
 836             }
 837             else
 838             {
 839                 // Specify how a new or moved node asset is inserted into the tree.
 840                 if (empty($this->asset_id) || $asset->parent_id != $parentId)
 841                 {
 842                     $asset->setLocation($parentId, 'last-child');
 843                 }
 844 
 845                 // Prepare the asset to be stored.
 846                 $asset->parent_id = $parentId;
 847                 $asset->name      = $name;
 848                 $asset->title     = $title;
 849 
 850                 if ($this->_rules instanceof JAccessRules)
 851                 {
 852                     $asset->rules = (string) $this->_rules;
 853                 }
 854 
 855                 if (!$asset->check() || !$asset->store($updateNulls))
 856                 {
 857                     $this->setError($asset->getError());
 858 
 859                     return false;
 860                 }
 861                 else
 862                 {
 863                     // Create an asset_id or heal one that is corrupted.
 864                     if (empty($this->asset_id) || ($currentAssetId != $this->asset_id && !empty($this->asset_id)))
 865                     {
 866                         // Update the asset_id field in this table.
 867                         $this->asset_id = (int) $asset->id;
 868 
 869                         $query = $this->_db->getQuery(true)
 870                             ->update($this->_db->quoteName($this->_tbl))
 871                             ->set('asset_id = ' . (int) $this->asset_id);
 872                         $this->appendPrimaryKeys($query);
 873                         $this->_db->setQuery($query)->execute();
 874                     }
 875                 }
 876             }
 877         }
 878 
 879         // Implement JObservableInterface: Post-processing by observers
 880         $this->_observers->update('onAfterStore', array(&$result));
 881 
 882         return $result;
 883     }
 884 
 885     /**
 886      * Method to provide a shortcut to binding, checking and storing a JTable instance to the database table.
 887      *
 888      * The method will check a row in once the data has been stored and if an ordering filter is present will attempt to reorder
 889      * the table rows based on the filter.  The ordering filter is an instance property name.  The rows that will be reordered
 890      * are those whose value matches the JTable instance for the property specified.
 891      *
 892      * @param   array|object  $src             An associative array or object to bind to the JTable instance.
 893      * @param   string        $orderingFilter  Filter for the order updating
 894      * @param   array|string  $ignore          An optional array or space separated list of properties to ignore while binding.
 895      *
 896      * @return  boolean  True on success.
 897      *
 898      * @since   11.1
 899      */
 900     public function save($src, $orderingFilter = '', $ignore = '')
 901     {
 902         // Attempt to bind the source to the instance.
 903         if (!$this->bind($src, $ignore))
 904         {
 905             return false;
 906         }
 907 
 908         // Run any sanity checks on the instance and verify that it is ready for storage.
 909         if (!$this->check())
 910         {
 911             return false;
 912         }
 913 
 914         // Attempt to store the properties to the database table.
 915         if (!$this->store())
 916         {
 917             return false;
 918         }
 919 
 920         // Attempt to check the row in, just in case it was checked out.
 921         if (!$this->checkin())
 922         {
 923             return false;
 924         }
 925 
 926         // If an ordering filter is set, attempt reorder the rows in the table based on the filter and value.
 927         if ($orderingFilter)
 928         {
 929             $filterValue = $this->$orderingFilter;
 930             $this->reorder($orderingFilter ? $this->_db->quoteName($orderingFilter) . ' = ' . $this->_db->quote($filterValue) : '');
 931         }
 932 
 933         // Set the error to empty and return true.
 934         $this->setError('');
 935 
 936         return true;
 937     }
 938 
 939     /**
 940      * Method to delete a row from the database table by primary key value.
 941      *
 942      * @param   mixed  $pk  An optional primary key value to delete.  If not set the instance property value is used.
 943      *
 944      * @return  boolean  True on success.
 945      *
 946      * @since   11.1
 947      * @throws  UnexpectedValueException
 948      */
 949     public function delete($pk = null)
 950     {
 951         if (is_null($pk))
 952         {
 953             $pk = array();
 954 
 955             foreach ($this->_tbl_keys as $key)
 956             {
 957                 $pk[$key] = $this->$key;
 958             }
 959         }
 960         elseif (!is_array($pk))
 961         {
 962             $pk = array($this->_tbl_key => $pk);
 963         }
 964 
 965         foreach ($this->_tbl_keys as $key)
 966         {
 967             $pk[$key] = is_null($pk[$key]) ? $this->$key : $pk[$key];
 968 
 969             if ($pk[$key] === null)
 970             {
 971                 throw new UnexpectedValueException('Null primary key not allowed.');
 972             }
 973 
 974             $this->$key = $pk[$key];
 975         }
 976 
 977         // Implement JObservableInterface: Pre-processing by observers
 978         $this->_observers->update('onBeforeDelete', array($pk));
 979 
 980         // If tracking assets, remove the asset first.
 981         if ($this->_trackAssets)
 982         {
 983             // Get the asset name
 984             $name  = $this->_getAssetName();
 985             /** @var JTableAsset $asset */
 986             $asset = self::getInstance('Asset');
 987 
 988             if ($asset->loadByName($name))
 989             {
 990                 if (!$asset->delete())
 991                 {
 992                     $this->setError($asset->getError());
 993 
 994                     return false;
 995                 }
 996             }
 997         }
 998 
 999         // Delete the row by primary key.
1000         $query = $this->_db->getQuery(true)
1001             ->delete($this->_tbl);
1002         $this->appendPrimaryKeys($query, $pk);
1003 
1004         $this->_db->setQuery($query);
1005 
1006         // Check for a database error.
1007         $this->_db->execute();
1008 
1009         // Implement JObservableInterface: Post-processing by observers
1010         $this->_observers->update('onAfterDelete', array($pk));
1011 
1012         return true;
1013     }
1014 
1015     /**
1016      * Method to check a row out if the necessary properties/fields exist.
1017      *
1018      * To prevent race conditions while editing rows in a database, a row can be checked out if the fields 'checked_out' and 'checked_out_time'
1019      * are available. While a row is checked out, any attempt to store the row by a user other than the one who checked the row out should be
1020      * held until the row is checked in again.
1021      *
1022      * @param   integer  $userId  The Id of the user checking out the row.
1023      * @param   mixed    $pk      An optional primary key value to check out.  If not set the instance property value is used.
1024      *
1025      * @return  boolean  True on success.
1026      *
1027      * @since   11.1
1028      * @throws  UnexpectedValueException
1029      */
1030     public function checkOut($userId, $pk = null)
1031     {
1032         $checkedOutField = $this->getColumnAlias('checked_out');
1033         $checkedOutTimeField = $this->getColumnAlias('checked_out_time');
1034 
1035         // If there is no checked_out or checked_out_time field, just return true.
1036         if (!property_exists($this, $checkedOutField) || !property_exists($this, $checkedOutTimeField))
1037         {
1038             return true;
1039         }
1040 
1041         if (is_null($pk))
1042         {
1043             $pk = array();
1044 
1045             foreach ($this->_tbl_keys as $key)
1046             {
1047                 $pk[$key] = $this->$key;
1048             }
1049         }
1050         elseif (!is_array($pk))
1051         {
1052             $pk = array($this->_tbl_key => $pk);
1053         }
1054 
1055         foreach ($this->_tbl_keys as $key)
1056         {
1057             $pk[$key] = is_null($pk[$key]) ? $this->$key : $pk[$key];
1058 
1059             if ($pk[$key] === null)
1060             {
1061                 throw new UnexpectedValueException('Null primary key not allowed.');
1062             }
1063         }
1064 
1065         // Get the current time in the database format.
1066         $time = JFactory::getDate()->toSql();
1067 
1068         // Check the row out by primary key.
1069         $query = $this->_db->getQuery(true)
1070             ->update($this->_tbl)
1071             ->set($this->_db->quoteName($checkedOutField) . ' = ' . (int) $userId)
1072             ->set($this->_db->quoteName($checkedOutTimeField) . ' = ' . $this->_db->quote($time));
1073         $this->appendPrimaryKeys($query, $pk);
1074         $this->_db->setQuery($query);
1075         $this->_db->execute();
1076 
1077         // Set table values in the object.
1078         $this->$checkedOutField      = (int) $userId;
1079         $this->$checkedOutTimeField = $time;
1080 
1081         return true;
1082     }
1083 
1084     /**
1085      * Method to check a row in if the necessary properties/fields exist.
1086      *
1087      * Checking a row in will allow other users the ability to edit the row.
1088      *
1089      * @param   mixed  $pk  An optional primary key value to check out.  If not set the instance property value is used.
1090      *
1091      * @return  boolean  True on success.
1092      *
1093      * @since   11.1
1094      * @throws  UnexpectedValueException
1095      */
1096     public function checkIn($pk = null)
1097     {
1098         $checkedOutField = $this->getColumnAlias('checked_out');
1099         $checkedOutTimeField = $this->getColumnAlias('checked_out_time');
1100 
1101         // If there is no checked_out or checked_out_time field, just return true.
1102         if (!property_exists($this, $checkedOutField) || !property_exists($this, $checkedOutTimeField))
1103         {
1104             return true;
1105         }
1106 
1107         if (is_null($pk))
1108         {
1109             $pk = array();
1110 
1111             foreach ($this->_tbl_keys as $key)
1112             {
1113                 $pk[$this->$key] = $this->$key;
1114             }
1115         }
1116         elseif (!is_array($pk))
1117         {
1118             $pk = array($this->_tbl_key => $pk);
1119         }
1120 
1121         foreach ($this->_tbl_keys as $key)
1122         {
1123             $pk[$key] = empty($pk[$key]) ? $this->$key : $pk[$key];
1124 
1125             if ($pk[$key] === null)
1126             {
1127                 throw new UnexpectedValueException('Null primary key not allowed.');
1128             }
1129         }
1130 
1131         // Check the row in by primary key.
1132         $query = $this->_db->getQuery(true)
1133             ->update($this->_tbl)
1134             ->set($this->_db->quoteName($checkedOutField) . ' = 0')
1135             ->set($this->_db->quoteName($checkedOutTimeField) . ' = ' . $this->_db->quote($this->_db->getNullDate()));
1136         $this->appendPrimaryKeys($query, $pk);
1137         $this->_db->setQuery($query);
1138 
1139         // Check for a database error.
1140         $this->_db->execute();
1141 
1142         // Set table values in the object.
1143         $this->$checkedOutField      = 0;
1144         $this->$checkedOutTimeField = '';
1145 
1146         return true;
1147     }
1148 
1149     /**
1150      * Validate that the primary key has been set.
1151      *
1152      * @return  boolean  True if the primary key(s) have been set.
1153      *
1154      * @since   12.3
1155      */
1156     public function hasPrimaryKey()
1157     {
1158         if ($this->_autoincrement)
1159         {
1160             $empty = true;
1161 
1162             foreach ($this->_tbl_keys as $key)
1163             {
1164                 $empty = $empty && empty($this->$key);
1165             }
1166         }
1167         else
1168         {
1169             $query = $this->_db->getQuery(true)
1170                 ->select('COUNT(*)')
1171                 ->from($this->_tbl);
1172             $this->appendPrimaryKeys($query);
1173 
1174             $this->_db->setQuery($query);
1175             $count = $this->_db->loadResult();
1176 
1177             if ($count == 1)
1178             {
1179                 $empty = false;
1180             }
1181             else
1182             {
1183                 $empty = true;
1184             }
1185         }
1186 
1187         return !$empty;
1188     }
1189 
1190     /**
1191      * Method to increment the hits for a row if the necessary property/field exists.
1192      *
1193      * @param   mixed  $pk  An optional primary key value to increment. If not set the instance property value is used.
1194      *
1195      * @return  boolean  True on success.
1196      *
1197      * @since   11.1
1198      * @throws  UnexpectedValueException
1199      */
1200     public function hit($pk = null)
1201     {
1202         $hitsField = $this->getColumnAlias('hits');
1203 
1204         // If there is no hits field, just return true.
1205         if (!property_exists($this, $hitsField))
1206         {
1207             return true;
1208         }
1209 
1210         if (is_null($pk))
1211         {
1212             $pk = array();
1213 
1214             foreach ($this->_tbl_keys as $key)
1215             {
1216                 $pk[$key] = $this->$key;
1217             }
1218         }
1219         elseif (!is_array($pk))
1220         {
1221             $pk = array($this->_tbl_key => $pk);
1222         }
1223 
1224         foreach ($this->_tbl_keys as $key)
1225         {
1226             $pk[$key] = is_null($pk[$key]) ? $this->$key : $pk[$key];
1227 
1228             if ($pk[$key] === null)
1229             {
1230                 throw new UnexpectedValueException('Null primary key not allowed.');
1231             }
1232         }
1233 
1234         // Check the row in by primary key.
1235         $query = $this->_db->getQuery(true)
1236             ->update($this->_tbl)
1237             ->set($this->_db->quoteName($hitsField) . ' = (' . $this->_db->quoteName($hitsField) . ' + 1)');
1238         $this->appendPrimaryKeys($query, $pk);
1239         $this->_db->setQuery($query);
1240         $this->_db->execute();
1241 
1242         // Set table values in the object.
1243         $this->hits++;
1244 
1245         return true;
1246     }
1247 
1248     /**
1249      * Method to determine if a row is checked out and therefore uneditable by a user.
1250      *
1251      * If the row is checked out by the same user, then it is considered not checked out -- as the user can still edit it.
1252      *
1253      * @param   integer  $with     The user ID to preform the match with, if an item is checked out by this user the function will return false.
1254      * @param   integer  $against  The user ID to perform the match against when the function is used as a static function.
1255      *
1256      * @return  boolean  True if checked out.
1257      *
1258      * @since   11.1
1259      */
1260     public function isCheckedOut($with = 0, $against = null)
1261     {
1262         // Handle the non-static case.
1263         if (isset($this) && ($this instanceof JTable) && is_null($against))
1264         {
1265             $checkedOutField = $this->getColumnAlias('checked_out');
1266             $against = $this->get($checkedOutField);
1267         }
1268 
1269         // The item is not checked out or is checked out by the same user.
1270         if (!$against || ($against == $with))
1271         {
1272             return false;
1273         }
1274 
1275         $db = JFactory::getDbo();
1276         $query = $db->getQuery(true)
1277             ->select('COUNT(userid)')
1278             ->from($db->quoteName('#__session'))
1279             ->where($db->quoteName('userid') . ' = ' . (int) $against);
1280         $db->setQuery($query);
1281         $checkedOut = (boolean) $db->loadResult();
1282 
1283         // If a session exists for the user then it is checked out.
1284         return $checkedOut;
1285     }
1286 
1287     /**
1288      * Method to get the next ordering value for a group of rows defined by an SQL WHERE clause.
1289      *
1290      * This is useful for placing a new item last in a group of items in the table.
1291      *
1292      * @param   string  $where  WHERE clause to use for selecting the MAX(ordering) for the table.
1293      *
1294      * @return  integer  The next ordering value.
1295      *
1296      * @since   11.1
1297      * @throws  UnexpectedValueException
1298      */
1299     public function getNextOrder($where = '')
1300     {
1301         // Check if there is an ordering field set
1302         $orderingField = $this->getColumnAlias('ordering');
1303 
1304         if (!property_exists($this, $orderingField))
1305         {
1306             throw new UnexpectedValueException(sprintf('%s does not support ordering.', get_class($this)));
1307         }
1308 
1309         // Get the largest ordering value for a given where clause.
1310         $query = $this->_db->getQuery(true)
1311             ->select('MAX(' . $this->_db->quoteName($orderingField) . ')')
1312             ->from($this->_tbl);
1313 
1314         if ($where)
1315         {
1316             $query->where($where);
1317         }
1318 
1319         $this->_db->setQuery($query);
1320         $max = (int) $this->_db->loadResult();
1321 
1322         // Return the largest ordering value + 1.
1323         return $max + 1;
1324     }
1325 
1326     /**
1327      * Get the primary key values for this table using passed in values as a default.
1328      *
1329      * @param   array  $keys  Optional primary key values to use.
1330      *
1331      * @return  array  An array of primary key names and values.
1332      *
1333      * @since   12.3
1334      */
1335     public function getPrimaryKey(array $keys = array())
1336     {
1337         foreach ($this->_tbl_keys as $key)
1338         {
1339             if (!isset($keys[$key]))
1340             {
1341                 if (!empty($this->$key))
1342                 {
1343                     $keys[$key] = $this->$key;
1344                 }
1345             }
1346         }
1347 
1348         return $keys;
1349     }
1350 
1351     /**
1352      * Method to compact the ordering values of rows in a group of rows defined by an SQL WHERE clause.
1353      *
1354      * @param   string  $where  WHERE clause to use for limiting the selection of rows to compact the ordering values.
1355      *
1356      * @return  mixed  Boolean  True on success.
1357      *
1358      * @since   11.1
1359      * @throws  UnexpectedValueException
1360      */
1361     public function reorder($where = '')
1362     {
1363         // Check if there is an ordering field set
1364         $orderingField = $this->getColumnAlias('ordering');
1365 
1366         if (!property_exists($this, $orderingField))
1367         {
1368             throw new UnexpectedValueException(sprintf('%s does not support ordering.', get_class($this)));
1369         }
1370 
1371         $quotedOrderingField = $this->_db->quoteName($orderingField);
1372 
1373         $subquery = $this->_db->getQuery(true)
1374             ->from($this->_tbl)
1375             ->selectRowNumber($quotedOrderingField, 'new_ordering');
1376 
1377         $query = $this->_db->getQuery(true)
1378             ->update($this->_tbl)
1379             ->set($quotedOrderingField . ' = sq.new_ordering');
1380 
1381         $innerOn = array();
1382 
1383         // Get the primary keys for the selection.
1384         foreach ($this->_tbl_keys as $i => $k)
1385         {
1386             $subquery->select($this->_db->quoteName($k, 'pk__' . $i));
1387             $innerOn[] = $this->_db->quoteName($k) . ' = sq.' . $this->_db->quoteName('pk__' . $i);
1388         }
1389 
1390         // Setup the extra where and ordering clause data.
1391         if ($where)
1392         {
1393             $subquery->where($where);
1394             $query->where($where);
1395         }
1396 
1397         $subquery->where($quotedOrderingField . ' >= 0');
1398         $query->where($quotedOrderingField . ' >= 0');
1399 
1400         $query->innerJoin('(' . (string) $subquery . ') AS sq ON ' . implode(' AND ', $innerOn));
1401 
1402         $this->_db->setQuery($query);
1403         $this->_db->execute();
1404 
1405         return true;
1406     }
1407 
1408     /**
1409      * Method to move a row in the ordering sequence of a group of rows defined by an SQL WHERE clause.
1410      *
1411      * Negative numbers move the row up in the sequence and positive numbers move it down.
1412      *
1413      * @param   integer  $delta  The direction and magnitude to move the row in the ordering sequence.
1414      * @param   string   $where  WHERE clause to use for limiting the selection of rows to compact the ordering values.
1415      *
1416      * @return  boolean  True on success.
1417      *
1418      * @since   11.1
1419      * @throws  UnexpectedValueException
1420      */
1421     public function move($delta, $where = '')
1422     {
1423         // Check if there is an ordering field set
1424         $orderingField = $this->getColumnAlias('ordering');
1425 
1426         if (!property_exists($this, $orderingField))
1427         {
1428             throw new UnexpectedValueException(sprintf('%s does not support ordering.', get_class($this)));
1429         }
1430 
1431         $quotedOrderingField = $this->_db->quoteName($orderingField);
1432 
1433         // If the change is none, do nothing.
1434         if (empty($delta))
1435         {
1436             return true;
1437         }
1438 
1439         $row   = null;
1440         $query = $this->_db->getQuery(true);
1441 
1442         // Select the primary key and ordering values from the table.
1443         $query->select(implode(',', $this->_tbl_keys) . ', ' . $quotedOrderingField)
1444             ->from($this->_tbl);
1445 
1446         // If the movement delta is negative move the row up.
1447         if ($delta < 0)
1448         {
1449             $query->where($quotedOrderingField . ' < ' . (int) $this->$orderingField)
1450                 ->order($quotedOrderingField . ' DESC');
1451         }
1452         // If the movement delta is positive move the row down.
1453         elseif ($delta > 0)
1454         {
1455             $query->where($quotedOrderingField . ' > ' . (int) $this->$orderingField)
1456                 ->order($quotedOrderingField . ' ASC');
1457         }
1458 
1459         // Add the custom WHERE clause if set.
1460         if ($where)
1461         {
1462             $query->where($where);
1463         }
1464 
1465         // Select the first row with the criteria.
1466         $this->_db->setQuery($query, 0, 1);
1467         $row = $this->_db->loadObject();
1468 
1469         // If a row is found, move the item.
1470         if (!empty($row))
1471         {
1472             // Update the ordering field for this instance to the row's ordering value.
1473             $query->clear()
1474                 ->update($this->_tbl)
1475                 ->set($quotedOrderingField . ' = ' . (int) $row->$orderingField);
1476             $this->appendPrimaryKeys($query);
1477             $this->_db->setQuery($query);
1478             $this->_db->execute();
1479 
1480             // Update the ordering field for the row to this instance's ordering value.
1481             $query->clear()
1482                 ->update($this->_tbl)
1483                 ->set($quotedOrderingField . ' = ' . (int) $this->$orderingField);
1484             $this->appendPrimaryKeys($query, $row);
1485             $this->_db->setQuery($query);
1486             $this->_db->execute();
1487 
1488             // Update the instance value.
1489             $this->$orderingField = $row->$orderingField;
1490         }
1491         else
1492         {
1493             // Update the ordering field for this instance.
1494             $query->clear()
1495                 ->update($this->_tbl)
1496                 ->set($quotedOrderingField . ' = ' . (int) $this->$orderingField);
1497             $this->appendPrimaryKeys($query);
1498             $this->_db->setQuery($query);
1499             $this->_db->execute();
1500         }
1501 
1502         return true;
1503     }
1504 
1505     /**
1506      * Method to set the publishing state for a row or list of rows in the database table.
1507      *
1508      * The method respects checked out rows by other users and will attempt to checkin rows that it can after adjustments are made.
1509      *
1510      * @param   mixed    $pks     An optional array of primary key values to update. If not set the instance property value is used.
1511      * @param   integer  $state   The publishing state. eg. [0 = unpublished, 1 = published]
1512      * @param   integer  $userId  The user ID of the user performing the operation.
1513      *
1514      * @return  boolean  True on success; false if $pks is empty.
1515      *
1516      * @since   11.1
1517      */
1518     public function publish($pks = null, $state = 1, $userId = 0)
1519     {
1520         // Sanitize input
1521         $userId = (int) $userId;
1522         $state  = (int) $state;
1523 
1524         if (!is_null($pks))
1525         {
1526             if (!is_array($pks))
1527             {
1528                 $pks = array($pks);
1529             }
1530 
1531             foreach ($pks as $key => $pk)
1532             {
1533                 if (!is_array($pk))
1534                 {
1535                     $pks[$key] = array($this->_tbl_key => $pk);
1536                 }
1537             }
1538         }
1539 
1540         // If there are no primary keys set check to see if the instance key is set.
1541         if (empty($pks))
1542         {
1543             $pk = array();
1544 
1545             foreach ($this->_tbl_keys as $key)
1546             {
1547                 if ($this->$key)
1548                 {
1549                     $pk[$key] = $this->$key;
1550                 }
1551                 // We don't have a full primary key - return false
1552                 else
1553                 {
1554                     $this->setError(JText::_('JLIB_DATABASE_ERROR_NO_ROWS_SELECTED'));
1555 
1556                     return false;
1557                 }
1558             }
1559 
1560             $pks = array($pk);
1561         }
1562 
1563         $publishedField = $this->getColumnAlias('published');
1564         $checkedOutField = $this->getColumnAlias('checked_out');
1565 
1566         foreach ($pks as $pk)
1567         {
1568             // Update the publishing state for rows with the given primary keys.
1569             $query = $this->_db->getQuery(true)
1570                 ->update($this->_tbl)
1571                 ->set($this->_db->quoteName($publishedField) . ' = ' . (int) $state);
1572 
1573             // If publishing, set published date/time if not previously set
1574             if ($state && property_exists($this, 'publish_up') && (int) $this->publish_up == 0)
1575             {
1576                 $nowDate = $this->_db->quote(JFactory::getDate()->toSql());
1577                 $query->set($this->_db->quoteName($this->getColumnAlias('publish_up')) . ' = ' . $nowDate);
1578             }
1579 
1580             // Determine if there is checkin support for the table.
1581             if (property_exists($this, 'checked_out') || property_exists($this, 'checked_out_time'))
1582             {
1583                 $query->where('(' . $this->_db->quoteName($checkedOutField) . ' = 0 OR ' . $this->_db->quoteName($checkedOutField) . ' = ' . (int) $userId . ')');
1584                 $checkin = true;
1585             }
1586             else
1587             {
1588                 $checkin = false;
1589             }
1590 
1591             // Build the WHERE clause for the primary keys.
1592             $this->appendPrimaryKeys($query, $pk);
1593 
1594             $this->_db->setQuery($query);
1595 
1596             try
1597             {
1598                 $this->_db->execute();
1599             }
1600             catch (RuntimeException $e)
1601             {
1602                 $this->setError($e->getMessage());
1603 
1604                 return false;
1605             }
1606 
1607             // If checkin is supported and all rows were adjusted, check them in.
1608             if ($checkin && (count($pks) == $this->_db->getAffectedRows()))
1609             {
1610                 $this->checkin($pk);
1611             }
1612 
1613             // If the JTable instance value is in the list of primary keys that were set, set the instance.
1614             $ours = true;
1615 
1616             foreach ($this->_tbl_keys as $key)
1617             {
1618                 if ($this->$key != $pk[$key])
1619                 {
1620                     $ours = false;
1621                 }
1622             }
1623 
1624             if ($ours)
1625             {
1626                 $this->$publishedField = $state;
1627             }
1628         }
1629 
1630         $this->setError('');
1631 
1632         return true;
1633     }
1634 
1635     /**
1636      * Method to lock the database table for writing.
1637      *
1638      * @return  boolean  True on success.
1639      *
1640      * @since   11.1
1641      * @throws  RuntimeException
1642      */
1643     protected function _lock()
1644     {
1645         $this->_db->lockTable($this->_tbl);
1646         $this->_locked = true;
1647 
1648         return true;
1649     }
1650 
1651     /**
1652      * Method to return the real name of a "special" column such as ordering, hits, published
1653      * etc etc. In this way you are free to follow your db naming convention and use the
1654      * built in Joomla functions.
1655      *
1656      * @param   string  $column  Name of the "special" column (ie ordering, hits)
1657      *
1658      * @return  string  The string that identify the special
1659      *
1660      * @since   3.4
1661      */
1662     public function getColumnAlias($column)
1663     {
1664         // Get the column data if set
1665         if (isset($this->_columnAlias[$column]))
1666         {
1667             $return = $this->_columnAlias[$column];
1668         }
1669         else
1670         {
1671             $return = $column;
1672         }
1673 
1674         // Sanitize the name
1675         $return = preg_replace('#[^A-Z0-9_]#i', '', $return);
1676 
1677         return $return;
1678     }
1679 
1680     /**
1681      * Method to register a column alias for a "special" column.
1682      *
1683      * @param   string  $column       The "special" column (ie ordering)
1684      * @param   string  $columnAlias  The real column name (ie foo_ordering)
1685      *
1686      * @return  void
1687      *
1688      * @since   3.4
1689      */
1690     public function setColumnAlias($column, $columnAlias)
1691     {
1692         // Santize the column name alias
1693         $column = strtolower($column);
1694         $column = preg_replace('#[^A-Z0-9_]#i', '', $column);
1695 
1696         // Set the column alias internally
1697         $this->_columnAlias[$column] = $columnAlias;
1698     }
1699 
1700     /**
1701      * Method to unlock the database table for writing.
1702      *
1703      * @return  boolean  True on success.
1704      *
1705      * @since   11.1
1706      */
1707     protected function _unlock()
1708     {
1709         $this->_db->unlockTables();
1710         $this->_locked = false;
1711 
1712         return true;
1713     }
1714 }
1715 
Joomla! Framework TM API documentation generated by ApiGen 2.8.0
Joomla!® and Joomla! Framework™ are trademarks of Open Source Matters, Inc. in the United States and other countries.