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     FrameworkOnFramework
   4  * @subpackage  database
   5  * @copyright   Copyright (C) 2010-2016 Nicholas K. Dionysopoulos / Akeeba Ltd. All rights reserved.
   6  * @license     GNU General Public License version 2 or later; see LICENSE.txt
   7  *
   8  * This file is adapted from the Joomla! Platform. It is used to iterate a database cursor returning FOFTable objects
   9  * instead of plain stdClass objects
  10  */
  11 
  12 // Protect from unauthorized access
  13 defined('FOF_INCLUDED') or die;
  14 
  15 /**
  16  * Joomla Platform Database Driver Class
  17  *
  18  * @since  12.1
  19  *
  20  * @method      string  q()   q($text, $escape = true)  Alias for quote method
  21  * @method      string  qn()  qn($name, $as = null)     Alias for quoteName method
  22  */
  23 abstract class FOFDatabaseDriver extends FOFDatabase implements FOFDatabaseInterface
  24 {
  25     /**
  26      * The name of the database.
  27      *
  28      * @var    string
  29      * @since  11.4
  30      */
  31     private $_database;
  32 
  33     /**
  34      * The name of the database driver.
  35      *
  36      * @var    string
  37      * @since  11.1
  38      */
  39     public $name;
  40 
  41     /**
  42      * The type of the database server family supported by this driver. Examples: mysql, oracle, postgresql, mssql,
  43      * sqlite.
  44      *
  45      * @var    string
  46      * @since  CMS 3.5.0
  47      */
  48     public $serverType;
  49 
  50     /**
  51      * @var    resource  The database connection resource.
  52      * @since  11.1
  53      */
  54     protected $connection;
  55 
  56     /**
  57      * @var    integer  The number of SQL statements executed by the database driver.
  58      * @since  11.1
  59      */
  60     protected $count = 0;
  61 
  62     /**
  63      * @var    resource  The database connection cursor from the last query.
  64      * @since  11.1
  65      */
  66     protected $cursor;
  67 
  68     /**
  69      * @var    boolean  The database driver debugging state.
  70      * @since  11.1
  71      */
  72     protected $debug = false;
  73 
  74     /**
  75      * @var    integer  The affected row limit for the current SQL statement.
  76      * @since  11.1
  77      */
  78     protected $limit = 0;
  79 
  80     /**
  81      * @var    array  The log of executed SQL statements by the database driver.
  82      * @since  11.1
  83      */
  84     protected $log = array();
  85 
  86     /**
  87      * @var    array  The log of executed SQL statements timings (start and stop microtimes) by the database driver.
  88      * @since  CMS 3.1.2
  89      */
  90     protected $timings = array();
  91 
  92     /**
  93      * @var    array  The log of executed SQL statements timings (start and stop microtimes) by the database driver.
  94      * @since  CMS 3.1.2
  95      */
  96     protected $callStacks = array();
  97 
  98     /**
  99      * @var    string  The character(s) used to quote SQL statement names such as table names or field names,
 100      *                 etc.  The child classes should define this as necessary.  If a single character string the
 101      *                 same character is used for both sides of the quoted name, else the first character will be
 102      *                 used for the opening quote and the second for the closing quote.
 103      * @since  11.1
 104      */
 105     protected $nameQuote;
 106 
 107     /**
 108      * @var    string  The null or zero representation of a timestamp for the database driver.  This should be
 109      *                 defined in child classes to hold the appropriate value for the engine.
 110      * @since  11.1
 111      */
 112     protected $nullDate;
 113 
 114     /**
 115      * @var    integer  The affected row offset to apply for the current SQL statement.
 116      * @since  11.1
 117      */
 118     protected $offset = 0;
 119 
 120     /**
 121      * @var    array  Passed in upon instantiation and saved.
 122      * @since  11.1
 123      */
 124     protected $options;
 125 
 126     /**
 127      * @var    mixed  The current SQL statement to execute.
 128      * @since  11.1
 129      */
 130     protected $sql;
 131 
 132     /**
 133      * @var    string  The common database table prefix.
 134      * @since  11.1
 135      */
 136     protected $tablePrefix;
 137 
 138     /**
 139      * @var    boolean  True if the database engine supports UTF-8 character encoding.
 140      * @since  11.1
 141      */
 142     protected $utf = true;
 143 
 144     /**
 145      * @var    boolean  True if the database engine supports UTF-8 Multibyte (utf8mb4) character encoding.
 146      * @since  CMS 3.5.0
 147      */
 148     protected $utf8mb4 = false;
 149 
 150     /**
 151      * @var         integer  The database error number
 152      * @since       11.1
 153      * @deprecated  12.1
 154      */
 155     protected $errorNum = 0;
 156 
 157     /**
 158      * @var         string  The database error message
 159      * @since       11.1
 160      * @deprecated  12.1
 161      */
 162     protected $errorMsg;
 163 
 164     /**
 165      * @var    array  FOFDatabaseDriver instances container.
 166      * @since  11.1
 167      */
 168     protected static $instances = array();
 169 
 170     /**
 171      * @var    string  The minimum supported database version.
 172      * @since  12.1
 173      */
 174     protected static $dbMinimum;
 175 
 176     /**
 177      * @var    integer  The depth of the current transaction.
 178      * @since  12.3
 179      */
 180     protected $transactionDepth = 0;
 181 
 182     /**
 183      * @var    callable[]  List of callables to call just before disconnecting database
 184      * @since  CMS 3.1.2
 185      */
 186     protected $disconnectHandlers = array();
 187 
 188     /**
 189      * Get a list of available database connectors.  The list will only be populated with connectors that both
 190      * the class exists and the static test method returns true.  This gives us the ability to have a multitude
 191      * of connector classes that are self-aware as to whether or not they are able to be used on a given system.
 192      *
 193      * @return  array  An array of available database connectors.
 194      *
 195      * @since   11.1
 196      */
 197     public static function getConnectors()
 198     {
 199         $connectors = array();
 200 
 201         // Get an iterator and loop trough the driver classes.
 202         $iterator = new DirectoryIterator(__DIR__ . '/driver');
 203 
 204         /* @type  $file  DirectoryIterator */
 205         foreach ($iterator as $file)
 206         {
 207             $fileName = $file->getFilename();
 208 
 209             // Only load for php files.
 210             if (!$file->isFile() || $file->getExtension() != 'php')
 211             {
 212                 continue;
 213             }
 214 
 215             // Block the ext/mysql driver for PHP 7
 216             if ($fileName === 'mysql.php' && PHP_MAJOR_VERSION >= 7)
 217             {
 218                 continue;
 219             }
 220 
 221             // Derive the class name from the type.
 222             $class = str_ireplace('.php', '', 'FOFDatabaseDriver' . ucfirst(trim($fileName)));
 223 
 224             // If the class doesn't exist we have nothing left to do but look at the next type. We did our best.
 225             if (!class_exists($class))
 226             {
 227                 continue;
 228             }
 229 
 230             // Sweet!  Our class exists, so now we just need to know if it passes its test method.
 231             if ($class::isSupported())
 232             {
 233                 // Connector names should not have file extensions.
 234                 $connectors[] = str_ireplace('.php', '', $fileName);
 235             }
 236         }
 237 
 238         return $connectors;
 239     }
 240 
 241     /**
 242      * Method to return a FOFDatabaseDriver instance based on the given options.  There are three global options and then
 243      * the rest are specific to the database driver.  The 'driver' option defines which FOFDatabaseDriver class is
 244      * used for the connection -- the default is 'mysqli'.  The 'database' option determines which database is to
 245      * be used for the connection.  The 'select' option determines whether the connector should automatically select
 246      * the chosen database.
 247      *
 248      * Instances are unique to the given options and new objects are only created when a unique options array is
 249      * passed into the method.  This ensures that we don't end up with unnecessary database connection resources.
 250      *
 251      * @param   array  $options  Parameters to be passed to the database driver.
 252      *
 253      * @return  FOFDatabaseDriver  A database object.
 254      *
 255      * @since   11.1
 256      * @throws  RuntimeException
 257      */
 258     public static function getInstance($options = array())
 259     {
 260         // Sanitize the database connector options.
 261         $options['driver']   = (isset($options['driver'])) ? preg_replace('/[^A-Z0-9_\.-]/i', '', $options['driver']) : 'mysqli';
 262         $options['database'] = (isset($options['database'])) ? $options['database'] : null;
 263         $options['select']   = (isset($options['select'])) ? $options['select'] : true;
 264 
 265         // If the selected driver is `mysql` and we are on PHP 7 or greater, switch to the `mysqli` driver.
 266         if ($options['driver'] === 'mysql' && PHP_MAJOR_VERSION >= 7)
 267         {
 268             // Check if we have support for the other MySQL drivers
 269             $mysqliSupported   = FOFDatabaseDriverMysqli::isSupported();
 270             $pdoMysqlSupported = FOFDatabaseDriverPdomysql::isSupported();
 271 
 272             // If neither is supported, then the user cannot use MySQL; throw an exception
 273             if (!$mysqliSupported && !$pdoMysqlSupported)
 274             {
 275                 throw new RuntimeException(
 276                     'The PHP `ext/mysql` extension is removed in PHP 7, cannot use the `mysql` driver.'
 277                     . ' Also, this system does not support MySQLi or PDO MySQL.  Cannot instantiate database driver.'
 278                 );
 279             }
 280 
 281             // Prefer MySQLi as it is a closer replacement for the removed MySQL driver, otherwise use the PDO driver
 282             if ($mysqliSupported)
 283             {
 284                 if (class_exists('JLog'))
 285                 {
 286                     JLog::add(
 287                             'The PHP `ext/mysql` extension is removed in PHP 7, cannot use the `mysql` driver.  Trying `mysqli` instead.',
 288                             JLog::WARNING,
 289                             'deprecated'
 290                     );
 291                 }
 292 
 293                 $options['driver'] = 'mysqli';
 294             }
 295             else
 296             {
 297                 if (class_exists('JLog'))
 298                 {
 299                     JLog::add(
 300                             'The PHP `ext/mysql` extension is removed in PHP 7, cannot use the `mysql` driver.  Trying `pdomysql` instead.',
 301                             JLog::WARNING,
 302                             'deprecated'
 303                     );
 304                 }
 305 
 306                 $options['driver'] = 'pdomysql';
 307             }
 308         }
 309 
 310         // Get the options signature for the database connector.
 311         $signature = md5(serialize($options));
 312 
 313         // If we already have a database connector instance for these options then just use that.
 314         if (empty(self::$instances[$signature]))
 315         {
 316             // Derive the class name from the driver.
 317             $class = 'FOFDatabaseDriver' . ucfirst(strtolower($options['driver']));
 318 
 319             // If the class still doesn't exist we have nothing left to do but throw an exception.  We did our best.
 320             if (!class_exists($class))
 321             {
 322                 throw new RuntimeException(sprintf('Unable to load Database Driver: %s', $options['driver']));
 323             }
 324 
 325             // Create our new FOFDatabaseDriver connector based on the options given.
 326             try
 327             {
 328                 $instance = new $class($options);
 329             }
 330             catch (RuntimeException $e)
 331             {
 332                 throw new RuntimeException(sprintf('Unable to connect to the Database: %s', $e->getMessage()), $e->getCode(), $e);
 333             }
 334 
 335             // Set the new connector to the global instances based on signature.
 336             self::$instances[$signature] = $instance;
 337         }
 338 
 339         return self::$instances[$signature];
 340     }
 341 
 342     /**
 343      * Splits a string of multiple queries into an array of individual queries.
 344      *
 345      * @param   string  $sql  Input SQL string with which to split into individual queries.
 346      *
 347      * @return  array  The queries from the input string separated into an array.
 348      *
 349      * @since   11.1
 350      */
 351     public static function splitSql($sql)
 352     {
 353         $start = 0;
 354         $open = false;
 355         $char = '';
 356         $end = strlen($sql);
 357         $queries = array();
 358 
 359         for ($i = 0; $i < $end; $i++)
 360         {
 361             $current = substr($sql, $i, 1);
 362 
 363             if (($current == '"' || $current == '\''))
 364             {
 365                 $n = 2;
 366 
 367                 while (substr($sql, $i - $n + 1, 1) == '\\' && $n < $i)
 368                 {
 369                     $n++;
 370                 }
 371 
 372                 if ($n % 2 == 0)
 373                 {
 374                     if ($open)
 375                     {
 376                         if ($current == $char)
 377                         {
 378                             $open = false;
 379                             $char = '';
 380                         }
 381                     }
 382                     else
 383                     {
 384                         $open = true;
 385                         $char = $current;
 386                     }
 387                 }
 388             }
 389 
 390             if (($current == ';' && !$open) || $i == $end - 1)
 391             {
 392                 $queries[] = substr($sql, $start, ($i - $start + 1));
 393                 $start = $i + 1;
 394             }
 395         }
 396 
 397         return $queries;
 398     }
 399 
 400     /**
 401      * Magic method to provide method alias support for quote() and quoteName().
 402      *
 403      * @param   string  $method  The called method.
 404      * @param   array   $args    The array of arguments passed to the method.
 405      *
 406      * @return  mixed  The aliased method's return value or null.
 407      *
 408      * @since   11.1
 409      */
 410     public function __call($method, $args)
 411     {
 412         if (empty($args))
 413         {
 414             return;
 415         }
 416 
 417         switch ($method)
 418         {
 419             case 'q':
 420                 return $this->quote($args[0], isset($args[1]) ? $args[1] : true);
 421                 break;
 422             case 'qn':
 423                 return $this->quoteName($args[0], isset($args[1]) ? $args[1] : null);
 424                 break;
 425         }
 426     }
 427 
 428     /**
 429      * Constructor.
 430      *
 431      * @param   array  $options  List of options used to configure the connection
 432      *
 433      * @since   11.1
 434      */
 435     public function __construct($options)
 436     {
 437         // Initialise object variables.
 438         $this->_database = (isset($options['database'])) ? $options['database'] : '';
 439         $this->tablePrefix = (isset($options['prefix'])) ? $options['prefix'] : 'jos_';
 440         $this->connection = array_key_exists('connection', $options) ? $options['connection'] : null;
 441 
 442         $this->count = 0;
 443         $this->errorNum = 0;
 444         $this->log = array();
 445 
 446         // Set class options.
 447         $this->options = $options;
 448     }
 449 
 450     /**
 451      * Alter database's character set, obtaining query string from protected member.
 452      *
 453      * @param   string  $dbName  The database name that will be altered
 454      *
 455      * @return  string  The query that alter the database query string
 456      *
 457      * @since   12.2
 458      * @throws  RuntimeException
 459      */
 460     public function alterDbCharacterSet($dbName)
 461     {
 462         if (is_null($dbName))
 463         {
 464             throw new RuntimeException('Database name must not be null.');
 465         }
 466 
 467         $this->setQuery($this->getAlterDbCharacterSet($dbName));
 468 
 469         return $this->execute();
 470     }
 471 
 472     /**
 473      * Alter a table's character set, obtaining an array of queries to do so from a protected method. The conversion is
 474      * wrapped in a transaction, if supported by the database driver. Otherwise the table will be locked before the
 475      * conversion. This prevents data corruption.
 476      *
 477      * @param   string   $tableName  The name of the table to alter
 478      * @param   boolean  $rethrow    True to rethrow database exceptions. Default: false (exceptions are suppressed)
 479      *
 480      * @return  boolean  True if successful
 481      *
 482      * @since   CMS 3.5.0
 483      * @throws  RuntimeException  If the table name is empty
 484      * @throws  Exception  Relayed from the database layer if a database error occurs and $rethrow == true
 485      */
 486     public function alterTableCharacterSet($tableName, $rethrow = false)
 487     {
 488         if (is_null($tableName))
 489         {
 490             throw new RuntimeException('Table name must not be null.');
 491         }
 492 
 493         $queries = $this->getAlterTableCharacterSet($tableName);
 494 
 495         if (empty($queries))
 496         {
 497             return false;
 498         }
 499 
 500         $hasTransaction = true;
 501 
 502         try
 503         {
 504             $this->transactionStart();
 505         }
 506         catch (Exception $e)
 507         {
 508             $hasTransaction = false;
 509             $this->lockTable($tableName);
 510         }
 511 
 512         foreach ($queries as $query)
 513         {
 514             try
 515             {
 516                 $this->setQuery($query)->execute();
 517             }
 518             catch (Exception $e)
 519             {
 520                 if ($hasTransaction)
 521                 {
 522                     $this->transactionRollback();
 523                 }
 524                 else
 525                 {
 526                     $this->unlockTables();
 527                 }
 528 
 529                 if ($rethrow)
 530                 {
 531                     throw $e;
 532                 }
 533 
 534                 return false;
 535             }
 536         }
 537 
 538         if ($hasTransaction)
 539         {
 540             try
 541             {
 542                 $this->transactionCommit();
 543             }
 544             catch (Exception $e)
 545             {
 546                 $this->transactionRollback();
 547 
 548                 if ($rethrow)
 549                 {
 550                     throw $e;
 551                 }
 552 
 553                 return false;
 554             }
 555         }
 556         else
 557         {
 558             $this->unlockTables();
 559         }
 560 
 561         return true;
 562     }
 563 
 564     /**
 565      * Connects to the database if needed.
 566      *
 567      * @return  void  Returns void if the database connected successfully.
 568      *
 569      * @since   12.1
 570      * @throws  RuntimeException
 571      */
 572     abstract public function connect();
 573 
 574     /**
 575      * Determines if the connection to the server is active.
 576      *
 577      * @return  boolean  True if connected to the database engine.
 578      *
 579      * @since   11.1
 580      */
 581     abstract public function connected();
 582 
 583     /**
 584      * Create a new database using information from $options object, obtaining query string
 585      * from protected member.
 586      *
 587      * @param   stdClass  $options  Object used to pass user and database name to database driver.
 588      *                                  This object must have "db_name" and "db_user" set.
 589      * @param   boolean   $utf      True if the database supports the UTF-8 character set.
 590      *
 591      * @return  string  The query that creates database
 592      *
 593      * @since   12.2
 594      * @throws  RuntimeException
 595      */
 596     public function createDatabase($options, $utf = true)
 597     {
 598         if (is_null($options))
 599         {
 600             throw new RuntimeException('$options object must not be null.');
 601         }
 602         elseif (empty($options->db_name))
 603         {
 604             throw new RuntimeException('$options object must have db_name set.');
 605         }
 606         elseif (empty($options->db_user))
 607         {
 608             throw new RuntimeException('$options object must have db_user set.');
 609         }
 610 
 611         $this->setQuery($this->getCreateDatabaseQuery($options, $utf));
 612 
 613         return $this->execute();
 614     }
 615 
 616     /**
 617      * Disconnects the database.
 618      *
 619      * @return  void
 620      *
 621      * @since   12.1
 622      */
 623     abstract public function disconnect();
 624 
 625     /**
 626      * Adds a function callable just before disconnecting the database. Parameter of the callable is $this FOFDatabaseDriver
 627      *
 628      * @param   callable  $callable  Function to call in disconnect() method just before disconnecting from database
 629      *
 630      * @return  void
 631      *
 632      * @since   CMS 3.1.2
 633      */
 634     public function addDisconnectHandler($callable)
 635     {
 636         $this->disconnectHandlers[] = $callable;
 637     }
 638 
 639     /**
 640      * Drops a table from the database.
 641      *
 642      * @param   string   $table     The name of the database table to drop.
 643      * @param   boolean  $ifExists  Optionally specify that the table must exist before it is dropped.
 644      *
 645      * @return  FOFDatabaseDriver     Returns this object to support chaining.
 646      *
 647      * @since   11.4
 648      * @throws  RuntimeException
 649      */
 650     public abstract function dropTable($table, $ifExists = true);
 651 
 652     /**
 653      * Escapes a string for usage in an SQL statement.
 654      *
 655      * @param   string   $text   The string to be escaped.
 656      * @param   boolean  $extra  Optional parameter to provide extra escaping.
 657      *
 658      * @return  string   The escaped string.
 659      *
 660      * @since   11.1
 661      */
 662     abstract public function escape($text, $extra = false);
 663 
 664     /**
 665      * Method to fetch a row from the result set cursor as an array.
 666      *
 667      * @param   mixed  $cursor  The optional result set cursor from which to fetch the row.
 668      *
 669      * @return  mixed  Either the next row from the result set or false if there are no more rows.
 670      *
 671      * @since   11.1
 672      */
 673     abstract protected function fetchArray($cursor = null);
 674 
 675     /**
 676      * Method to fetch a row from the result set cursor as an associative array.
 677      *
 678      * @param   mixed  $cursor  The optional result set cursor from which to fetch the row.
 679      *
 680      * @return  mixed  Either the next row from the result set or false if there are no more rows.
 681      *
 682      * @since   11.1
 683      */
 684     abstract protected function fetchAssoc($cursor = null);
 685 
 686     /**
 687      * Method to fetch a row from the result set cursor as an object.
 688      *
 689      * @param   mixed   $cursor  The optional result set cursor from which to fetch the row.
 690      * @param   string  $class   The class name to use for the returned row object.
 691      *
 692      * @return  mixed   Either the next row from the result set or false if there are no more rows.
 693      *
 694      * @since   11.1
 695      */
 696     abstract protected function fetchObject($cursor = null, $class = 'stdClass');
 697 
 698     /**
 699      * Method to free up the memory used for the result set.
 700      *
 701      * @param   mixed  $cursor  The optional result set cursor from which to fetch the row.
 702      *
 703      * @return  void
 704      *
 705      * @since   11.1
 706      */
 707     abstract protected function freeResult($cursor = null);
 708 
 709     /**
 710      * Get the number of affected rows for the previous executed SQL statement.
 711      *
 712      * @return  integer  The number of affected rows.
 713      *
 714      * @since   11.1
 715      */
 716     abstract public function getAffectedRows();
 717 
 718     /**
 719      * Return the query string to alter the database character set.
 720      *
 721      * @param   string  $dbName  The database name
 722      *
 723      * @return  string  The query that alter the database query string
 724      *
 725      * @since   12.2
 726      */
 727     public function getAlterDbCharacterSet($dbName)
 728     {
 729         $charset = $this->utf8mb4 ? 'utf8mb4' : 'utf8';
 730 
 731         return 'ALTER DATABASE ' . $this->quoteName($dbName) . ' CHARACTER SET `' . $charset . '`';
 732     }
 733 
 734     /**
 735      * Get the query strings to alter the character set and collation of a table.
 736      *
 737      * @param   string  $tableName  The name of the table
 738      *
 739      * @return  string[]  The queries required to alter the table's character set and collation
 740      *
 741      * @since   CMS 3.5.0
 742      */
 743     public function getAlterTableCharacterSet($tableName)
 744     {
 745         $charset = $this->utf8mb4 ? 'utf8mb4' : 'utf8';
 746         $collation = $charset . '_general_ci';
 747 
 748         $quotedTableName = $this->quoteName($tableName);
 749 
 750         $queries = array();
 751         $queries[] = "ALTER TABLE $quotedTableName CONVERT TO CHARACTER SET $charset COLLATE $collation";
 752 
 753         /**
 754          * We also need to convert each text column, modifying their character set and collation. This allows us to
 755          * change, for example, a utf8_bin collated column to a utf8mb4_bin collated column.
 756          */
 757         $sql = "SHOW FULL COLUMNS FROM $quotedTableName";
 758         $this->setQuery($sql);
 759         $columns = $this->loadAssocList();
 760         $columnMods = array();
 761 
 762         if (is_array($columns))
 763         {
 764             foreach ($columns as $column)
 765             {
 766                 // Make sure we are redefining only columns which do support a collation
 767                 $col = (object) $column;
 768 
 769                 if (empty($col->Collation))
 770                 {
 771                     continue;
 772                 }
 773 
 774                 // Default new collation: utf8_general_ci or utf8mb4_general_ci
 775                 $newCollation = $charset . '_general_ci';
 776                 $collationParts = explode('_', $col->Collation);
 777 
 778                 /**
 779                  * If the collation is in the form charset_collationType_ci or charset_collationType we have to change
 780                  * the charset but leave the collationType intact (e.g. utf8_bin must become utf8mb4_bin, NOT
 781                  * utf8mb4_general_ci).
 782                  */
 783                 if (count($collationParts) >= 2)
 784                 {
 785                     $ci = array_pop($collationParts);
 786                     $collationType = array_pop($collationParts);
 787                     $newCollation = $charset . '_' . $collationType . '_' . $ci;
 788 
 789                     /**
 790                      * When the last part of the old collation is not _ci we have a charset_collationType format,
 791                      * something like utf8_bin. Therefore the new collation only has *two* parts.
 792                      */
 793                     if ($ci != 'ci')
 794                     {
 795                         $newCollation = $charset . '_' . $ci;
 796                     }
 797                 }
 798 
 799                 // If the old and new collation is the same we don't have to change the collation type
 800                 if (strtolower($newCollation) == strtolower($col->Collation))
 801                 {
 802                     continue;
 803                 }
 804 
 805                 $null = $col->Null == 'YES' ? 'NULL' : 'NOT NULL';
 806                 $default = is_null($col->Default) ? '' : "DEFAULT '" . $this->q($col->Default) . "'";
 807                 $columnMods[] = "MODIFY COLUMN `{$col->Field}` {$col->Type} CHARACTER SET $charset COLLATE $newCollation $null $default";
 808             }
 809         }
 810 
 811         if (count($columnMods))
 812         {
 813             $queries[] = "ALTER TABLE $quotedTableName " .
 814                 implode(',', $columnMods) .
 815                 " CHARACTER SET $charset COLLATE $collation";
 816         }
 817 
 818         return $queries;
 819     }
 820 
 821     /**
 822      * Automatically downgrade a CREATE TABLE or ALTER TABLE query from utf8mb4 (UTF-8 Multibyte) to plain utf8. Used
 823      * when the server doesn't support UTF-8 Multibyte.
 824      *
 825      * @param   string  $query  The query to convert
 826      *
 827      * @return  string  The converted query
 828      */
 829     public function convertUtf8mb4QueryToUtf8($query)
 830     {
 831         if ($this->hasUTF8mb4Support())
 832         {
 833             return $query;
 834         }
 835 
 836         // If it's not an ALTER TABLE or CREATE TABLE command there's nothing to convert
 837         $beginningOfQuery = substr($query, 0, 12);
 838         $beginningOfQuery = strtoupper($beginningOfQuery);
 839 
 840         if (!in_array($beginningOfQuery, array('ALTER TABLE ', 'CREATE TABLE')))
 841         {
 842             return $query;
 843         }
 844 
 845         // Replace utf8mb4 with utf8
 846         return str_replace('utf8mb4', 'utf8', $query);
 847     }
 848 
 849     /**
 850      * Return the query string to create new Database.
 851      * Each database driver, other than MySQL, need to override this member to return correct string.
 852      *
 853      * @param   stdClass  $options  Object used to pass user and database name to database driver.
 854      *                   This object must have "db_name" and "db_user" set.
 855      * @param   boolean   $utf      True if the database supports the UTF-8 character set.
 856      *
 857      * @return  string  The query that creates database
 858      *
 859      * @since   12.2
 860      */
 861     protected function getCreateDatabaseQuery($options, $utf)
 862     {
 863         if ($utf)
 864         {
 865             $charset = $this->utf8mb4 ? 'utf8mb4' : 'utf8';
 866 
 867             return 'CREATE DATABASE ' . $this->quoteName($options->db_name) . ' CHARACTER SET `' . $charset . '`';
 868         }
 869 
 870         return 'CREATE DATABASE ' . $this->quoteName($options->db_name);
 871     }
 872 
 873     /**
 874      * Method to get the database collation in use by sampling a text field of a table in the database.
 875      *
 876      * @return  mixed  The collation in use by the database or boolean false if not supported.
 877      *
 878      * @since   11.1
 879      */
 880     abstract public function getCollation();
 881 
 882     /**
 883      * Method to get the database connection collation, as reported by the driver. If the connector doesn't support
 884      * reporting this value please return an empty string.
 885      *
 886      * @return  string
 887      */
 888     public function getConnectionCollation()
 889     {
 890         return '';
 891     }
 892 
 893     /**
 894      * Method that provides access to the underlying database connection. Useful for when you need to call a
 895      * proprietary method such as postgresql's lo_* methods.
 896      *
 897      * @return  resource  The underlying database connection resource.
 898      *
 899      * @since   11.1
 900      */
 901     public function getConnection()
 902     {
 903         return $this->connection;
 904     }
 905 
 906     /**
 907      * Get the total number of SQL statements executed by the database driver.
 908      *
 909      * @return  integer
 910      *
 911      * @since   11.1
 912      */
 913     public function getCount()
 914     {
 915         return $this->count;
 916     }
 917 
 918     /**
 919      * Gets the name of the database used by this conneciton.
 920      *
 921      * @return  string
 922      *
 923      * @since   11.4
 924      */
 925     protected function getDatabase()
 926     {
 927         return $this->_database;
 928     }
 929 
 930     /**
 931      * Returns a PHP date() function compliant date format for the database driver.
 932      *
 933      * @return  string  The format string.
 934      *
 935      * @since   11.1
 936      */
 937     public function getDateFormat()
 938     {
 939         return 'Y-m-d H:i:s';
 940     }
 941 
 942     /**
 943      * Get the database driver SQL statement log.
 944      *
 945      * @return  array  SQL statements executed by the database driver.
 946      *
 947      * @since   11.1
 948      */
 949     public function getLog()
 950     {
 951         return $this->log;
 952     }
 953 
 954     /**
 955      * Get the database driver SQL statement log.
 956      *
 957      * @return  array  SQL statements executed by the database driver.
 958      *
 959      * @since   CMS 3.1.2
 960      */
 961     public function getTimings()
 962     {
 963         return $this->timings;
 964     }
 965 
 966     /**
 967      * Get the database driver SQL statement log.
 968      *
 969      * @return  array  SQL statements executed by the database driver.
 970      *
 971      * @since   CMS 3.1.2
 972      */
 973     public function getCallStacks()
 974     {
 975         return $this->callStacks;
 976     }
 977 
 978     /**
 979      * Get the minimum supported database version.
 980      *
 981      * @return  string  The minimum version number for the database driver.
 982      *
 983      * @since   12.1
 984      */
 985     public function getMinimum()
 986     {
 987         return static::$dbMinimum;
 988     }
 989 
 990     /**
 991      * Get the null or zero representation of a timestamp for the database driver.
 992      *
 993      * @return  string  Null or zero representation of a timestamp.
 994      *
 995      * @since   11.1
 996      */
 997     public function getNullDate()
 998     {
 999         return $this->nullDate;
1000     }
1001 
1002     /**
1003      * Get the number of returned rows for the previous executed SQL statement.
1004      *
1005      * @param   resource  $cursor  An optional database cursor resource to extract the row count from.
1006      *
1007      * @return  integer   The number of returned rows.
1008      *
1009      * @since   11.1
1010      */
1011     abstract public function getNumRows($cursor = null);
1012 
1013     /**
1014      * Get the common table prefix for the database driver.
1015      *
1016      * @return  string  The common database table prefix.
1017      *
1018      * @since   11.1
1019      */
1020     public function getPrefix()
1021     {
1022         return $this->tablePrefix;
1023     }
1024 
1025     /**
1026      * Gets an exporter class object.
1027      *
1028      * @return  FOFDatabaseExporter  An exporter object.
1029      *
1030      * @since   12.1
1031      * @throws  RuntimeException
1032      */
1033     public function getExporter()
1034     {
1035         // Derive the class name from the driver.
1036         $class = 'FOFDatabaseExporter' . ucfirst($this->name);
1037 
1038         // Make sure we have an exporter class for this driver.
1039         if (!class_exists($class))
1040         {
1041             // If it doesn't exist we are at an impasse so throw an exception.
1042             throw new RuntimeException('Database Exporter not found.');
1043         }
1044 
1045         $o = new $class;
1046         $o->setDbo($this);
1047 
1048         return $o;
1049     }
1050 
1051     /**
1052      * Gets an importer class object.
1053      *
1054      * @return  FOFDatabaseImporter  An importer object.
1055      *
1056      * @since   12.1
1057      * @throws  RuntimeException
1058      */
1059     public function getImporter()
1060     {
1061         // Derive the class name from the driver.
1062         $class = 'FOFDatabaseImporter' . ucfirst($this->name);
1063 
1064         // Make sure we have an importer class for this driver.
1065         if (!class_exists($class))
1066         {
1067             // If it doesn't exist we are at an impasse so throw an exception.
1068             throw new RuntimeException('Database Importer not found');
1069         }
1070 
1071         $o = new $class;
1072         $o->setDbo($this);
1073 
1074         return $o;
1075     }
1076 
1077     /**
1078      * Get the name of the database driver. If $this->name is not set it will try guessing the driver name from the
1079      * class name.
1080      *
1081      * @return  string
1082      *
1083      * @since   CMS 3.5.0
1084      */
1085     public function getName()
1086     {
1087         if (empty($this->name))
1088         {
1089             $className = get_class($this);
1090             $className = str_replace('FOFDatabaseDriver', '', $className);
1091             $this->name = strtolower($className);
1092         }
1093 
1094         return $this->name;
1095     }
1096 
1097     /**
1098      * Get the server family type, e.g. mysql, postgresql, oracle, sqlite, mssql. If $this->serverType is not set it
1099      * will attempt guessing the server family type from the driver name. If this is not possible the driver name will
1100      * be returned instead.
1101      *
1102      * @return  string
1103      *
1104      * @since   CMS 3.5.0
1105      */
1106     public function getServerType()
1107     {
1108         if (empty($this->serverType))
1109         {
1110             $name = $this->getName();
1111 
1112             if (stristr($name, 'mysql') !== false)
1113             {
1114                 $this->serverType = 'mysql';
1115             }
1116             elseif (stristr($name, 'postgre') !== false)
1117             {
1118                 $this->serverType = 'postgresql';
1119             }
1120             elseif (stristr($name, 'oracle') !== false)
1121             {
1122                 $this->serverType = 'oracle';
1123             }
1124             elseif (stristr($name, 'sqlite') !== false)
1125             {
1126                 $this->serverType = 'sqlite';
1127             }
1128             elseif (stristr($name, 'sqlsrv') !== false)
1129             {
1130                 $this->serverType = 'mssql';
1131             }
1132             elseif (stristr($name, 'mssql') !== false)
1133             {
1134                 $this->serverType = 'mssql';
1135             }
1136             else
1137             {
1138                 $this->serverType = $name;
1139             }
1140         }
1141 
1142         return $this->serverType;
1143     }
1144 
1145     /**
1146      * Get the current query object or a new FOFDatabaseQuery object.
1147      *
1148      * @param   boolean  $new  False to return the current query object, True to return a new FOFDatabaseQuery object.
1149      *
1150      * @return  FOFDatabaseQuery  The current query object or a new object extending the FOFDatabaseQuery class.
1151      *
1152      * @since   11.1
1153      * @throws  RuntimeException
1154      */
1155     public function getQuery($new = false)
1156     {
1157         if ($new)
1158         {
1159             // Derive the class name from the driver.
1160             $class = 'FOFDatabaseQuery' . ucfirst($this->name);
1161 
1162             // Make sure we have a query class for this driver.
1163             if (!class_exists($class))
1164             {
1165                 // If it doesn't exist we are at an impasse so throw an exception.
1166                 throw new RuntimeException('Database Query Class not found.');
1167             }
1168 
1169             return new $class($this);
1170         }
1171         else
1172         {
1173             return $this->sql;
1174         }
1175     }
1176 
1177     /**
1178      * Get a new iterator on the current query.
1179      *
1180      * @param   string  $column  An option column to use as the iterator key.
1181      * @param   string  $class   The class of object that is returned.
1182      *
1183      * @return  FOFDatabaseIterator  A new database iterator.
1184      *
1185      * @since   12.1
1186      * @throws  RuntimeException
1187      */
1188     public function getIterator($column = null, $class = 'stdClass')
1189     {
1190         // Derive the class name from the driver.
1191         $iteratorClass = 'FOFDatabaseIterator' . ucfirst($this->name);
1192 
1193         // Make sure we have an iterator class for this driver.
1194         if (!class_exists($iteratorClass))
1195         {
1196             // If it doesn't exist we are at an impasse so throw an exception.
1197             throw new RuntimeException(sprintf('class *%s* is not defined', $iteratorClass));
1198         }
1199 
1200         // Return a new iterator
1201         return new $iteratorClass($this->execute(), $column, $class);
1202     }
1203 
1204     /**
1205      * Retrieves field information about the given tables.
1206      *
1207      * @param   string   $table     The name of the database table.
1208      * @param   boolean  $typeOnly  True (default) to only return field types.
1209      *
1210      * @return  array  An array of fields by table.
1211      *
1212      * @since   11.1
1213      * @throws  RuntimeException
1214      */
1215     abstract public function getTableColumns($table, $typeOnly = true);
1216 
1217     /**
1218      * Shows the table CREATE statement that creates the given tables.
1219      *
1220      * @param   mixed  $tables  A table name or a list of table names.
1221      *
1222      * @return  array  A list of the create SQL for the tables.
1223      *
1224      * @since   11.1
1225      * @throws  RuntimeException
1226      */
1227     abstract public function getTableCreate($tables);
1228 
1229     /**
1230      * Retrieves field information about the given tables.
1231      *
1232      * @param   mixed  $tables  A table name or a list of table names.
1233      *
1234      * @return  array  An array of keys for the table(s).
1235      *
1236      * @since   11.1
1237      * @throws  RuntimeException
1238      */
1239     abstract public function getTableKeys($tables);
1240 
1241     /**
1242      * Method to get an array of all tables in the database.
1243      *
1244      * @return  array  An array of all the tables in the database.
1245      *
1246      * @since   11.1
1247      * @throws  RuntimeException
1248      */
1249     abstract public function getTableList();
1250 
1251     /**
1252      * Determine whether or not the database engine supports UTF-8 character encoding.
1253      *
1254      * @return  boolean  True if the database engine supports UTF-8 character encoding.
1255      *
1256      * @since   11.1
1257      * @deprecated 12.3 (Platform) & 4.0 (CMS) - Use hasUTFSupport() instead
1258      */
1259     public function getUTFSupport()
1260     {
1261         if (class_exists('JLog'))
1262         {
1263             JLog::add('FOFDatabaseDriver::getUTFSupport() is deprecated. Use FOFDatabaseDriver::hasUTFSupport() instead.', JLog::WARNING, 'deprecated');
1264         }
1265 
1266         return $this->hasUTFSupport();
1267     }
1268 
1269     /**
1270      * Determine whether or not the database engine supports UTF-8 character encoding.
1271      *
1272      * @return  boolean  True if the database engine supports UTF-8 character encoding.
1273      *
1274      * @since   12.1
1275      */
1276     public function hasUTFSupport()
1277     {
1278         return $this->utf;
1279     }
1280 
1281     /**
1282      * Determine whether the database engine support the UTF-8 Multibyte (utf8mb4) character encoding. This applies to
1283      * MySQL databases.
1284      *
1285      * @return  boolean  True if the database engine supports UTF-8 Multibyte.
1286      *
1287      * @since   CMS 3.5.0
1288      */
1289     public function hasUTF8mb4Support()
1290     {
1291         return $this->utf8mb4;
1292     }
1293 
1294     /**
1295      * Get the version of the database connector
1296      *
1297      * @return  string  The database connector version.
1298      *
1299      * @since   11.1
1300      */
1301     abstract public function getVersion();
1302 
1303     /**
1304      * Method to get the auto-incremented value from the last INSERT statement.
1305      *
1306      * @return  mixed  The value of the auto-increment field from the last inserted row.
1307      *
1308      * @since   11.1
1309      */
1310     abstract public function insertid();
1311 
1312     /**
1313      * Inserts a row into a table based on an object's properties.
1314      *
1315      * @param   string  $table    The name of the database table to insert into.
1316      * @param   object  &$object  A reference to an object whose public properties match the table fields.
1317      * @param   string  $key      The name of the primary key. If provided the object property is updated.
1318      *
1319      * @return  boolean    True on success.
1320      *
1321      * @since   11.1
1322      * @throws  RuntimeException
1323      */
1324     public function insertObject($table, &$object, $key = null)
1325     {
1326         $fields = array();
1327         $values = array();
1328 
1329         // Iterate over the object variables to build the query fields and values.
1330         foreach (get_object_vars($object) as $k => $v)
1331         {
1332             // Only process non-null scalars.
1333             if (is_array($v) or is_object($v) or $v === null)
1334             {
1335                 continue;
1336             }
1337 
1338             // Ignore any internal fields.
1339             if ($k[0] == '_')
1340             {
1341                 continue;
1342             }
1343 
1344             // Prepare and sanitize the fields and values for the database query.
1345             $fields[] = $this->quoteName($k);
1346             $values[] = $this->quote($v);
1347         }
1348 
1349         // Create the base insert statement.
1350         $query = $this->getQuery(true)
1351             ->insert($this->quoteName($table))
1352             ->columns($fields)
1353             ->values(implode(',', $values));
1354 
1355         // Set the query and execute the insert.
1356         $this->setQuery($query);
1357 
1358         if (!$this->execute())
1359         {
1360             return false;
1361         }
1362 
1363         // Update the primary key if it exists.
1364         $id = $this->insertid();
1365 
1366         if ($key && $id && is_string($key))
1367         {
1368             $object->$key = $id;
1369         }
1370 
1371         return true;
1372     }
1373 
1374     /**
1375      * Method to check whether the installed database version is supported by the database driver
1376      *
1377      * @return  boolean  True if the database version is supported
1378      *
1379      * @since   12.1
1380      */
1381     public function isMinimumVersion()
1382     {
1383         return version_compare($this->getVersion(), static::$dbMinimum) >= 0;
1384     }
1385 
1386     /**
1387      * Method to get the first row of the result set from the database query as an associative array
1388      * of ['field_name' => 'row_value'].
1389      *
1390      * @return  mixed  The return value or null if the query failed.
1391      *
1392      * @since   11.1
1393      * @throws  RuntimeException
1394      */
1395     public function loadAssoc()
1396     {
1397         $this->connect();
1398 
1399         $ret = null;
1400 
1401         // Execute the query and get the result set cursor.
1402         if (!($cursor = $this->execute()))
1403         {
1404             return null;
1405         }
1406 
1407         // Get the first row from the result set as an associative array.
1408         if ($array = $this->fetchAssoc($cursor))
1409         {
1410             $ret = $array;
1411         }
1412 
1413         // Free up system resources and return.
1414         $this->freeResult($cursor);
1415 
1416         return $ret;
1417     }
1418 
1419     /**
1420      * Method to get an array of the result set rows from the database query where each row is an associative array
1421      * of ['field_name' => 'row_value'].  The array of rows can optionally be keyed by a field name, but defaults to
1422      * a sequential numeric array.
1423      *
1424      * NOTE: Chosing to key the result array by a non-unique field name can result in unwanted
1425      * behavior and should be avoided.
1426      *
1427      * @param   string  $key     The name of a field on which to key the result array.
1428      * @param   string  $column  An optional column name. Instead of the whole row, only this column value will be in
1429      * the result array.
1430      *
1431      * @return  mixed   The return value or null if the query failed.
1432      *
1433      * @since   11.1
1434      * @throws  RuntimeException
1435      */
1436     public function loadAssocList($key = null, $column = null)
1437     {
1438         $this->connect();
1439 
1440         $array = array();
1441 
1442         // Execute the query and get the result set cursor.
1443         if (!($cursor = $this->execute()))
1444         {
1445             return null;
1446         }
1447 
1448         // Get all of the rows from the result set.
1449         while ($row = $this->fetchAssoc($cursor))
1450         {
1451             $value = ($column) ? (isset($row[$column]) ? $row[$column] : $row) : $row;
1452 
1453             if ($key)
1454             {
1455                 $array[$row[$key]] = $value;
1456             }
1457             else
1458             {
1459                 $array[] = $value;
1460             }
1461         }
1462 
1463         // Free up system resources and return.
1464         $this->freeResult($cursor);
1465 
1466         return $array;
1467     }
1468 
1469     /**
1470      * Method to get an array of values from the <var>$offset</var> field in each row of the result set from
1471      * the database query.
1472      *
1473      * @param   integer  $offset  The row offset to use to build the result array.
1474      *
1475      * @return  mixed    The return value or null if the query failed.
1476      *
1477      * @since   11.1
1478      * @throws  RuntimeException
1479      */
1480     public function loadColumn($offset = 0)
1481     {
1482         $this->connect();
1483 
1484         $array = array();
1485 
1486         // Execute the query and get the result set cursor.
1487         if (!($cursor = $this->execute()))
1488         {
1489             return null;
1490         }
1491 
1492         // Get all of the rows from the result set as arrays.
1493         while ($row = $this->fetchArray($cursor))
1494         {
1495             $array[] = $row[$offset];
1496         }
1497 
1498         // Free up system resources and return.
1499         $this->freeResult($cursor);
1500 
1501         return $array;
1502     }
1503 
1504     /**
1505      * Method to get the next row in the result set from the database query as an object.
1506      *
1507      * @param   string  $class  The class name to use for the returned row object.
1508      *
1509      * @return  mixed   The result of the query as an array, false if there are no more rows.
1510      *
1511      * @since   11.1
1512      * @throws  RuntimeException
1513      * @deprecated  12.3 (Platform) & 4.0 (CMS) - Use getIterator() instead
1514      */
1515     public function loadNextObject($class = 'stdClass')
1516     {
1517         if (class_exists('JLog'))
1518         {
1519             JLog::add(__METHOD__ . '() is deprecated. Use FOFDatabaseDriver::getIterator() instead.', JLog::WARNING, 'deprecated');
1520         }
1521 
1522         $this->connect();
1523 
1524         static $cursor = null;
1525 
1526         // Execute the query and get the result set cursor.
1527         if ( is_null($cursor) )
1528         {
1529             if (!($cursor = $this->execute()))
1530             {
1531                 return $this->errorNum ? null : false;
1532             }
1533         }
1534 
1535         // Get the next row from the result set as an object of type $class.
1536         if ($row = $this->fetchObject($cursor, $class))
1537         {
1538             return $row;
1539         }
1540 
1541         // Free up system resources and return.
1542         $this->freeResult($cursor);
1543         $cursor = null;
1544 
1545         return false;
1546     }
1547 
1548     /**
1549      * Method to get the next row in the result set from the database query as an array.
1550      *
1551      * @return  mixed  The result of the query as an array, false if there are no more rows.
1552      *
1553      * @since   11.1
1554      * @throws  RuntimeException
1555      * @deprecated  4.0 (CMS)  Use FOFDatabaseDriver::getIterator() instead
1556      */
1557     public function loadNextRow()
1558     {
1559         if (class_exists('JLog'))
1560         {
1561             JLog::add(__METHOD__ . '() is deprecated. Use FOFDatabaseDriver::getIterator() instead.', JLog::WARNING, 'deprecated');
1562         }
1563 
1564         $this->connect();
1565 
1566         static $cursor = null;
1567 
1568         // Execute the query and get the result set cursor.
1569         if ( is_null($cursor) )
1570         {
1571             if (!($cursor = $this->execute()))
1572             {
1573                 return $this->errorNum ? null : false;
1574             }
1575         }
1576 
1577         // Get the next row from the result set as an object of type $class.
1578         if ($row = $this->fetchArray($cursor))
1579         {
1580             return $row;
1581         }
1582 
1583         // Free up system resources and return.
1584         $this->freeResult($cursor);
1585         $cursor = null;
1586 
1587         return false;
1588     }
1589 
1590     /**
1591      * Method to get the first row of the result set from the database query as an object.
1592      *
1593      * @param   string  $class  The class name to use for the returned row object.
1594      *
1595      * @return  mixed   The return value or null if the query failed.
1596      *
1597      * @since   11.1
1598      * @throws  RuntimeException
1599      */
1600     public function loadObject($class = 'stdClass')
1601     {
1602         $this->connect();
1603 
1604         $ret = null;
1605 
1606         // Execute the query and get the result set cursor.
1607         if (!($cursor = $this->execute()))
1608         {
1609             return null;
1610         }
1611 
1612         // Get the first row from the result set as an object of type $class.
1613         if ($object = $this->fetchObject($cursor, $class))
1614         {
1615             $ret = $object;
1616         }
1617 
1618         // Free up system resources and return.
1619         $this->freeResult($cursor);
1620 
1621         return $ret;
1622     }
1623 
1624     /**
1625      * Method to get an array of the result set rows from the database query where each row is an object.  The array
1626      * of objects can optionally be keyed by a field name, but defaults to a sequential numeric array.
1627      *
1628      * NOTE: Choosing to key the result array by a non-unique field name can result in unwanted
1629      * behavior and should be avoided.
1630      *
1631      * @param   string  $key    The name of a field on which to key the result array.
1632      * @param   string  $class  The class name to use for the returned row objects.
1633      *
1634      * @return  mixed   The return value or null if the query failed.
1635      *
1636      * @since   11.1
1637      * @throws  RuntimeException
1638      */
1639     public function loadObjectList($key = '', $class = 'stdClass')
1640     {
1641         $this->connect();
1642 
1643         $array = array();
1644 
1645         // Execute the query and get the result set cursor.
1646         if (!($cursor = $this->execute()))
1647         {
1648             return null;
1649         }
1650 
1651         // Get all of the rows from the result set as objects of type $class.
1652         while ($row = $this->fetchObject($cursor, $class))
1653         {
1654             if ($key)
1655             {
1656                 $array[$row->$key] = $row;
1657             }
1658             else
1659             {
1660                 $array[] = $row;
1661             }
1662         }
1663 
1664         // Free up system resources and return.
1665         $this->freeResult($cursor);
1666 
1667         return $array;
1668     }
1669 
1670     /**
1671      * Method to get the first field of the first row of the result set from the database query.
1672      *
1673      * @return  mixed  The return value or null if the query failed.
1674      *
1675      * @since   11.1
1676      * @throws  RuntimeException
1677      */
1678     public function loadResult()
1679     {
1680         $this->connect();
1681 
1682         $ret = null;
1683 
1684         // Execute the query and get the result set cursor.
1685         if (!($cursor = $this->execute()))
1686         {
1687             return null;
1688         }
1689 
1690         // Get the first row from the result set as an array.
1691         if ($row = $this->fetchArray($cursor))
1692         {
1693             $ret = $row[0];
1694         }
1695 
1696         // Free up system resources and return.
1697         $this->freeResult($cursor);
1698 
1699         return $ret;
1700     }
1701 
1702     /**
1703      * Method to get the first row of the result set from the database query as an array.  Columns are indexed
1704      * numerically so the first column in the result set would be accessible via <var>$row[0]</var>, etc.
1705      *
1706      * @return  mixed  The return value or null if the query failed.
1707      *
1708      * @since   11.1
1709      * @throws  RuntimeException
1710      */
1711     public function loadRow()
1712     {
1713         $this->connect();
1714 
1715         $ret = null;
1716 
1717         // Execute the query and get the result set cursor.
1718         if (!($cursor = $this->execute()))
1719         {
1720             return null;
1721         }
1722 
1723         // Get the first row from the result set as an array.
1724         if ($row = $this->fetchArray($cursor))
1725         {
1726             $ret = $row;
1727         }
1728 
1729         // Free up system resources and return.
1730         $this->freeResult($cursor);
1731 
1732         return $ret;
1733     }
1734 
1735     /**
1736      * Method to get an array of the result set rows from the database query where each row is an array.  The array
1737      * of objects can optionally be keyed by a field offset, but defaults to a sequential numeric array.
1738      *
1739      * NOTE: Choosing to key the result array by a non-unique field can result in unwanted
1740      * behavior and should be avoided.
1741      *
1742      * @param   string  $key  The name of a field on which to key the result array.
1743      *
1744      * @return  mixed   The return value or null if the query failed.
1745      *
1746      * @since   11.1
1747      * @throws  RuntimeException
1748      */
1749     public function loadRowList($key = null)
1750     {
1751         $this->connect();
1752 
1753         $array = array();
1754 
1755         // Execute the query and get the result set cursor.
1756         if (!($cursor = $this->execute()))
1757         {
1758             return null;
1759         }
1760 
1761         // Get all of the rows from the result set as arrays.
1762         while ($row = $this->fetchArray($cursor))
1763         {
1764             if ($key !== null)
1765             {
1766                 $array[$row[$key]] = $row;
1767             }
1768             else
1769             {
1770                 $array[] = $row;
1771             }
1772         }
1773 
1774         // Free up system resources and return.
1775         $this->freeResult($cursor);
1776 
1777         return $array;
1778     }
1779 
1780     /**
1781      * Locks a table in the database.
1782      *
1783      * @param   string  $tableName  The name of the table to unlock.
1784      *
1785      * @return  FOFDatabaseDriver     Returns this object to support chaining.
1786      *
1787      * @since   11.4
1788      * @throws  RuntimeException
1789      */
1790     public abstract function lockTable($tableName);
1791 
1792     /**
1793      * Quotes and optionally escapes a string to database requirements for use in database queries.
1794      *
1795      * @param   mixed    $text    A string or an array of strings to quote.
1796      * @param   boolean  $escape  True (default) to escape the string, false to leave it unchanged.
1797      *
1798      * @return  string  The quoted input string.
1799      *
1800      * @note    Accepting an array of strings was added in 12.3.
1801      * @since   11.1
1802      */
1803     public function quote($text, $escape = true)
1804     {
1805         if (is_array($text))
1806         {
1807             foreach ($text as $k => $v)
1808             {
1809                 $text[$k] = $this->quote($v, $escape);
1810             }
1811 
1812             return $text;
1813         }
1814         else
1815         {
1816             return '\'' . ($escape ? $this->escape($text) : $text) . '\'';
1817         }
1818     }
1819 
1820     /**
1821      * Wrap an SQL statement identifier name such as column, table or database names in quotes to prevent injection
1822      * risks and reserved word conflicts.
1823      *
1824      * @param   mixed  $name  The identifier name to wrap in quotes, or an array of identifier names to wrap in quotes.
1825      *                        Each type supports dot-notation name.
1826      * @param   mixed  $as    The AS query part associated to $name. It can be string or array, in latter case it has to be
1827      *                        same length of $name; if is null there will not be any AS part for string or array element.
1828      *
1829      * @return  mixed  The quote wrapped name, same type of $name.
1830      *
1831      * @since   11.1
1832      */
1833     public function quoteName($name, $as = null)
1834     {
1835         if (is_string($name))
1836         {
1837             $quotedName = $this->quoteNameStr(explode('.', $name));
1838 
1839             $quotedAs = '';
1840 
1841             if (!is_null($as))
1842             {
1843                 settype($as, 'array');
1844                 $quotedAs .= ' AS ' . $this->quoteNameStr($as);
1845             }
1846 
1847             return $quotedName . $quotedAs;
1848         }
1849         else
1850         {
1851             $fin = array();
1852 
1853             if (is_null($as))
1854             {
1855                 foreach ($name as $str)
1856                 {
1857                     $fin[] = $this->quoteName($str);
1858                 }
1859             }
1860             elseif (is_array($name) && (count($name) == count($as)))
1861             {
1862                 $count = count($name);
1863 
1864                 for ($i = 0; $i < $count; $i++)
1865                 {
1866                     $fin[] = $this->quoteName($name[$i], $as[$i]);
1867                 }
1868             }
1869 
1870             return $fin;
1871         }
1872     }
1873 
1874     /**
1875      * Quote strings coming from quoteName call.
1876      *
1877      * @param   array  $strArr  Array of strings coming from quoteName dot-explosion.
1878      *
1879      * @return  string  Dot-imploded string of quoted parts.
1880      *
1881      * @since 11.3
1882      */
1883     protected function quoteNameStr($strArr)
1884     {
1885         $parts = array();
1886         $q = $this->nameQuote;
1887 
1888         foreach ($strArr as $part)
1889         {
1890             if (is_null($part))
1891             {
1892                 continue;
1893             }
1894 
1895             if (strlen($q) == 1)
1896             {
1897                 $parts[] = $q . $part . $q;
1898             }
1899             else
1900             {
1901                 $parts[] = $q{0} . $part . $q{1};
1902             }
1903         }
1904 
1905         return implode('.', $parts);
1906     }
1907 
1908     /**
1909      * This function replaces a string identifier <var>$prefix</var> with the string held is the
1910      * <var>tablePrefix</var> class variable.
1911      *
1912      * @param   string  $sql     The SQL statement to prepare.
1913      * @param   string  $prefix  The common table prefix.
1914      *
1915      * @return  string  The processed SQL statement.
1916      *
1917      * @since   11.1
1918      */
1919     public function replacePrefix($sql, $prefix = '#__')
1920     {
1921         $startPos = 0;
1922         $literal = '';
1923 
1924         $sql = trim($sql);
1925         $n = strlen($sql);
1926 
1927         while ($startPos < $n)
1928         {
1929             $ip = strpos($sql, $prefix, $startPos);
1930 
1931             if ($ip === false)
1932             {
1933                 break;
1934             }
1935 
1936             $j = strpos($sql, "'", $startPos);
1937             $k = strpos($sql, '"', $startPos);
1938 
1939             if (($k !== false) && (($k < $j) || ($j === false)))
1940             {
1941                 $quoteChar = '"';
1942                 $j = $k;
1943             }
1944             else
1945             {
1946                 $quoteChar = "'";
1947             }
1948 
1949             if ($j === false)
1950             {
1951                 $j = $n;
1952             }
1953 
1954             $literal .= str_replace($prefix, $this->tablePrefix, substr($sql, $startPos, $j - $startPos));
1955             $startPos = $j;
1956 
1957             $j = $startPos + 1;
1958 
1959             if ($j >= $n)
1960             {
1961                 break;
1962             }
1963 
1964             // Quote comes first, find end of quote
1965             while (true)
1966             {
1967                 $k = strpos($sql, $quoteChar, $j);
1968                 $escaped = false;
1969 
1970                 if ($k === false)
1971                 {
1972                     break;
1973                 }
1974 
1975                 $l = $k - 1;
1976 
1977                 while ($l >= 0 && $sql{$l} == '\\')
1978                 {
1979                     $l--;
1980                     $escaped = !$escaped;
1981                 }
1982 
1983                 if ($escaped)
1984                 {
1985                     $j = $k + 1;
1986                     continue;
1987                 }
1988 
1989                 break;
1990             }
1991 
1992             if ($k === false)
1993             {
1994                 // Error in the query - no end quote; ignore it
1995                 break;
1996             }
1997 
1998             $literal .= substr($sql, $startPos, $k - $startPos + 1);
1999             $startPos = $k + 1;
2000         }
2001 
2002         if ($startPos < $n)
2003         {
2004             $literal .= substr($sql, $startPos, $n - $startPos);
2005         }
2006 
2007         return $literal;
2008     }
2009 
2010     /**
2011      * Renames a table in the database.
2012      *
2013      * @param   string  $oldTable  The name of the table to be renamed
2014      * @param   string  $newTable  The new name for the table.
2015      * @param   string  $backup    Table prefix
2016      * @param   string  $prefix    For the table - used to rename constraints in non-mysql databases
2017      *
2018      * @return  FOFDatabaseDriver    Returns this object to support chaining.
2019      *
2020      * @since   11.4
2021      * @throws  RuntimeException
2022      */
2023     public abstract function renameTable($oldTable, $newTable, $backup = null, $prefix = null);
2024 
2025     /**
2026      * Select a database for use.
2027      *
2028      * @param   string  $database  The name of the database to select for use.
2029      *
2030      * @return  boolean  True if the database was successfully selected.
2031      *
2032      * @since   11.1
2033      * @throws  RuntimeException
2034      */
2035     abstract public function select($database);
2036 
2037     /**
2038      * Sets the database debugging state for the driver.
2039      *
2040      * @param   boolean  $level  True to enable debugging.
2041      *
2042      * @return  boolean  The old debugging level.
2043      *
2044      * @since   11.1
2045      */
2046     public function setDebug($level)
2047     {
2048         $previous = $this->debug;
2049         $this->debug = (bool) $level;
2050 
2051         return $previous;
2052     }
2053 
2054     /**
2055      * Sets the SQL statement string for later execution.
2056      *
2057      * @param   mixed    $query   The SQL statement to set either as a FOFDatabaseQuery object or a string.
2058      * @param   integer  $offset  The affected row offset to set.
2059      * @param   integer  $limit   The maximum affected rows to set.
2060      *
2061      * @return  FOFDatabaseDriver  This object to support method chaining.
2062      *
2063      * @since   11.1
2064      */
2065     public function setQuery($query, $offset = 0, $limit = 0)
2066     {
2067         $this->sql = $query;
2068 
2069         if ($query instanceof FOFDatabaseQueryLimitable)
2070         {
2071             if (!$limit && $query->limit)
2072             {
2073                 $limit = $query->limit;
2074             }
2075 
2076             if (!$offset && $query->offset)
2077             {
2078                 $offset = $query->offset;
2079             }
2080 
2081             $query->setLimit($limit, $offset);
2082         }
2083         else
2084         {
2085             $this->limit = (int) max(0, $limit);
2086             $this->offset = (int) max(0, $offset);
2087         }
2088 
2089         return $this;
2090     }
2091 
2092     /**
2093      * Set the connection to use UTF-8 character encoding.
2094      *
2095      * @return  boolean  True on success.
2096      *
2097      * @since   11.1
2098      */
2099     abstract public function setUtf();
2100 
2101     /**
2102      * Method to commit a transaction.
2103      *
2104      * @param   boolean  $toSavepoint  If true, commit to the last savepoint.
2105      *
2106      * @return  void
2107      *
2108      * @since   11.1
2109      * @throws  RuntimeException
2110      */
2111     abstract public function transactionCommit($toSavepoint = false);
2112 
2113     /**
2114      * Method to roll back a transaction.
2115      *
2116      * @param   boolean  $toSavepoint  If true, rollback to the last savepoint.
2117      *
2118      * @return  void
2119      *
2120      * @since   11.1
2121      * @throws  RuntimeException
2122      */
2123     abstract public function transactionRollback($toSavepoint = false);
2124 
2125     /**
2126      * Method to initialize a transaction.
2127      *
2128      * @param   boolean  $asSavepoint  If true and a transaction is already active, a savepoint will be created.
2129      *
2130      * @return  void
2131      *
2132      * @since   11.1
2133      * @throws  RuntimeException
2134      */
2135     abstract public function transactionStart($asSavepoint = false);
2136 
2137     /**
2138      * Method to truncate a table.
2139      *
2140      * @param   string  $table  The table to truncate
2141      *
2142      * @return  void
2143      *
2144      * @since   11.3
2145      * @throws  RuntimeException
2146      */
2147     public function truncateTable($table)
2148     {
2149         $this->setQuery('TRUNCATE TABLE ' . $this->quoteName($table));
2150         $this->execute();
2151     }
2152 
2153     /**
2154      * Updates a row in a table based on an object's properties.
2155      *
2156      * @param   string   $table    The name of the database table to update.
2157      * @param   object   &$object  A reference to an object whose public properties match the table fields.
2158      * @param   array    $key      The name of the primary key.
2159      * @param   boolean  $nulls    True to update null fields or false to ignore them.
2160      *
2161      * @return  boolean  True on success.
2162      *
2163      * @since   11.1
2164      * @throws  RuntimeException
2165      */
2166     public function updateObject($table, &$object, $key, $nulls = false)
2167     {
2168         $fields = array();
2169         $where = array();
2170 
2171         if (is_string($key))
2172         {
2173             $key = array($key);
2174         }
2175 
2176         if (is_object($key))
2177         {
2178             $key = (array) $key;
2179         }
2180 
2181         // Create the base update statement.
2182         $statement = 'UPDATE ' . $this->quoteName($table) . ' SET %s WHERE %s';
2183 
2184         // Iterate over the object variables to build the query fields/value pairs.
2185         foreach (get_object_vars($object) as $k => $v)
2186         {
2187             // Only process scalars that are not internal fields.
2188             if (is_array($v) or is_object($v) or $k[0] == '_')
2189             {
2190                 continue;
2191             }
2192 
2193             // Set the primary key to the WHERE clause instead of a field to update.
2194             if (in_array($k, $key))
2195             {
2196                 $where[] = $this->quoteName($k) . '=' . $this->quote($v);
2197                 continue;
2198             }
2199 
2200             // Prepare and sanitize the fields and values for the database query.
2201             if ($v === null)
2202             {
2203                 // If the value is null and we want to update nulls then set it.
2204                 if ($nulls)
2205                 {
2206                     $val = 'NULL';
2207                 }
2208                 // If the value is null and we do not want to update nulls then ignore this field.
2209                 else
2210                 {
2211                     continue;
2212                 }
2213             }
2214             // The field is not null so we prep it for update.
2215             else
2216             {
2217                 $val = $this->quote($v);
2218             }
2219 
2220             // Add the field to be updated.
2221             $fields[] = $this->quoteName($k) . '=' . $val;
2222         }
2223 
2224         // We don't have any fields to update.
2225         if (empty($fields))
2226         {
2227             return true;
2228         }
2229 
2230         // Set the query and execute the update.
2231         $this->setQuery(sprintf($statement, implode(",", $fields), implode(' AND ', $where)));
2232 
2233         return $this->execute();
2234     }
2235 
2236     /**
2237      * Execute the SQL statement.
2238      *
2239      * @return  mixed  A database cursor resource on success, boolean false on failure.
2240      *
2241      * @since   12.1
2242      * @throws  RuntimeException
2243      */
2244     abstract public function execute();
2245 
2246     /**
2247      * Unlocks tables in the database.
2248      *
2249      * @return  FOFDatabaseDriver  Returns this object to support chaining.
2250      *
2251      * @since   11.4
2252      * @throws  RuntimeException
2253      */
2254     public abstract function unlockTables();
2255 }
2256 
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.