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

Namespaces

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

Classes

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

Interfaces

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

Exceptions

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

Constants

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

Functions

  • __autoload
  • array_column
  • boolval
  • composerRequire205c915b9c7d3e718e7c95793ee67ffe
  • gzopen
  • gzseek
  • gztell
  • hash_equals
  • hash_pbkdf2
  • HTMLFilter
  • jexit
  • jimport
  • json_last_error_msg
  • ldap_escape
  • password_get_info
  • password_hash
  • password_needs_rehash
  • password_verify
  • PHPMailerAutoload
  • random_bytes
  • random_int
  • RandomCompat_intval
  • RandomCompat_strlen
  • RandomCompat_substr
  • tln_body2div
  • tln_casenormalize
  • tln_deent
  • tln_defang
  • tln_findnxreg
  • tln_findnxstr
  • tln_fixatts
  • tln_fixstyle
  • tln_fixurl
  • tln_getnxtag
  • tln_sanitize
  • tln_skipspace
  • tln_tagprint
  • tln_unspace
  • utf8_accents_to_ascii
  • utf8_bad_explain
  • utf8_bad_find
  • utf8_bad_findall
  • utf8_bad_identify
  • utf8_bad_replace
  • utf8_bad_strip
  • utf8_byte_position
  • utf8_compliant
  • utf8_from_unicode
  • utf8_ireplace
  • utf8_is_ascii
  • utf8_is_ascii_ctrl
  • utf8_is_valid
  • utf8_is_word_chars
  • utf8_locate_current_chr
  • utf8_locate_next_chr
  • utf8_ltrim
  • utf8_ord
  • utf8_rtrim
  • utf8_specials_pattern
  • utf8_str_pad
  • utf8_str_split
  • utf8_strcasecmp
  • utf8_strcspn
  • utf8_strip_ascii_ctrl
  • utf8_strip_non_ascii
  • utf8_strip_non_ascii_ctrl
  • utf8_strip_specials
  • utf8_stristr
  • utf8_strlen
  • utf8_strpos
  • utf8_strrev
  • utf8_strrpos
  • utf8_strspn
  • utf8_strtolower
  • utf8_strtoupper
  • utf8_substr
  • utf8_substr_replace
  • utf8_to_unicode
  • utf8_trim
  • utf8_ucfirst
  • utf8_ucwords
  • utf8_ucwords_callback
  1 <?php
  2 /**
  3  * @package     Joomla.Platform
  4  * @subpackage  Application
  5  *
  6  * @copyright   Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved.
  7  * @license     GNU General Public License version 2 or later; see LICENSE
  8  */
  9 
 10 defined('JPATH_PLATFORM') or die;
 11 
 12 jimport('joomla.filesystem.folder');
 13 
 14 use Joomla\Registry\Registry;
 15 
 16 /**
 17  * Class to turn JApplicationCli applications into daemons.  It requires CLI and PCNTL support built into PHP.
 18  *
 19  * @link   https://secure.php.net/manual/en/book.pcntl.php
 20  * @link   https://secure.php.net/manual/en/features.commandline.php
 21  * @since  11.1
 22  */
 23 class JApplicationDaemon extends JApplicationCli
 24 {
 25     /**
 26      * @var    array  The available POSIX signals to be caught by default.
 27      * @link   https://secure.php.net/manual/pcntl.constants.php
 28      * @since  11.1
 29      */
 30     protected static $signals = array(
 31         'SIGHUP',
 32         'SIGINT',
 33         'SIGQUIT',
 34         'SIGILL',
 35         'SIGTRAP',
 36         'SIGABRT',
 37         'SIGIOT',
 38         'SIGBUS',
 39         'SIGFPE',
 40         'SIGUSR1',
 41         'SIGSEGV',
 42         'SIGUSR2',
 43         'SIGPIPE',
 44         'SIGALRM',
 45         'SIGTERM',
 46         'SIGSTKFLT',
 47         'SIGCLD',
 48         'SIGCHLD',
 49         'SIGCONT',
 50         'SIGTSTP',
 51         'SIGTTIN',
 52         'SIGTTOU',
 53         'SIGURG',
 54         'SIGXCPU',
 55         'SIGXFSZ',
 56         'SIGVTALRM',
 57         'SIGPROF',
 58         'SIGWINCH',
 59         'SIGPOLL',
 60         'SIGIO',
 61         'SIGPWR',
 62         'SIGSYS',
 63         'SIGBABY',
 64         'SIG_BLOCK',
 65         'SIG_UNBLOCK',
 66         'SIG_SETMASK',
 67     );
 68 
 69     /**
 70      * @var    boolean  True if the daemon is in the process of exiting.
 71      * @since  11.1
 72      */
 73     protected $exiting = false;
 74 
 75     /**
 76      * @var    integer  The parent process id.
 77      * @since  12.1
 78      */
 79     protected $parentId = 0;
 80 
 81     /**
 82      * @var    integer  The process id of the daemon.
 83      * @since  11.1
 84      */
 85     protected $processId = 0;
 86 
 87     /**
 88      * @var    boolean  True if the daemon is currently running.
 89      * @since  11.1
 90      */
 91     protected $running = false;
 92 
 93     /**
 94      * Class constructor.
 95      *
 96      * @param   JInputCli         $input       An optional argument to provide dependency injection for the application's
 97      *                                         input object.  If the argument is a JInputCli object that object will become
 98      *                                         the application's input object, otherwise a default input object is created.
 99      * @param   Registry          $config      An optional argument to provide dependency injection for the application's
100      *                                         config object.  If the argument is a Registry object that object will become
101      *                                         the application's config object, otherwise a default config object is created.
102      * @param   JEventDispatcher  $dispatcher  An optional argument to provide dependency injection for the application's
103      *                                         event dispatcher.  If the argument is a JEventDispatcher object that object will become
104      *                                         the application's event dispatcher, if it is null then the default event dispatcher
105      *                                         will be created based on the application's loadDispatcher() method.
106      *
107      * @since   11.1
108      * @throws  RuntimeException
109      */
110     public function __construct(JInputCli $input = null, Registry $config = null, JEventDispatcher $dispatcher = null)
111     {
112         // Verify that the process control extension for PHP is available.
113         // @codeCoverageIgnoreStart
114         if (!defined('SIGHUP'))
115         {
116             JLog::add('The PCNTL extension for PHP is not available.', JLog::ERROR);
117             throw new RuntimeException('The PCNTL extension for PHP is not available.');
118         }
119 
120         // Verify that POSIX support for PHP is available.
121         if (!function_exists('posix_getpid'))
122         {
123             JLog::add('The POSIX extension for PHP is not available.', JLog::ERROR);
124             throw new RuntimeException('The POSIX extension for PHP is not available.');
125         }
126         // @codeCoverageIgnoreEnd
127 
128         // Call the parent constructor.
129         parent::__construct($input, $config, $dispatcher);
130 
131         // Set some system limits.
132         @set_time_limit($this->config->get('max_execution_time', 0));
133 
134         if ($this->config->get('max_memory_limit') !== null)
135         {
136             ini_set('memory_limit', $this->config->get('max_memory_limit', '256M'));
137         }
138 
139         // Flush content immediately.
140         ob_implicit_flush();
141     }
142 
143     /**
144      * Method to handle POSIX signals.
145      *
146      * @param   integer  $signal  The received POSIX signal.
147      *
148      * @return  void
149      *
150      * @since   11.1
151      * @see     pcntl_signal()
152      * @throws  RuntimeException
153      */
154     public static function signal($signal)
155     {
156         // Log all signals sent to the daemon.
157         JLog::add('Received signal: ' . $signal, JLog::DEBUG);
158 
159         // Let's make sure we have an application instance.
160         if (!is_subclass_of(static::$instance, 'JApplicationDaemon'))
161         {
162             JLog::add('Cannot find the application instance.', JLog::EMERGENCY);
163             throw new RuntimeException('Cannot find the application instance.');
164         }
165 
166         // Fire the onReceiveSignal event.
167         static::$instance->triggerEvent('onReceiveSignal', array($signal));
168 
169         switch ($signal)
170         {
171             case SIGINT:
172             case SIGTERM:
173                 // Handle shutdown tasks
174                 if (static::$instance->running && static::$instance->isActive())
175                 {
176                     static::$instance->shutdown();
177                 }
178                 else
179                 {
180                     static::$instance->close();
181                 }
182                 break;
183             case SIGHUP:
184                 // Handle restart tasks
185                 if (static::$instance->running && static::$instance->isActive())
186                 {
187                     static::$instance->shutdown(true);
188                 }
189                 else
190                 {
191                     static::$instance->close();
192                 }
193                 break;
194             case SIGCHLD:
195                 // A child process has died
196                 while (static::$instance->pcntlWait($signal, WNOHANG || WUNTRACED) > 0)
197                 {
198                     usleep(1000);
199                 }
200                 break;
201             case SIGCLD:
202                 while (static::$instance->pcntlWait($signal, WNOHANG) > 0)
203                 {
204                     $signal = static::$instance->pcntlChildExitStatus($signal);
205                 }
206                 break;
207             default:
208                 break;
209         }
210     }
211 
212     /**
213      * Check to see if the daemon is active.  This does not assume that $this daemon is active, but
214      * only if an instance of the application is active as a daemon.
215      *
216      * @return  boolean  True if daemon is active.
217      *
218      * @since   11.1
219      */
220     public function isActive()
221     {
222         // Get the process id file location for the application.
223         $pidFile = $this->config->get('application_pid_file');
224 
225         // If the process id file doesn't exist then the daemon is obviously not running.
226         if (!is_file($pidFile))
227         {
228             return false;
229         }
230 
231         // Read the contents of the process id file as an integer.
232         $fp = fopen($pidFile, 'r');
233         $pid = fread($fp, filesize($pidFile));
234         $pid = (int) $pid;
235         fclose($fp);
236 
237         // Check to make sure that the process id exists as a positive integer.
238         if (!$pid)
239         {
240             return false;
241         }
242 
243         // Check to make sure the process is active by pinging it and ensure it responds.
244         if (!posix_kill($pid, 0))
245         {
246             // No response so remove the process id file and log the situation.
247             @ unlink($pidFile);
248             JLog::add('The process found based on PID file was unresponsive.', JLog::WARNING);
249 
250             return false;
251         }
252 
253         return true;
254     }
255 
256     /**
257      * Load an object or array into the application configuration object.
258      *
259      * @param   mixed  $data  Either an array or object to be loaded into the configuration object.
260      *
261      * @return  JCli  Instance of $this to allow chaining.
262      *
263      * @since   11.1
264      */
265     public function loadConfiguration($data)
266     {
267         // Execute the parent load method.
268         parent::loadConfiguration($data);
269 
270         /*
271          * Setup some application metadata options.  This is useful if we ever want to write out startup scripts
272          * or just have some sort of information available to share about things.
273          */
274 
275         // The application author name.  This string is used in generating startup scripts and has
276         // a maximum of 50 characters.
277         $tmp = (string) $this->config->get('author_name', 'Joomla Platform');
278         $this->config->set('author_name', (strlen($tmp) > 50) ? substr($tmp, 0, 50) : $tmp);
279 
280         // The application author email.  This string is used in generating startup scripts.
281         $tmp = (string) $this->config->get('author_email', 'admin@joomla.org');
282         $this->config->set('author_email', filter_var($tmp, FILTER_VALIDATE_EMAIL));
283 
284         // The application name.  This string is used in generating startup scripts.
285         $tmp = (string) $this->config->get('application_name', 'JApplicationDaemon');
286         $this->config->set('application_name', (string) preg_replace('/[^A-Z0-9_-]/i', '', $tmp));
287 
288         // The application description.  This string is used in generating startup scripts.
289         $tmp = (string) $this->config->get('application_description', 'A generic Joomla Platform application.');
290         $this->config->set('application_description', filter_var($tmp, FILTER_SANITIZE_STRING));
291 
292         /*
293          * Setup the application path options.  This defines the default executable name, executable directory,
294          * and also the path to the daemon process id file.
295          */
296 
297         // The application executable daemon.  This string is used in generating startup scripts.
298         $tmp = (string) $this->config->get('application_executable', basename($this->input->executable));
299         $this->config->set('application_executable', $tmp);
300 
301         // The home directory of the daemon.
302         $tmp = (string) $this->config->get('application_directory', dirname($this->input->executable));
303         $this->config->set('application_directory', $tmp);
304 
305         // The pid file location.  This defaults to a path inside the /tmp directory.
306         $name = $this->config->get('application_name');
307         $tmp = (string) $this->config->get('application_pid_file', strtolower('/tmp/' . $name . '/' . $name . '.pid'));
308         $this->config->set('application_pid_file', $tmp);
309 
310         /*
311          * Setup the application identity options.  It is important to remember if the default of 0 is set for
312          * either UID or GID then changing that setting will not be attempted as there is no real way to "change"
313          * the identity of a process from some user to root.
314          */
315 
316         // The user id under which to run the daemon.
317         $tmp = (int) $this->config->get('application_uid', 0);
318         $options = array('options' => array('min_range' => 0, 'max_range' => 65000));
319         $this->config->set('application_uid', filter_var($tmp, FILTER_VALIDATE_INT, $options));
320 
321         // The group id under which to run the daemon.
322         $tmp = (int) $this->config->get('application_gid', 0);
323         $options = array('options' => array('min_range' => 0, 'max_range' => 65000));
324         $this->config->set('application_gid', filter_var($tmp, FILTER_VALIDATE_INT, $options));
325 
326         // Option to kill the daemon if it cannot switch to the chosen identity.
327         $tmp = (bool) $this->config->get('application_require_identity', 1);
328         $this->config->set('application_require_identity', $tmp);
329 
330         /*
331          * Setup the application runtime options.  By default our execution time limit is infinite obviously
332          * because a daemon should be constantly running unless told otherwise.  The default limit for memory
333          * usage is 256M, which admittedly is a little high, but remember it is a "limit" and PHP's memory
334          * management leaves a bit to be desired :-)
335          */
336 
337         // The maximum execution time of the application in seconds.  Zero is infinite.
338         $tmp = $this->config->get('max_execution_time');
339 
340         if ($tmp !== null)
341         {
342             $this->config->set('max_execution_time', (int) $tmp);
343         }
344 
345         // The maximum amount of memory the application can use.
346         $tmp = $this->config->get('max_memory_limit', '256M');
347 
348         if ($tmp !== null)
349         {
350             $this->config->set('max_memory_limit', (string) $tmp);
351         }
352 
353         return $this;
354     }
355 
356     /**
357      * Execute the daemon.
358      *
359      * @return  void
360      *
361      * @since   11.1
362      */
363     public function execute()
364     {
365         // Trigger the onBeforeExecute event.
366         $this->triggerEvent('onBeforeExecute');
367 
368         // Enable basic garbage collection.
369         gc_enable();
370 
371         JLog::add('Starting ' . $this->name, JLog::INFO);
372 
373         // Set off the process for becoming a daemon.
374         if ($this->daemonize())
375         {
376             // Declare ticks to start signal monitoring. When you declare ticks, PCNTL will monitor
377             // incoming signals after each tick and call the relevant signal handler automatically.
378             declare (ticks = 1);
379 
380             // Start the main execution loop.
381             while (true)
382             {
383                 // Perform basic garbage collection.
384                 $this->gc();
385 
386                 // Don't completely overload the CPU.
387                 usleep(1000);
388 
389                 // Execute the main application logic.
390                 $this->doExecute();
391             }
392         }
393         // We were not able to daemonize the application so log the failure and die gracefully.
394         else
395         {
396             JLog::add('Starting ' . $this->name . ' failed', JLog::INFO);
397         }
398 
399         // Trigger the onAfterExecute event.
400         $this->triggerEvent('onAfterExecute');
401     }
402 
403     /**
404      * Restart daemon process.
405      *
406      * @return  void
407      *
408      * @codeCoverageIgnore
409      * @since   11.1
410      */
411     public function restart()
412     {
413         JLog::add('Stopping ' . $this->name, JLog::INFO);
414         $this->shutdown(true);
415     }
416 
417     /**
418      * Stop daemon process.
419      *
420      * @return  void
421      *
422      * @codeCoverageIgnore
423      * @since   11.1
424      */
425     public function stop()
426     {
427         JLog::add('Stopping ' . $this->name, JLog::INFO);
428         $this->shutdown();
429     }
430 
431     /**
432      * Method to change the identity of the daemon process and resources.
433      *
434      * @return  boolean  True if identity successfully changed
435      *
436      * @since   11.1
437      * @see     posix_setuid()
438      */
439     protected function changeIdentity()
440     {
441         // Get the group and user ids to set for the daemon.
442         $uid = (int) $this->config->get('application_uid', 0);
443         $gid = (int) $this->config->get('application_gid', 0);
444 
445         // Get the application process id file path.
446         $file = $this->config->get('application_pid_file');
447 
448         // Change the user id for the process id file if necessary.
449         if ($uid && (fileowner($file) != $uid) && (!@ chown($file, $uid)))
450         {
451             JLog::add('Unable to change user ownership of the process id file.', JLog::ERROR);
452 
453             return false;
454         }
455 
456         // Change the group id for the process id file if necessary.
457         if ($gid && (filegroup($file) != $gid) && (!@ chgrp($file, $gid)))
458         {
459             JLog::add('Unable to change group ownership of the process id file.', JLog::ERROR);
460 
461             return false;
462         }
463 
464         // Set the correct home directory for the process.
465         if ($uid && ($info = posix_getpwuid($uid)) && is_dir($info['dir']))
466         {
467             system('export HOME="' . $info['dir'] . '"');
468         }
469 
470         // Change the user id for the process necessary.
471         if ($uid && (posix_getuid($file) != $uid) && (!@ posix_setuid($uid)))
472         {
473             JLog::add('Unable to change user ownership of the proccess.', JLog::ERROR);
474 
475             return false;
476         }
477 
478         // Change the group id for the process necessary.
479         if ($gid && (posix_getgid($file) != $gid) && (!@ posix_setgid($gid)))
480         {
481             JLog::add('Unable to change group ownership of the proccess.', JLog::ERROR);
482 
483             return false;
484         }
485 
486         // Get the user and group information based on uid and gid.
487         $user = posix_getpwuid($uid);
488         $group = posix_getgrgid($gid);
489 
490         JLog::add('Changed daemon identity to ' . $user['name'] . ':' . $group['name'], JLog::INFO);
491 
492         return true;
493     }
494 
495     /**
496      * Method to put the application into the background.
497      *
498      * @return  boolean
499      *
500      * @since   11.1
501      * @throws  RuntimeException
502      */
503     protected function daemonize()
504     {
505         // Is there already an active daemon running?
506         if ($this->isActive())
507         {
508             JLog::add($this->name . ' daemon is still running. Exiting the application.', JLog::EMERGENCY);
509 
510             return false;
511         }
512 
513         // Reset Process Information
514         $this->safeMode = !!@ ini_get('safe_mode');
515         $this->processId = 0;
516         $this->running = false;
517 
518         // Detach process!
519         try
520         {
521             // Check if we should run in the foreground.
522             if (!$this->input->get('f'))
523             {
524                 // Detach from the terminal.
525                 $this->detach();
526             }
527             else
528             {
529                 // Setup running values.
530                 $this->exiting = false;
531                 $this->running = true;
532 
533                 // Set the process id.
534                 $this->processId = (int) posix_getpid();
535                 $this->parentId = $this->processId;
536             }
537         }
538         catch (RuntimeException $e)
539         {
540             JLog::add('Unable to fork.', JLog::EMERGENCY);
541 
542             return false;
543         }
544 
545         // Verify the process id is valid.
546         if ($this->processId < 1)
547         {
548             JLog::add('The process id is invalid; the fork failed.', JLog::EMERGENCY);
549 
550             return false;
551         }
552 
553         // Clear the umask.
554         @ umask(0);
555 
556         // Write out the process id file for concurrency management.
557         if (!$this->writeProcessIdFile())
558         {
559             JLog::add('Unable to write the pid file at: ' . $this->config->get('application_pid_file'), JLog::EMERGENCY);
560 
561             return false;
562         }
563 
564         // Attempt to change the identity of user running the process.
565         if (!$this->changeIdentity())
566         {
567             // If the identity change was required then we need to return false.
568             if ($this->config->get('application_require_identity'))
569             {
570                 JLog::add('Unable to change process owner.', JLog::CRITICAL);
571 
572                 return false;
573             }
574             else
575             {
576                 JLog::add('Unable to change process owner.', JLog::WARNING);
577             }
578         }
579 
580         // Setup the signal handlers for the daemon.
581         if (!$this->setupSignalHandlers())
582         {
583             return false;
584         }
585 
586         // Change the current working directory to the application working directory.
587         @ chdir($this->config->get('application_directory'));
588 
589         return true;
590     }
591 
592     /**
593      * This is truly where the magic happens.  This is where we fork the process and kill the parent
594      * process, which is essentially what turns the application into a daemon.
595      *
596      * @return  void
597      *
598      * @since   12.1
599      * @throws  RuntimeException
600      */
601     protected function detach()
602     {
603         JLog::add('Detaching the ' . $this->name . ' daemon.', JLog::DEBUG);
604 
605         // Attempt to fork the process.
606         $pid = $this->fork();
607 
608         // If the pid is positive then we successfully forked, and can close this application.
609         if ($pid)
610         {
611             // Add the log entry for debugging purposes and exit gracefully.
612             JLog::add('Ending ' . $this->name . ' parent process', JLog::DEBUG);
613             $this->close();
614         }
615         // We are in the forked child process.
616         else
617         {
618             // Setup some protected values.
619             $this->exiting = false;
620             $this->running = true;
621 
622             // Set the parent to self.
623             $this->parentId = $this->processId;
624         }
625     }
626 
627     /**
628      * Method to fork the process.
629      *
630      * @return  integer  The child process id to the parent process, zero to the child process.
631      *
632      * @since   11.1
633      * @throws  RuntimeException
634      */
635     protected function fork()
636     {
637         // Attempt to fork the process.
638         $pid = $this->pcntlFork();
639 
640         // If the fork failed, throw an exception.
641         if ($pid === -1)
642         {
643             throw new RuntimeException('The process could not be forked.');
644         }
645         // Update the process id for the child.
646         elseif ($pid === 0)
647         {
648             $this->processId = (int) posix_getpid();
649         }
650         // Log the fork in the parent.
651         else
652         {
653             // Log the fork.
654             JLog::add('Process forked ' . $pid, JLog::DEBUG);
655         }
656 
657         // Trigger the onFork event.
658         $this->postFork();
659 
660         return $pid;
661     }
662 
663     /**
664      * Method to perform basic garbage collection and memory management in the sense of clearing the
665      * stat cache.  We will probably call this method pretty regularly in our main loop.
666      *
667      * @return  void
668      *
669      * @codeCoverageIgnore
670      * @since   11.1
671      */
672     protected function gc()
673     {
674         // Perform generic garbage collection.
675         gc_collect_cycles();
676 
677         // Clear the stat cache so it doesn't blow up memory.
678         clearstatcache();
679     }
680 
681     /**
682      * Method to attach the JApplicationDaemon signal handler to the known signals.  Applications
683      * can override these handlers by using the pcntl_signal() function and attaching a different
684      * callback method.
685      *
686      * @return  boolean
687      *
688      * @since   11.1
689      * @see     pcntl_signal()
690      */
691     protected function setupSignalHandlers()
692     {
693         // We add the error suppression for the loop because on some platforms some constants are not defined.
694         foreach (self::$signals as $signal)
695         {
696             // Ignore signals that are not defined.
697             if (!defined($signal) || !is_int(constant($signal)) || (constant($signal) === 0))
698             {
699                 // Define the signal to avoid notices.
700                 JLog::add('Signal "' . $signal . '" not defined. Defining it as null.', JLog::DEBUG);
701                 define($signal, null);
702 
703                 // Don't listen for signal.
704                 continue;
705             }
706 
707             // Attach the signal handler for the signal.
708             if (!$this->pcntlSignal(constant($signal), array('JApplicationDaemon', 'signal')))
709             {
710                 JLog::add(sprintf('Unable to reroute signal handler: %s', $signal), JLog::EMERGENCY);
711 
712                 return false;
713             }
714         }
715 
716         return true;
717     }
718 
719     /**
720      * Method to shut down the daemon and optionally restart it.
721      *
722      * @param   boolean  $restart  True to restart the daemon on exit.
723      *
724      * @return  void
725      *
726      * @since   11.1
727      */
728     protected function shutdown($restart = false)
729     {
730         // If we are already exiting, chill.
731         if ($this->exiting)
732         {
733             return;
734         }
735         // If not, now we are.
736         else
737         {
738             $this->exiting = true;
739         }
740 
741         // If we aren't already daemonized then just kill the application.
742         if (!$this->running && !$this->isActive())
743         {
744             JLog::add('Process was not daemonized yet, just halting current process', JLog::INFO);
745             $this->close();
746         }
747 
748         // Only read the pid for the parent file.
749         if ($this->parentId == $this->processId)
750         {
751             // Read the contents of the process id file as an integer.
752             $fp = fopen($this->config->get('application_pid_file'), 'r');
753             $pid = fread($fp, filesize($this->config->get('application_pid_file')));
754             $pid = (int) $pid;
755             fclose($fp);
756 
757             // Remove the process id file.
758             @ unlink($this->config->get('application_pid_file'));
759 
760             // If we are supposed to restart the daemon we need to execute the same command.
761             if ($restart)
762             {
763                 $this->close(exec(implode(' ', $GLOBALS['argv']) . ' > /dev/null &'));
764             }
765             // If we are not supposed to restart the daemon let's just kill -9.
766             else
767             {
768                 passthru('kill -9 ' . $pid);
769                 $this->close();
770             }
771         }
772     }
773 
774     /**
775      * Method to write the process id file out to disk.
776      *
777      * @return  boolean
778      *
779      * @since   11.1
780      */
781     protected function writeProcessIdFile()
782     {
783         // Verify the process id is valid.
784         if ($this->processId < 1)
785         {
786             JLog::add('The process id is invalid.', JLog::EMERGENCY);
787 
788             return false;
789         }
790 
791         // Get the application process id file path.
792         $file = $this->config->get('application_pid_file');
793 
794         if (empty($file))
795         {
796             JLog::add('The process id file path is empty.', JLog::ERROR);
797 
798             return false;
799         }
800 
801         // Make sure that the folder where we are writing the process id file exists.
802         $folder = dirname($file);
803 
804         if (!is_dir($folder) && !JFolder::create($folder))
805         {
806             JLog::add('Unable to create directory: ' . $folder, JLog::ERROR);
807 
808             return false;
809         }
810 
811         // Write the process id file out to disk.
812         if (!file_put_contents($file, $this->processId))
813         {
814             JLog::add('Unable to write proccess id file: ' . $file, JLog::ERROR);
815 
816             return false;
817         }
818 
819         // Make sure the permissions for the proccess id file are accurate.
820         if (!chmod($file, 0644))
821         {
822             JLog::add('Unable to adjust permissions for the proccess id file: ' . $file, JLog::ERROR);
823 
824             return false;
825         }
826 
827         return true;
828     }
829 
830     /**
831      * Method to handle post-fork triggering of the onFork event.
832      *
833      * @return  void
834      *
835      * @since   12.1
836      */
837     protected function postFork()
838     {
839         // Trigger the onFork event.
840         $this->triggerEvent('onFork');
841     }
842 
843     /**
844      * Method to return the exit code of a terminated child process.
845      *
846      * @param   integer  $status  The status parameter is the status parameter supplied to a successful call to pcntl_waitpid().
847      *
848      * @return  integer  The child process exit code.
849      *
850      * @codeCoverageIgnore
851      * @see     pcntl_wexitstatus()
852      * @since   11.3
853      */
854     protected function pcntlChildExitStatus($status)
855     {
856         return pcntl_wexitstatus($status);
857     }
858 
859     /**
860      * Method to return the exit code of a terminated child process.
861      *
862      * @return  integer  On success, the PID of the child process is returned in the parent's thread
863      *                   of execution, and a 0 is returned in the child's thread of execution. On
864      *                   failure, a -1 will be returned in the parent's context, no child process
865      *                   will be created, and a PHP error is raised.
866      *
867      * @codeCoverageIgnore
868      * @see     pcntl_fork()
869      * @since   11.3
870      */
871     protected function pcntlFork()
872     {
873         return pcntl_fork();
874     }
875 
876     /**
877      * Method to install a signal handler.
878      *
879      * @param   integer   $signal   The signal number.
880      * @param   callable  $handler  The signal handler which may be the name of a user created function,
881      *                              or method, or either of the two global constants SIG_IGN or SIG_DFL.
882      * @param   boolean   $restart  Specifies whether system call restarting should be used when this
883      *                              signal arrives.
884      *
885      * @return  boolean  True on success.
886      *
887      * @codeCoverageIgnore
888      * @see     pcntl_signal()
889      * @since   11.3
890      */
891     protected function pcntlSignal($signal, $handler, $restart = true)
892     {
893         return pcntl_signal($signal, $handler, $restart);
894     }
895 
896     /**
897      * Method to wait on or return the status of a forked child.
898      *
899      * @param   integer  &$status  Status information.
900      * @param   integer  $options  If wait3 is available on your system (mostly BSD-style systems),
901      *                             you can provide the optional options parameter.
902      *
903      * @return  integer  The process ID of the child which exited, -1 on error or zero if WNOHANG
904      *                   was provided as an option (on wait3-available systems) and no child was available.
905      *
906      * @codeCoverageIgnore
907      * @see     pcntl_wait()
908      * @since   11.3
909      */
910     protected function pcntlWait(&$status, $options = 0)
911     {
912         return pcntl_wait($status, $options);
913     }
914 }
915 
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.