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  utils
   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 
   9 // Protect from unauthorized access
  10 defined('FOF_INCLUDED') or die;
  11 
  12 if (version_compare(JVERSION, '2.5.0', 'lt'))
  13 {
  14     jimport('joomla.updater.updater');
  15 }
  16 
  17 /**
  18  * A helper Model to interact with Joomla!'s extensions update feature
  19  */
  20 class FOFUtilsUpdate extends FOFModel
  21 {
  22     /** @var JUpdater The Joomla! updater object */
  23     protected $updater = null;
  24 
  25     /** @var int The extension_id of this component */
  26     protected $extension_id = 0;
  27 
  28     /** @var string The currently installed version, as reported by the #__extensions table */
  29     protected $version = 'dev';
  30 
  31     /** @var string The machine readable name of the component e.g. com_something */
  32     protected $component = 'com_foobar';
  33 
  34     /** @var string The human readable name of the component e.g. Your Component's Name. Used for emails. */
  35     protected $componentDescription = 'Foobar';
  36 
  37     /** @var string The URL to the component's update XML stream */
  38     protected $updateSite = null;
  39 
  40     /** @var string The name to the component's update site (description of the update XML stream) */
  41     protected $updateSiteName = null;
  42 
  43     /** @var string The extra query to append to (commercial) components' download URLs */
  44     protected $extraQuery = null;
  45 
  46     /** @var string The common parameters' key, used for storing data in the #__akeeba_common table */
  47     protected $commonKey = 'foobar';
  48 
  49     /**
  50      * The common parameters table. It's a simple table with key(VARCHAR) and value(LONGTEXT) fields.
  51      * Here is an example MySQL CREATE TABLE command to make this kind of table:
  52      *
  53      * CREATE TABLE `#__akeeba_common` (
  54      *  `key` varchar(255) NOT NULL,
  55      *  `value` longtext NOT NULL,
  56      *  PRIMARY KEY (`key`)
  57      *  ) DEFAULT COLLATE utf8_general_ci CHARSET=utf8;
  58      *
  59      * @var  string
  60      */
  61     protected $commonTable = '#__akeeba_common';
  62 
  63     /**
  64      * Subject of the component update emails
  65      *
  66      * @var  string
  67      */
  68     protected $updateEmailSubject = 'THIS EMAIL IS SENT FROM YOUR SITE "[SITENAME]" - Update available for [COMPONENT], new version [VERSION]';
  69 
  70     /**
  71      * Body of the component update email
  72      *
  73      * @var  string
  74      */
  75     protected $updateEmailBody= <<< ENDBLOCK
  76 This email IS NOT sent by the authors of [COMPONENT].
  77 It is sent automatically by your own site, [SITENAME].
  78 
  79 ================================================================================
  80 UPDATE INFORMATION
  81 ================================================================================
  82 
  83 Your site has determined that there is an updated version of [COMPONENT]
  84 available for download.
  85 
  86 New version number: [VERSION]
  87 
  88 This email is sent to you by your site to remind you of this fact. The authors
  89 of the software will never contact you about available updates.
  90 
  91 ================================================================================
  92 WHY AM I RECEIVING THIS EMAIL?
  93 ================================================================================
  94 
  95 This email has been automatically sent by a CLI script or Joomla! plugin you, or
  96 the person who built or manages your site, has installed and explicitly
  97 activated. This script or plugin looks for updated versions of the software and
  98 sends an email notification to all Super Users. You will receive several similar
  99 emails from your site, up to 6 times per day, until you either update the
 100 software or disable these emails.
 101 
 102 To disable these emails, please contact your site administrator.
 103 
 104 If you do not understand what this means, please do not contact the authors of
 105 the software. They are NOT sending you this email and they cannot help you.
 106 Instead, please contact the person who built or manages your site.
 107 
 108 ================================================================================
 109 WHO SENT ME THIS EMAIL?
 110 ================================================================================
 111 
 112 This email is sent to you by your own site, [SITENAME]
 113 ENDBLOCK;
 114 
 115     /**
 116      * Public constructor. Initialises the protected members as well. Useful $config keys:
 117      * update_component     The component name, e.g. com_foobar
 118      * update_version       The default version if the manifest cache is unreadable
 119      * update_site          The URL to the component's update XML stream
 120      * update_extraquery    The extra query to append to (commercial) components' download URLs
 121      * update_sitename      The update site's name (description)
 122      *
 123      * @param array $config
 124      */
 125     public function __construct($config = array())
 126     {
 127         parent::__construct($config);
 128 
 129         // Get an instance of the updater class
 130         $this->updater = JUpdater::getInstance();
 131 
 132         // Get the component name
 133         if (isset($config['update_component']))
 134         {
 135             $this->component = $config['update_component'];
 136         }
 137         else
 138         {
 139             $this->component = $this->input->getCmd('option', '');
 140         }
 141 
 142         // Get the component description
 143         if (isset($config['update_component_description']))
 144         {
 145             $this->component = $config['update_component_description'];
 146         }
 147         else
 148         {
 149             // Try to auto-translate (hopefully you've loaded the language files)
 150             $key = strtoupper($this->component);
 151             $description = JText::_($key);
 152         }
 153 
 154         // Get the component version
 155         if (isset($config['update_version']))
 156         {
 157             $this->version = $config['update_version'];
 158         }
 159 
 160         // Get the common key
 161         if (isset($config['common_key']))
 162         {
 163             $this->commonKey = $config['common_key'];
 164         }
 165         else
 166         {
 167             // Convert com_foobar, pkg_foobar etc to "foobar"
 168             $this->commonKey = substr($this->component, 4);
 169         }
 170 
 171         // Get the update site
 172         if (isset($config['update_site']))
 173         {
 174             $this->updateSite = $config['update_site'];
 175         }
 176 
 177         // Get the extra query
 178         if (isset($config['update_extraquery']))
 179         {
 180             $this->extraQuery = $config['update_extraquery'];
 181         }
 182 
 183         // Get the update site's name
 184         if (isset($config['update_sitename']))
 185         {
 186             $this->updateSiteName = $config['update_sitename'];
 187         }
 188 
 189         // Find the extension ID
 190         $db = FOFPlatform::getInstance()->getDbo();
 191         $query = $db->getQuery(true)
 192             ->select('*')
 193             ->from($db->qn('#__extensions'))
 194             ->where($db->qn('type') . ' = ' . $db->q('component'))
 195             ->where($db->qn('element') . ' = ' . $db->q($this->component));
 196         $db->setQuery($query);
 197         $extension = $db->loadObject();
 198 
 199         if (is_object($extension))
 200         {
 201             $this->extension_id = $extension->extension_id;
 202             $data = json_decode($extension->manifest_cache, true);
 203 
 204             if (isset($data['version']))
 205             {
 206                 $this->version = $data['version'];
 207             }
 208         }
 209     }
 210 
 211     /**
 212      * Retrieves the update information of the component, returning an array with the following keys:
 213      *
 214      * hasUpdate    True if an update is available
 215      * version      The version of the available update
 216      * infoURL      The URL to the download page of the update
 217      *
 218      * @param   bool    $force            Set to true if you want to forcibly reload the update information
 219      * @param   string  $preferredMethod  Preferred update method: 'joomla' or 'classic'
 220      *
 221      * @return  array  See the method description for more information
 222      */
 223     public function getUpdates($force = false, $preferredMethod = null)
 224     {
 225         // Default response (no update)
 226         $updateResponse = array(
 227             'hasUpdate' => false,
 228             'version'   => '',
 229             'infoURL'   => '',
 230             'downloadURL' => '',
 231         );
 232 
 233         if (empty($this->extension_id))
 234         {
 235             return $updateResponse;
 236         }
 237 
 238         $updateRecord = $this->findUpdates($force, $preferredMethod);
 239 
 240         // If we have an update record in the database return the information found there
 241         if (is_object($updateRecord))
 242         {
 243             $updateResponse = array(
 244                 'hasUpdate' => true,
 245                 'version'   => $updateRecord->version,
 246                 'infoURL'   => $updateRecord->infourl,
 247                 'downloadURL' => $updateRecord->downloadurl,
 248             );
 249         }
 250 
 251         return $updateResponse;
 252     }
 253 
 254     /**
 255      * Find the available update record object. If we're at the latest version it will return null.
 256      *
 257      * Please see getUpdateMethod for information on how the $preferredMethod is handled and what it means.
 258      *
 259      * @param   bool    $force            Should I forcibly reload the updates from the server?
 260      * @param   string  $preferredMethod  Preferred update method: 'joomla' or 'classic'
 261      *
 262      * @return  \stdClass|null
 263      */
 264     public function findUpdates($force, $preferredMethod = null)
 265     {
 266         $preferredMethod = $this->getUpdateMethod($preferredMethod);
 267 
 268         switch ($preferredMethod)
 269         {
 270             case 'joomla':
 271                 return $this->findUpdatesJoomla($force);
 272                 break;
 273 
 274             default:
 275             case 'classic':
 276                 return $this->findUpdatesClassic($force);
 277                 break;
 278         }
 279     }
 280 
 281     /**
 282      * Gets the update site Ids for our extension.
 283      *
 284      * @return  mixed   An array of Ids or null if the query failed.
 285      */
 286     public function getUpdateSiteIds()
 287     {
 288         $db = FOFPlatform::getInstance()->getDbo();
 289         $query = $db->getQuery(true)
 290                     ->select($db->qn('update_site_id'))
 291                     ->from($db->qn('#__update_sites_extensions'))
 292                     ->where($db->qn('extension_id') . ' = ' . $db->q($this->extension_id));
 293         $db->setQuery($query);
 294         $updateSiteIds = $db->loadColumn(0);
 295 
 296         return $updateSiteIds;
 297     }
 298 
 299     /**
 300      * Get the currently installed version as reported by the #__extensions table
 301      *
 302      * @return  string
 303      */
 304     public function getVersion()
 305     {
 306         return $this->version;
 307     }
 308 
 309     /**
 310      * Returns the name of the component, e.g. com_foobar
 311      *
 312      * @return  string
 313      */
 314     public function getComponentName()
 315     {
 316         return $this->component;
 317     }
 318 
 319     /**
 320      * Returns the human readable component name, e.g. Foobar Component
 321      *
 322      * @return  string
 323      */
 324     public function getComponentDescription()
 325     {
 326         return $this->componentDescription;
 327     }
 328 
 329     /**
 330      * Returns the numeric extension ID for the component
 331      *
 332      * @return  int
 333      */
 334     public function getExtensionId()
 335     {
 336         return $this->extension_id;
 337     }
 338 
 339     /**
 340      * Returns the update site URL, i.e. the URL to the XML update stream
 341      *
 342      * @return  string
 343      */
 344     public function getUpdateSite()
 345     {
 346         return $this->updateSite;
 347     }
 348 
 349     /**
 350      * Returns the human readable description of the update site
 351      *
 352      * @return  string
 353      */
 354     public function getUpdateSiteName()
 355     {
 356         return $this->updateSiteName;
 357     }
 358 
 359     /**
 360      * Override the currently installed version as reported by the #__extensions table
 361      *
 362      * @param  string  $version
 363      */
 364     public function setVersion($version)
 365     {
 366         $this->version = $version;
 367     }
 368 
 369     /**
 370      * Refreshes the Joomla! update sites for this extension as needed
 371      *
 372      * @return  void
 373      */
 374     public function refreshUpdateSite()
 375     {
 376         // Joomla! 1.5 does not have update sites.
 377         if (version_compare(JVERSION, '1.6.0', 'lt'))
 378         {
 379             return;
 380         }
 381 
 382         if (empty($this->extension_id))
 383         {
 384             return;
 385         }
 386 
 387         // Remove obsolete update sites that don't match our extension ID but match our name or update site location
 388         $this->removeObsoleteUpdateSites();
 389 
 390         // Create the update site definition we want to store to the database
 391         $update_site = array(
 392                 'name'      => $this->updateSiteName,
 393                 'type'      => 'extension',
 394                 'location'  => $this->updateSite,
 395                 'enabled'   => 1,
 396                 'last_check_timestamp'  => 0,
 397                 'extra_query'   => $this->extraQuery
 398         );
 399 
 400         // Get a reference to the db driver
 401         $db = FOFPlatform::getInstance()->getDbo();
 402 
 403         // Get the #__update_sites columns
 404         $columns = $db->getTableColumns('#__update_sites', true);
 405 
 406         if (version_compare(JVERSION, '3.2.0', 'lt') || !array_key_exists('extra_query', $columns))
 407         {
 408             unset($update_site['extra_query']);
 409         }
 410 
 411         if (version_compare(JVERSION, '2.5.0', 'lt') || !array_key_exists('extra_query', $columns))
 412         {
 413             unset($update_site['last_check_timestamp']);
 414         }
 415 
 416         // Get the update sites for our extension
 417         $updateSiteIds = $this->getUpdateSiteIds();
 418 
 419         if (empty($updateSiteIds))
 420         {
 421             $updateSiteIds = array();
 422         }
 423 
 424         /** @var boolean $needNewUpdateSite Do I need to create a new update site? */
 425         $needNewUpdateSite = true;
 426 
 427         /** @var int[] $deleteOldSites Old Site IDs to delete */
 428         $deleteOldSites = array();
 429 
 430         // Loop through all update sites
 431         foreach ($updateSiteIds as $id)
 432         {
 433             $query = $db->getQuery(true)
 434                         ->select('*')
 435                         ->from($db->qn('#__update_sites'))
 436                         ->where($db->qn('update_site_id') . ' = ' . $db->q($id));
 437             $db->setQuery($query);
 438             $aSite = $db->loadObject();
 439 
 440             if (empty($aSite))
 441             {
 442                 // Update site is now up-to-date, don't need to refresh it anymore.
 443                 continue;
 444             }
 445 
 446             // We have an update site that looks like ours
 447             if ($needNewUpdateSite && ($aSite->name == $update_site['name']) && ($aSite->location == $update_site['location']))
 448             {
 449                 $needNewUpdateSite = false;
 450                 $mustUpdate = false;
 451 
 452                 // Is it enabled? If not, enable it.
 453                 if (!$aSite->enabled)
 454                 {
 455                     $mustUpdate = true;
 456                     $aSite->enabled = 1;
 457                 }
 458 
 459                 // Do we have the extra_query property (J 3.2+) and does it match?
 460                 if (property_exists($aSite, 'extra_query') && isset($update_site['extra_query'])
 461                     && ($aSite->extra_query != $update_site['extra_query']))
 462                 {
 463                     $mustUpdate = true;
 464                     $aSite->extra_query = $update_site['extra_query'];
 465                 }
 466 
 467                 // Update the update site if necessary
 468                 if ($mustUpdate)
 469                 {
 470                     $db->updateObject('#__update_sites', $aSite, 'update_site_id', true);
 471                 }
 472 
 473                 continue;
 474             }
 475 
 476             // In any other case we need to delete this update site, it's obsolete
 477             $deleteOldSites[] = $aSite->update_site_id;
 478         }
 479 
 480         if (!empty($deleteOldSites))
 481         {
 482             try
 483             {
 484                 $obsoleteIDsQuoted = array_map(array($db, 'quote'), $deleteOldSites);
 485 
 486                 // Delete update sites
 487                 $query = $db->getQuery(true)
 488                             ->delete('#__update_sites')
 489                             ->where($db->qn('update_site_id') . ' IN (' . implode(',', $obsoleteIDsQuoted) . ')');
 490                 $db->setQuery($query)->execute();
 491 
 492                 // Delete update sites to extension ID records
 493                 $query = $db->getQuery(true)
 494                             ->delete('#__update_sites_extensions')
 495                             ->where($db->qn('update_site_id') . ' IN (' . implode(',', $obsoleteIDsQuoted) . ')');
 496                 $db->setQuery($query)->execute();
 497             }
 498             catch (\Exception $e)
 499             {
 500                 // Do nothing on failure
 501                 return;
 502             }
 503 
 504         }
 505 
 506         // Do we still need to create a new update site?
 507         if ($needNewUpdateSite)
 508         {
 509             // No update sites defined. Create a new one.
 510             $newSite = (object)$update_site;
 511             $db->insertObject('#__update_sites', $newSite);
 512 
 513             $id                  = $db->insertid();
 514             $updateSiteExtension = (object)array(
 515                 'update_site_id' => $id,
 516                 'extension_id'   => $this->extension_id,
 517             );
 518             $db->insertObject('#__update_sites_extensions', $updateSiteExtension);
 519         }
 520     }
 521 
 522     /**
 523      * Removes any update sites which go by the same name or the same location as our update site but do not match the
 524      * extension ID.
 525      */
 526     public function removeObsoleteUpdateSites()
 527     {
 528         $db = $this->getDbo();
 529 
 530         // Get update site IDs
 531         $updateSiteIDs = $this->getUpdateSiteIds();
 532 
 533         // Find update sites where the name OR the location matches BUT they are not one of the update site IDs
 534         $query = $db->getQuery(true)
 535                     ->select($db->qn('update_site_id'))
 536                     ->from($db->qn('#__update_sites'))
 537                     ->where(
 538                         '((' . $db->qn('name') . ' = ' . $db->q($this->updateSiteName) . ') OR ' .
 539                         '(' . $db->qn('location') . ' = ' . $db->q($this->updateSite) . '))'
 540                     );
 541 
 542         if (!empty($updateSiteIDs))
 543         {
 544             $updateSitesQuoted = array_map(array($db, 'quote'), $updateSiteIDs);
 545             $query->where($db->qn('update_site_id') . ' NOT IN (' . implode(',', $updateSitesQuoted) . ')');
 546         }
 547 
 548         try
 549         {
 550             $ids = $db->setQuery($query)->loadColumn();
 551 
 552             if (!empty($ids))
 553             {
 554                 $obsoleteIDsQuoted = array_map(array($db, 'quote'), $ids);
 555 
 556                 // Delete update sites
 557                 $query = $db->getQuery(true)
 558                             ->delete('#__update_sites')
 559                             ->where($db->qn('update_site_id') . ' IN (' . implode(',', $obsoleteIDsQuoted) . ')');
 560                 $db->setQuery($query)->execute();
 561 
 562                 // Delete update sites to extension ID records
 563                 $query = $db->getQuery(true)
 564                             ->delete('#__update_sites_extensions')
 565                             ->where($db->qn('update_site_id') . ' IN (' . implode(',', $obsoleteIDsQuoted) . ')');
 566                 $db->setQuery($query)->execute();
 567             }
 568         }
 569         catch (\Exception $e)
 570         {
 571             // Do nothing on failure
 572             return;
 573         }
 574     }
 575 
 576     /**
 577      * Get the update method we should use, 'joomla' or 'classic'
 578      *
 579      * You can defined the preferred update method: 'joomla' uses JUpdater whereas 'classic' handles update caching and
 580      * parsing internally. If you are on Joomla! 3.1 or earlier this option is forced to 'classic' since these old
 581      * Joomla! versions couldn't handle updates of commercial components correctly (that's why I contributed the fix to
 582      * that problem, the extra_query field that's present in Joomla! 3.2 onwards).
 583      *
 584      * If 'classic' is defined then it will be used in *all* Joomla! versions. It's the most stable method for fetching
 585      * update information.
 586      *
 587      * @param   string  $preferred  Preferred update method. One of 'joomla' or 'classic'.
 588      *
 589      * @return  string
 590      */
 591     public function getUpdateMethod($preferred = null)
 592     {
 593         $method = $preferred;
 594 
 595         // Make sure the update fetch method is valid, otherwise load the component's "update_method" parameter.
 596         $validMethods = array('joomla', 'classic');
 597 
 598         if (!in_array($method, $validMethods))
 599         {
 600             $method = FOFUtilsConfigHelper::getComponentConfigurationValue($this->component, 'update_method', 'joomla');
 601         }
 602 
 603         // We can't handle updates using Joomla!'s extensions updater in Joomla! 3.1 and earlier
 604         if (($method == 'joomla') && version_compare(JVERSION, '3.2.0', 'lt'))
 605         {
 606             $method = 'classic';
 607         }
 608 
 609         return $method;
 610     }
 611 
 612     /**
 613      * Find the available update record object. If we're at the latest version it will return null.
 614      *
 615      * @param   bool  $force  Should I forcibly reload the updates from the server?
 616      *
 617      * @return  \stdClass|null
 618      */
 619     protected function findUpdatesJoomla($force = false)
 620     {
 621         $db = FOFPlatform::getInstance()->getDbo();
 622 
 623         // If we are forcing the reload, set the last_check_timestamp to 0
 624         // and remove cached component update info in order to force a reload
 625         if ($force)
 626         {
 627             // Find the update site IDs
 628             $updateSiteIds = $this->getUpdateSiteIds();
 629 
 630             if (empty($updateSiteIds))
 631             {
 632                 return null;
 633             }
 634 
 635             // Set the last_check_timestamp to 0
 636             if (version_compare(JVERSION, '2.5.0', 'ge'))
 637             {
 638                 $query = $db->getQuery(true)
 639                             ->update($db->qn('#__update_sites'))
 640                             ->set($db->qn('last_check_timestamp') . ' = ' . $db->q('0'))
 641                             ->where($db->qn('update_site_id') .' IN ('.implode(', ', $updateSiteIds).')');
 642                 $db->setQuery($query);
 643                 $db->execute();
 644             }
 645 
 646             // Remove cached component update info from #__updates
 647             $query = $db->getQuery(true)
 648                         ->delete($db->qn('#__updates'))
 649                         ->where($db->qn('update_site_id') .' IN ('.implode(', ', $updateSiteIds).')');
 650             $db->setQuery($query);
 651             $db->execute();
 652         }
 653 
 654         // Use the update cache timeout specified in com_installer
 655         $timeout = 3600 * FOFUtilsConfigHelper::getComponentConfigurationValue('com_installer', 'cachetimeout', '6');
 656 
 657         // Load any updates from the network into the #__updates table
 658         $this->updater->findUpdates($this->extension_id, $timeout);
 659 
 660         // Get the update record from the database
 661         $query = $db->getQuery(true)
 662                     ->select('*')
 663                     ->from($db->qn('#__updates'))
 664                     ->where($db->qn('extension_id') . ' = ' . $db->q($this->extension_id));
 665         $db->setQuery($query);
 666 
 667         try
 668         {
 669             $updateObject = $db->loadObject();
 670         }
 671         catch (Exception $e)
 672         {
 673             return null;
 674         }
 675 
 676         if (!is_object($updateObject))
 677         {
 678             return null;
 679         }
 680 
 681         $updateObject->downloadurl = '';
 682 
 683         JLoader::import('joomla.updater.update');
 684 
 685         if (class_exists('JUpdate'))
 686         {
 687             $update = new JUpdate();
 688             $update->loadFromXML($updateObject->detailsurl);
 689 
 690             if (isset($update->get('downloadurl')->_data))
 691             {
 692                 $url = trim($update->downloadurl->_data);
 693 
 694                 $extra_query = isset($updateObject->extra_query) ? $updateObject->extra_query : $this->extraQuery;
 695 
 696                 if ($extra_query)
 697                 {
 698                     if (strpos($url, '?') === false)
 699                     {
 700                         $url .= '?';
 701                     }
 702                     else
 703                     {
 704                         $url .= '&amp;';
 705                     }
 706 
 707                     $url .= $extra_query;
 708                 }
 709 
 710                 $updateObject->downloadurl = $url;
 711             }
 712         }
 713 
 714         return $updateObject;
 715     }
 716 
 717     /**
 718      * Find the available update record object. If we're at the latest version return null.
 719      *
 720      * @param   bool  $force  Should I forcibly reload the updates from the server?
 721      *
 722      * @return  \stdClass|null
 723      */
 724     protected function findUpdatesClassic($force = false)
 725     {
 726         $allUpdates = $this->loadUpdatesClassic($force);
 727 
 728         if (empty($allUpdates))
 729         {
 730             return null;
 731         }
 732 
 733         $bestVersion = '0.0.0';
 734         $bestUpdate = null;
 735         $bestUpdateObject = null;
 736 
 737         foreach($allUpdates as $update)
 738         {
 739             if (!isset($update['version']))
 740             {
 741                 continue;
 742             }
 743 
 744             if (version_compare($bestVersion, $update['version'], 'lt'))
 745             {
 746                 $bestVersion = $update['version'];
 747                 $bestUpdate = $update;
 748             }
 749         }
 750 
 751         // If the current version is newer or equal to the best one, unset it. Otherwise the user will be always prompted to update
 752         if(version_compare($this->version, $bestVersion, 'ge'))
 753         {
 754             $bestUpdate = null;
 755             $bestVersion = '0.0.0';
 756         }
 757 
 758         if (!is_null($bestUpdate))
 759         {
 760             $url = '';
 761 
 762             if (isset($bestUpdate['downloads']) && isset($bestUpdate['downloads'][0])
 763             && isset($bestUpdate['downloads'][0]['url']))
 764             {
 765                 $url = $bestUpdate['downloads'][0]['url'];
 766             }
 767 
 768             if ($this->extraQuery)
 769             {
 770                 if (strpos($url, '?') === false)
 771                 {
 772                     $url .= '?';
 773                 }
 774                 else
 775                 {
 776                     $url .= '&amp;';
 777                 }
 778 
 779                 $url .= $this->extraQuery;
 780             }
 781 
 782             $bestUpdateObject = (object)array(
 783                     'update_id'      => 0,
 784                     'update_site_id' => 0,
 785                     'extension_id'   => $this->extension_id,
 786                     'name'           => $this->updateSiteName,
 787                     'description'    => $bestUpdate['description'],
 788                     'element'        => $bestUpdate['element'],
 789                     'type'           => $bestUpdate['type'],
 790                     'folder'         => count($bestUpdate['folder']) ? $bestUpdate['folder'][0] : '',
 791                     'client_id'      => isset($bestUpdate['client']) ? $bestUpdate['client'] : 0,
 792                     'version'        => $bestUpdate['version'],
 793                     'data'           => '',
 794                     'detailsurl'     => $this->updateSite,
 795                     'infourl'        => $bestUpdate['infourl']['url'],
 796                     'extra_query'    => $this->extraQuery,
 797                     'downloadurl'    => $url,
 798             );
 799         }
 800 
 801         return $bestUpdateObject;
 802     }
 803 
 804     /**
 805      * Load all available updates without going through JUpdate
 806      *
 807      * @param   bool  $force  Should I forcibly reload the updates from the server?
 808      *
 809      * @return  array
 810      */
 811     protected function loadUpdatesClassic($force = false)
 812     {
 813         // Is the cache busted? If it is I set $force = true to make sure I download fresh updates
 814         if (!$force)
 815         {
 816             // Get the cache timeout. On older Joomla! installations it will always default to 6 hours.
 817             $timeout = 3600 * FOFUtilsConfigHelper::getComponentConfigurationValue('com_installer', 'cachetimeout', '6');
 818 
 819             // Do I need to check for updates?
 820             $lastCheck = $this->getCommonParameter('lastcheck', 0);
 821             $now = time();
 822 
 823             if (($now - $lastCheck) >= $timeout)
 824             {
 825                 $force = true;
 826             }
 827         }
 828 
 829         // Get the cached JSON-encoded updates list
 830         $rawUpdates = $this->getCommonParameter('allUpdates', '');
 831 
 832         // Am I forced to reload the XML file (explicitly or because the cache is busted)?
 833         if ($force)
 834         {
 835             // Set the timestamp
 836             $now = time();
 837             $this->setCommonParameter('lastcheck', $now);
 838 
 839             // Get all available updates
 840             $updateHelper = new FOFUtilsUpdateExtension();
 841             $updates = $updateHelper->getUpdatesFromExtension($this->updateSite);
 842 
 843             // Save the raw updates list in the database
 844             $rawUpdates = json_encode($updates);
 845             $this->setCommonParameter('allUpdates', $rawUpdates);
 846         }
 847 
 848         // Decode the updates list
 849         $updates = json_decode($rawUpdates, true);
 850 
 851         // Walk through the updates and find the ones compatible with our Joomla! and PHP version
 852         $compatibleUpdates = array();
 853 
 854         // Get the Joomla! version family (e.g. 2.5)
 855         $jVersion = JVERSION;
 856         $jVersionParts = explode('.', $jVersion);
 857         $jVersionShort = $jVersionParts[0] . '.' . $jVersionParts[1];
 858 
 859         // Get the PHP version family (e.g. 5.6)
 860         $phpVersion = PHP_VERSION;
 861         $phpVersionParts = explode('.', $phpVersion);
 862         $phpVersionShort = $phpVersionParts[0] . '.' . $phpVersionParts[1];
 863 
 864         foreach ($updates as $update)
 865         {
 866             // No platform?
 867             if (!isset($update['targetplatform']))
 868             {
 869                 continue;
 870             }
 871 
 872             // Wrong platform?
 873             if ($update['targetplatform']['name'] != 'joomla')
 874             {
 875                 continue;
 876             }
 877 
 878             // Get the target Joomla! version
 879             $targetJoomlaVersion = $update['targetplatform']['version'];
 880             $targetVersionParts = explode('.', $targetJoomlaVersion);
 881             $targetVersionShort = $targetVersionParts[0] . '.' . $targetVersionParts[1];
 882 
 883             // The target version MUST be in the same Joomla! branch
 884             if ($jVersionShort != $targetVersionShort)
 885             {
 886                 continue;
 887             }
 888 
 889             // If the target version is major.minor.revision we must make sure our current JVERSION is AT LEAST equal to that.
 890             if (version_compare($targetJoomlaVersion, JVERSION, 'gt'))
 891             {
 892                 continue;
 893             }
 894 
 895             // Do I have target PHP versions?
 896             if (isset($update['ars-phpcompat']))
 897             {
 898                 $phpCompatible = false;
 899 
 900                 foreach ($update['ars-phpcompat'] as $entry)
 901                 {
 902                     // Get the target PHP version family
 903                     $targetPHPVersion = $entry['@attributes']['version'];
 904                     $targetPHPVersionParts = explode('.', $targetPHPVersion);
 905                     $targetPHPVersionShort = $targetPHPVersionParts[0] . '.' . $targetPHPVersionParts[1];
 906 
 907                     // The target PHP version MUST be in the same PHP branch
 908                     if ($phpVersionShort != $targetPHPVersionShort)
 909                     {
 910                         continue;
 911                     }
 912 
 913                     // If the target version is major.minor.revision we must make sure our current PHP_VERSION is AT LEAST equal to that.
 914                     if (version_compare($targetPHPVersion, PHP_VERSION, 'gt'))
 915                     {
 916                         continue;
 917                     }
 918 
 919                     $phpCompatible = true;
 920                     break;
 921                 }
 922 
 923                 if (!$phpCompatible)
 924                 {
 925                     continue;
 926                 }
 927             }
 928 
 929             // All checks pass. Add this update to the list of compatible updates.
 930             $compatibleUpdates[] = $update;
 931         }
 932 
 933         return $compatibleUpdates;
 934     }
 935 
 936     /**
 937      * Get a common parameter from the #__akeeba_common table
 938      *
 939      * @param   string  $key      The key to retrieve
 940      * @param   mixed   $default  The default value in case none is set
 941      *
 942      * @return  mixed  The saved parameter value (or $default, if nothing is currently set)
 943      */
 944     protected function getCommonParameter($key, $default = null)
 945     {
 946         $dbKey = $this->commonKey . '_autoupdate_' . $key;
 947 
 948         $db = FOFPlatform::getInstance()->getDbo();
 949 
 950         $query = $db->getQuery(true)
 951                     ->select($db->qn('value'))
 952                     ->from($db->qn($this->commonTable))
 953                     ->where($db->qn('key') . ' = ' . $db->q($dbKey));
 954 
 955         $result = $db->setQuery($query)->loadResult();
 956 
 957         if (!$result)
 958         {
 959             return $default;
 960         }
 961 
 962         return $result;
 963     }
 964 
 965     /**
 966      * Set a common parameter from the #__akeeba_common table
 967      *
 968      * @param   string  $key    The key to set
 969      * @param   mixed   $value  The value to set
 970      *
 971      * @return  void
 972      */
 973     protected function setCommonParameter($key, $value)
 974     {
 975         $dbKey = $this->commonKey . '_autoupdate_' . $key;
 976 
 977         $db = FOFPlatform::getInstance()->getDbo();
 978 
 979         $query = $db->getQuery(true)
 980                     ->select('COUNT(*)')
 981                     ->from($db->qn($this->commonTable))
 982                     ->where($db->qn('key') . ' = ' . $db->q($dbKey));
 983         $count = $db->setQuery($query)->loadResult();
 984 
 985         if ($count)
 986         {
 987             $query = $db->getQuery(true)
 988                         ->update($db->qn($this->commonTable))
 989                         ->set($db->qn('value') . ' = ' . $db->q($value))
 990                         ->where($db->qn('key') . ' = ' . $db->q($dbKey));
 991             $db->setQuery($query)->execute();
 992         }
 993         else
 994         {
 995             $data = (object)array(
 996                     'key'   => $dbKey,
 997                     'value' => $value,
 998             );
 999 
1000             $db->insertObject($this->commonTable, $data);
1001         }
1002     }
1003 
1004     /**
1005      * Proxy to updateComponent(). Required since old versions of our software had an updateComponent method declared
1006      * private. If we set the updateComponent() method public we cause a fatal error.
1007      *
1008      * @return  string
1009      */
1010     public function doUpdateComponent()
1011     {
1012         return $this->updateComponent();
1013     }
1014 
1015     /**
1016      * Automatically install the extension update under Joomla! 1.5.5 or later (web) / 3.0 or later (CLI).
1017      *
1018      * @return  string  The update message
1019      */
1020     private function updateComponent()
1021     {
1022         $isCli          = FOFPlatform::getInstance()->isCli();
1023         $minVersion     = $isCli ? '3.0.0' : '1.5.5';
1024         $errorQualifier = $isCli ? ' using an unattended CLI CRON script ' : ' ';
1025 
1026         if (version_compare(JVERSION, $minVersion, 'lt'))
1027         {
1028             return "Extension updates{$errorQualifier}only work with Joomla! $minVersion and later.";
1029         }
1030 
1031         try
1032         {
1033             $updatePackagePath = $this->downloadUpdate();
1034         }
1035         catch (Exception $e)
1036         {
1037             return $e->getMessage();
1038         }
1039 
1040         // Unpack the downloaded package file
1041         jimport('joomla.installer.helper');
1042         jimport('cms.installer.helper');
1043         $package = JInstallerHelper::unpack($updatePackagePath);
1044 
1045         if (!$package)
1046         {
1047             // Clean up
1048             if (JFile::exists($updatePackagePath))
1049             {
1050                 JFile::delete($updatePackagePath);
1051             }
1052 
1053             return "An error occurred while unpacking the file. Please double check your Joomla temp-directory setting in Global Configuration.";
1054         }
1055 
1056         $installer = new JInstaller;
1057         $installed = $installer->install($package['extractdir']);
1058 
1059         // Let's cleanup the downloaded archive and the temp folder
1060         if (JFolder::exists($package['extractdir']))
1061         {
1062             JFolder::delete($package['extractdir']);
1063         }
1064 
1065         if (JFile::exists($package['packagefile']))
1066         {
1067             JFile::delete($package['packagefile']);
1068         }
1069 
1070         if ($installed)
1071         {
1072             return "Component successfully updated";
1073         }
1074         else
1075         {
1076             return "An error occurred while trying to update the component";
1077         }
1078     }
1079 
1080     /**
1081      * Downloads the latest update package to Joomla!'s temporary directory
1082      *
1083      * @return  string  The absolute path to the downloaded update package.
1084      */
1085     public function downloadUpdate()
1086     {
1087         // Get the update URL
1088         $updateInformation = $this->getUpdates();
1089         $url               = $updateInformation['downloadURL'];
1090 
1091         if (empty($url))
1092         {
1093             throw new RuntimeException("No download URL was provided in the update information");
1094         }
1095 
1096         $config   = JFactory::getConfig();
1097         $tmp_dest = $config->get('tmp_path');
1098 
1099         if (!$tmp_dest)
1100         {
1101             throw new RuntimeException("You must set a non-empty Joomla! temp-directory in Global Configuration before continuing.");
1102         }
1103 
1104         if (!JFolder::exists($tmp_dest))
1105         {
1106             throw new RuntimeException("Joomla!'s temp-directory does not exist. Please set the correct path in Global Configuration before continuing.");
1107         }
1108 
1109         // Get the target filename
1110         $filename = $this->component . '.zip';
1111         $filename = rtrim($tmp_dest, '\\/') . '/' . $filename;
1112 
1113         try
1114         {
1115             $downloader = new FOFDownload();
1116             $data = $downloader->getFromURL($url);
1117         }
1118         catch (Exception $e)
1119         {
1120             $code =$e->getCode();
1121             $message =$e->getMessage();
1122             throw new RuntimeException("An error occurred while trying to download the update package. Double check your Download ID and your server's network settings. The error message was: #$code: $message");
1123         }
1124 
1125         if (!JFile::write($filename, $data))
1126         {
1127             if (!file_put_contents($filename, $data))
1128             {
1129                 throw new RuntimeException("Joomla!'s temp-directory is not writeable. Please check its permissions or set a different, writeable path in Global Configuration before continuing.");
1130             }
1131         }
1132 
1133         return $filename;
1134     }
1135 
1136     /**
1137      * Gets a file name out of a url
1138      *
1139      * @param   string  $url  URL to get name from
1140      *
1141      * @return  mixed   String filename or boolean false if failed
1142      */
1143     private function getFilenameFromURL($url)
1144     {
1145         if (is_string($url))
1146         {
1147             $parts = explode('/', $url);
1148 
1149             return $parts[count($parts) - 1];
1150         }
1151 
1152         return false;
1153     }
1154 
1155     /**
1156      * Proxy to sendNotificationEmail(). Required since old versions of our software had a sendNotificationEmail method
1157      * declared private. If we set the sendNotificationEmail() method public we cause a fatal error.
1158      *
1159      * @param   string  $version  The new version of our software
1160      * @param   string  $email    The email address to send the notification to
1161      *
1162      * @return  mixed  The result of JMail::send()
1163      */
1164     public function doSendNotificationEmail($version, $email)
1165     {
1166         try
1167         {
1168             return $this->sendNotificationEmail($version, $email);
1169         }
1170         catch (\Exception $e)
1171         {
1172             // Joomla! 3.5 is buggy
1173         }
1174     }
1175 
1176     /**
1177      * Sends an update notification email
1178      *
1179      * @param   string  $version  The new version of our software
1180      * @param   string  $email    The email address to send the notification to
1181      *
1182      * @return  mixed  The result of JMail::send()
1183      */
1184     private function sendNotificationEmail($version, $email)
1185     {
1186         $email_subject  = $this->updateEmailSubject;
1187         $email_body = $this->updateEmailBody;
1188 
1189         $jconfig  = JFactory::getConfig();
1190         $sitename = $jconfig->get('sitename');
1191 
1192         $substitutions = array(
1193                 '[VERSION]'         => $version,
1194                 '[SITENAME]'        => $sitename,
1195                 '[COMPONENT]'       => $this->componentDescription,
1196         );
1197 
1198         $email_subject = str_replace(array_keys($substitutions), array_values($substitutions), $email_subject);
1199         $email_body    = str_replace(array_keys($substitutions), array_values($substitutions), $email_body);
1200 
1201         $mailer = JFactory::getMailer();
1202 
1203         $mailfrom = $jconfig->get('mailfrom');
1204         $fromname = $jconfig->get('fromname');
1205 
1206         $mailer->setSender(array( $mailfrom, $fromname ));
1207         $mailer->addRecipient($email);
1208         $mailer->setSubject($email_subject);
1209         $mailer->setBody($email_body);
1210 
1211         return $mailer->Send();
1212     }
1213 }
1214 
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.