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  * PHPMailer RFC821 SMTP email transport class.
   4  * PHP Version 5
   5  * @package PHPMailer
   6  * @link https://github.com/PHPMailer/PHPMailer/ The PHPMailer GitHub project
   7  * @author Marcus Bointon (Synchro/coolbru) <phpmailer@synchromedia.co.uk>
   8  * @author Jim Jagielski (jimjag) <jimjag@gmail.com>
   9  * @author Andy Prevost (codeworxtech) <codeworxtech@users.sourceforge.net>
  10  * @author Brent R. Matzelle (original founder)
  11  * @copyright 2014 Marcus Bointon
  12  * @copyright 2010 - 2012 Jim Jagielski
  13  * @copyright 2004 - 2009 Andy Prevost
  14  * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
  15  * @note This program is distributed in the hope that it will be useful - WITHOUT
  16  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  17  * FITNESS FOR A PARTICULAR PURPOSE.
  18  */
  19 
  20 /**
  21  * PHPMailer RFC821 SMTP email transport class.
  22  * Implements RFC 821 SMTP commands and provides some utility methods for sending mail to an SMTP server.
  23  * @package PHPMailer
  24  * @author Chris Ryan
  25  * @author Marcus Bointon <phpmailer@synchromedia.co.uk>
  26  */
  27 class SMTP
  28 {
  29     /**
  30      * The PHPMailer SMTP version number.
  31      * @var string
  32      */
  33     const VERSION = '5.2.23';
  34 
  35     /**
  36      * SMTP line break constant.
  37      * @var string
  38      */
  39     const CRLF = "\r\n";
  40 
  41     /**
  42      * The SMTP port to use if one is not specified.
  43      * @var integer
  44      */
  45     const DEFAULT_SMTP_PORT = 25;
  46 
  47     /**
  48      * The maximum line length allowed by RFC 2822 section 2.1.1
  49      * @var integer
  50      */
  51     const MAX_LINE_LENGTH = 998;
  52 
  53     /**
  54      * Debug level for no output
  55      */
  56     const DEBUG_OFF = 0;
  57 
  58     /**
  59      * Debug level to show client -> server messages
  60      */
  61     const DEBUG_CLIENT = 1;
  62 
  63     /**
  64      * Debug level to show client -> server and server -> client messages
  65      */
  66     const DEBUG_SERVER = 2;
  67 
  68     /**
  69      * Debug level to show connection status, client -> server and server -> client messages
  70      */
  71     const DEBUG_CONNECTION = 3;
  72 
  73     /**
  74      * Debug level to show all messages
  75      */
  76     const DEBUG_LOWLEVEL = 4;
  77 
  78     /**
  79      * The PHPMailer SMTP Version number.
  80      * @var string
  81      * @deprecated Use the `VERSION` constant instead
  82      * @see SMTP::VERSION
  83      */
  84     public $Version = '5.2.23';
  85 
  86     /**
  87      * SMTP server port number.
  88      * @var integer
  89      * @deprecated This is only ever used as a default value, so use the `DEFAULT_SMTP_PORT` constant instead
  90      * @see SMTP::DEFAULT_SMTP_PORT
  91      */
  92     public $SMTP_PORT = 25;
  93 
  94     /**
  95      * SMTP reply line ending.
  96      * @var string
  97      * @deprecated Use the `CRLF` constant instead
  98      * @see SMTP::CRLF
  99      */
 100     public $CRLF = "\r\n";
 101 
 102     /**
 103      * Debug output level.
 104      * Options:
 105      * * self::DEBUG_OFF (`0`) No debug output, default
 106      * * self::DEBUG_CLIENT (`1`) Client commands
 107      * * self::DEBUG_SERVER (`2`) Client commands and server responses
 108      * * self::DEBUG_CONNECTION (`3`) As DEBUG_SERVER plus connection status
 109      * * self::DEBUG_LOWLEVEL (`4`) Low-level data output, all messages
 110      * @var integer
 111      */
 112     public $do_debug = self::DEBUG_OFF;
 113 
 114     /**
 115      * How to handle debug output.
 116      * Options:
 117      * * `echo` Output plain-text as-is, appropriate for CLI
 118      * * `html` Output escaped, line breaks converted to `<br>`, appropriate for browser output
 119      * * `error_log` Output to error log as configured in php.ini
 120      *
 121      * Alternatively, you can provide a callable expecting two params: a message string and the debug level:
 122      * <code>
 123      * $smtp->Debugoutput = function($str, $level) {echo "debug level $level; message: $str";};
 124      * </code>
 125      * @var string|callable
 126      */
 127     public $Debugoutput = 'echo';
 128 
 129     /**
 130      * Whether to use VERP.
 131      * @link http://en.wikipedia.org/wiki/Variable_envelope_return_path
 132      * @link http://www.postfix.org/VERP_README.html Info on VERP
 133      * @var boolean
 134      */
 135     public $do_verp = false;
 136 
 137     /**
 138      * The timeout value for connection, in seconds.
 139      * Default of 5 minutes (300sec) is from RFC2821 section 4.5.3.2
 140      * This needs to be quite high to function correctly with hosts using greetdelay as an anti-spam measure.
 141      * @link http://tools.ietf.org/html/rfc2821#section-4.5.3.2
 142      * @var integer
 143      */
 144     public $Timeout = 300;
 145 
 146     /**
 147      * How long to wait for commands to complete, in seconds.
 148      * Default of 5 minutes (300sec) is from RFC2821 section 4.5.3.2
 149      * @var integer
 150      */
 151     public $Timelimit = 300;
 152 
 153     /**
 154      * @var array patterns to extract smtp transaction id from smtp reply
 155      * Only first capture group will be use, use non-capturing group to deal with it
 156      * Extend this class to override this property to fulfil your needs.
 157      */
 158     protected $smtp_transaction_id_patterns = array(
 159         'exim' => '/[0-9]{3} OK id=(.*)/',
 160         'sendmail' => '/[0-9]{3} 2.0.0 (.*) Message/',
 161         'postfix' => '/[0-9]{3} 2.0.0 Ok: queued as (.*)/'
 162     );
 163 
 164     /**
 165      * The socket for the server connection.
 166      * @var resource
 167      */
 168     protected $smtp_conn;
 169 
 170     /**
 171      * Error information, if any, for the last SMTP command.
 172      * @var array
 173      */
 174     protected $error = array(
 175         'error' => '',
 176         'detail' => '',
 177         'smtp_code' => '',
 178         'smtp_code_ex' => ''
 179     );
 180 
 181     /**
 182      * The reply the server sent to us for HELO.
 183      * If null, no HELO string has yet been received.
 184      * @var string|null
 185      */
 186     protected $helo_rply = null;
 187 
 188     /**
 189      * The set of SMTP extensions sent in reply to EHLO command.
 190      * Indexes of the array are extension names.
 191      * Value at index 'HELO' or 'EHLO' (according to command that was sent)
 192      * represents the server name. In case of HELO it is the only element of the array.
 193      * Other values can be boolean TRUE or an array containing extension options.
 194      * If null, no HELO/EHLO string has yet been received.
 195      * @var array|null
 196      */
 197     protected $server_caps = null;
 198 
 199     /**
 200      * The most recent reply received from the server.
 201      * @var string
 202      */
 203     protected $last_reply = '';
 204 
 205     /**
 206      * Output debugging info via a user-selected method.
 207      * @see SMTP::$Debugoutput
 208      * @see SMTP::$do_debug
 209      * @param string $str Debug string to output
 210      * @param integer $level The debug level of this message; see DEBUG_* constants
 211      * @return void
 212      */
 213     protected function edebug($str, $level = 0)
 214     {
 215         if ($level > $this->do_debug) {
 216             return;
 217         }
 218         //Avoid clash with built-in function names
 219         if (!in_array($this->Debugoutput, array('error_log', 'html', 'echo')) and is_callable($this->Debugoutput)) {
 220             call_user_func($this->Debugoutput, $str, $level);
 221             return;
 222         }
 223         switch ($this->Debugoutput) {
 224             case 'error_log':
 225                 //Don't output, just log
 226                 error_log($str);
 227                 break;
 228             case 'html':
 229                 //Cleans up output a bit for a better looking, HTML-safe output
 230                 echo htmlentities(
 231                     preg_replace('/[\r\n]+/', '', $str),
 232                     ENT_QUOTES,
 233                     'UTF-8'
 234                 ) . "<br>\n";
 235                 break;
 236             case 'echo':
 237             default:
 238                 //Normalize line breaks
 239                 $str = preg_replace('/(\r\n|\r|\n)/ms', "\n", $str);
 240                 echo gmdate('Y-m-d H:i:s') . "\t" . str_replace(
 241                     "\n",
 242                     "\n                   \t                  ",
 243                     trim($str)
 244                 ) . "\n";
 245         }
 246     }
 247 
 248     /**
 249      * Connect to an SMTP server.
 250      * @param string $host SMTP server IP or host name
 251      * @param integer $port The port number to connect to
 252      * @param integer $timeout How long to wait for the connection to open
 253      * @param array $options An array of options for stream_context_create()
 254      * @access public
 255      * @return boolean
 256      */
 257     public function connect($host, $port = null, $timeout = 30, $options = array())
 258     {
 259         static $streamok;
 260         //This is enabled by default since 5.0.0 but some providers disable it
 261         //Check this once and cache the result
 262         if (is_null($streamok)) {
 263             $streamok = function_exists('stream_socket_client');
 264         }
 265         // Clear errors to avoid confusion
 266         $this->setError('');
 267         // Make sure we are __not__ connected
 268         if ($this->connected()) {
 269             // Already connected, generate error
 270             $this->setError('Already connected to a server');
 271             return false;
 272         }
 273         if (empty($port)) {
 274             $port = self::DEFAULT_SMTP_PORT;
 275         }
 276         // Connect to the SMTP server
 277         $this->edebug(
 278             "Connection: opening to $host:$port, timeout=$timeout, options=" .
 279             var_export($options, true),
 280             self::DEBUG_CONNECTION
 281         );
 282         $errno = 0;
 283         $errstr = '';
 284         if ($streamok) {
 285             $socket_context = stream_context_create($options);
 286             set_error_handler(array($this, 'errorHandler'));
 287             $this->smtp_conn = stream_socket_client(
 288                 $host . ":" . $port,
 289                 $errno,
 290                 $errstr,
 291                 $timeout,
 292                 STREAM_CLIENT_CONNECT,
 293                 $socket_context
 294             );
 295             restore_error_handler();
 296         } else {
 297             //Fall back to fsockopen which should work in more places, but is missing some features
 298             $this->edebug(
 299                 "Connection: stream_socket_client not available, falling back to fsockopen",
 300                 self::DEBUG_CONNECTION
 301             );
 302             set_error_handler(array($this, 'errorHandler'));
 303             $this->smtp_conn = fsockopen(
 304                 $host,
 305                 $port,
 306                 $errno,
 307                 $errstr,
 308                 $timeout
 309             );
 310             restore_error_handler();
 311         }
 312         // Verify we connected properly
 313         if (!is_resource($this->smtp_conn)) {
 314             $this->setError(
 315                 'Failed to connect to server',
 316                 $errno,
 317                 $errstr
 318             );
 319             $this->edebug(
 320                 'SMTP ERROR: ' . $this->error['error']
 321                 . ": $errstr ($errno)",
 322                 self::DEBUG_CLIENT
 323             );
 324             return false;
 325         }
 326         $this->edebug('Connection: opened', self::DEBUG_CONNECTION);
 327         // SMTP server can take longer to respond, give longer timeout for first read
 328         // Windows does not have support for this timeout function
 329         if (substr(PHP_OS, 0, 3) != 'WIN') {
 330             $max = ini_get('max_execution_time');
 331             // Don't bother if unlimited
 332             if ($max != 0 && $timeout > $max) {
 333                 @set_time_limit($timeout);
 334             }
 335             stream_set_timeout($this->smtp_conn, $timeout, 0);
 336         }
 337         // Get any announcement
 338         $announce = $this->get_lines();
 339         $this->edebug('SERVER -> CLIENT: ' . $announce, self::DEBUG_SERVER);
 340         return true;
 341     }
 342 
 343     /**
 344      * Initiate a TLS (encrypted) session.
 345      * @access public
 346      * @return boolean
 347      */
 348     public function startTLS()
 349     {
 350         if (!$this->sendCommand('STARTTLS', 'STARTTLS', 220)) {
 351             return false;
 352         }
 353 
 354         //Allow the best TLS version(s) we can
 355         $crypto_method = STREAM_CRYPTO_METHOD_TLS_CLIENT;
 356 
 357         //PHP 5.6.7 dropped inclusion of TLS 1.1 and 1.2 in STREAM_CRYPTO_METHOD_TLS_CLIENT
 358         //so add them back in manually if we can
 359         if (defined('STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT')) {
 360             $crypto_method |= STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT;
 361             $crypto_method |= STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT;
 362         }
 363 
 364         // Begin encrypted connection
 365         set_error_handler(array($this, 'errorHandler'));
 366         $crypto_ok = stream_socket_enable_crypto(
 367             $this->smtp_conn,
 368             true,
 369             $crypto_method
 370         );
 371         restore_error_handler();
 372         return $crypto_ok;
 373     }
 374 
 375     /**
 376      * Perform SMTP authentication.
 377      * Must be run after hello().
 378      * @see hello()
 379      * @param string $username The user name
 380      * @param string $password The password
 381      * @param string $authtype The auth type (PLAIN, LOGIN, NTLM, CRAM-MD5, XOAUTH2)
 382      * @param string $realm The auth realm for NTLM
 383      * @param string $workstation The auth workstation for NTLM
 384      * @param null|OAuth $OAuth An optional OAuth instance (@see PHPMailerOAuth)
 385      * @return bool True if successfully authenticated.* @access public
 386      */
 387     public function authenticate(
 388         $username,
 389         $password,
 390         $authtype = null,
 391         $realm = '',
 392         $workstation = '',
 393         $OAuth = null
 394     ) {
 395         if (!$this->server_caps) {
 396             $this->setError('Authentication is not allowed before HELO/EHLO');
 397             return false;
 398         }
 399 
 400         if (array_key_exists('EHLO', $this->server_caps)) {
 401             // SMTP extensions are available; try to find a proper authentication method
 402             if (!array_key_exists('AUTH', $this->server_caps)) {
 403                 $this->setError('Authentication is not allowed at this stage');
 404                 // 'at this stage' means that auth may be allowed after the stage changes
 405                 // e.g. after STARTTLS
 406                 return false;
 407             }
 408 
 409             self::edebug('Auth method requested: ' . ($authtype ? $authtype : 'UNKNOWN'), self::DEBUG_LOWLEVEL);
 410             self::edebug(
 411                 'Auth methods available on the server: ' . implode(',', $this->server_caps['AUTH']),
 412                 self::DEBUG_LOWLEVEL
 413             );
 414 
 415             if (empty($authtype)) {
 416                 foreach (array('CRAM-MD5', 'LOGIN', 'PLAIN', 'NTLM', 'XOAUTH2') as $method) {
 417                     if (in_array($method, $this->server_caps['AUTH'])) {
 418                         $authtype = $method;
 419                         break;
 420                     }
 421                 }
 422                 if (empty($authtype)) {
 423                     $this->setError('No supported authentication methods found');
 424                     return false;
 425                 }
 426                 self::edebug('Auth method selected: ' . $authtype, self::DEBUG_LOWLEVEL);
 427             }
 428 
 429             if (!in_array($authtype, $this->server_caps['AUTH'])) {
 430                 $this->setError("The requested authentication method \"$authtype\" is not supported by the server");
 431                 return false;
 432             }
 433         } elseif (empty($authtype)) {
 434             $authtype = 'LOGIN';
 435         }
 436         switch ($authtype) {
 437             case 'PLAIN':
 438                 // Start authentication
 439                 if (!$this->sendCommand('AUTH', 'AUTH PLAIN', 334)) {
 440                     return false;
 441                 }
 442                 // Send encoded username and password
 443                 if (!$this->sendCommand(
 444                     'User & Password',
 445                     base64_encode("\0" . $username . "\0" . $password),
 446                     235
 447                 )
 448                 ) {
 449                     return false;
 450                 }
 451                 break;
 452             case 'LOGIN':
 453                 // Start authentication
 454                 if (!$this->sendCommand('AUTH', 'AUTH LOGIN', 334)) {
 455                     return false;
 456                 }
 457                 if (!$this->sendCommand("Username", base64_encode($username), 334)) {
 458                     return false;
 459                 }
 460                 if (!$this->sendCommand("Password", base64_encode($password), 235)) {
 461                     return false;
 462                 }
 463                 break;
 464             case 'XOAUTH2':
 465                 //If the OAuth Instance is not set. Can be a case when PHPMailer is used
 466                 //instead of PHPMailerOAuth
 467                 if (is_null($OAuth)) {
 468                     return false;
 469                 }
 470                 $oauth = $OAuth->getOauth64();
 471 
 472                 // Start authentication
 473                 if (!$this->sendCommand('AUTH', 'AUTH XOAUTH2 ' . $oauth, 235)) {
 474                     return false;
 475                 }
 476                 break;
 477             case 'NTLM':
 478                 /*
 479                  * ntlm_sasl_client.php
 480                  * Bundled with Permission
 481                  *
 482                  * How to telnet in windows:
 483                  * http://technet.microsoft.com/en-us/library/aa995718%28EXCHG.65%29.aspx
 484                  * PROTOCOL Docs http://curl.haxx.se/rfc/ntlm.html#ntlmSmtpAuthentication
 485                  */
 486                 require_once 'extras/ntlm_sasl_client.php';
 487                 $temp = new stdClass;
 488                 $ntlm_client = new ntlm_sasl_client_class;
 489                 //Check that functions are available
 490                 if (!$ntlm_client->initialize($temp)) {
 491                     $this->setError($temp->error);
 492                     $this->edebug(
 493                         'You need to enable some modules in your php.ini file: '
 494                         . $this->error['error'],
 495                         self::DEBUG_CLIENT
 496                     );
 497                     return false;
 498                 }
 499                 //msg1
 500                 $msg1 = $ntlm_client->typeMsg1($realm, $workstation); //msg1
 501 
 502                 if (!$this->sendCommand(
 503                     'AUTH NTLM',
 504                     'AUTH NTLM ' . base64_encode($msg1),
 505                     334
 506                 )
 507                 ) {
 508                     return false;
 509                 }
 510                 //Though 0 based, there is a white space after the 3 digit number
 511                 //msg2
 512                 $challenge = substr($this->last_reply, 3);
 513                 $challenge = base64_decode($challenge);
 514                 $ntlm_res = $ntlm_client->NTLMResponse(
 515                     substr($challenge, 24, 8),
 516                     $password
 517                 );
 518                 //msg3
 519                 $msg3 = $ntlm_client->typeMsg3(
 520                     $ntlm_res,
 521                     $username,
 522                     $realm,
 523                     $workstation
 524                 );
 525                 // send encoded username
 526                 return $this->sendCommand('Username', base64_encode($msg3), 235);
 527             case 'CRAM-MD5':
 528                 // Start authentication
 529                 if (!$this->sendCommand('AUTH CRAM-MD5', 'AUTH CRAM-MD5', 334)) {
 530                     return false;
 531                 }
 532                 // Get the challenge
 533                 $challenge = base64_decode(substr($this->last_reply, 4));
 534 
 535                 // Build the response
 536                 $response = $username . ' ' . $this->hmac($challenge, $password);
 537 
 538                 // send encoded credentials
 539                 return $this->sendCommand('Username', base64_encode($response), 235);
 540             default:
 541                 $this->setError("Authentication method \"$authtype\" is not supported");
 542                 return false;
 543         }
 544         return true;
 545     }
 546 
 547     /**
 548      * Calculate an MD5 HMAC hash.
 549      * Works like hash_hmac('md5', $data, $key)
 550      * in case that function is not available
 551      * @param string $data The data to hash
 552      * @param string $key The key to hash with
 553      * @access protected
 554      * @return string
 555      */
 556     protected function hmac($data, $key)
 557     {
 558         if (function_exists('hash_hmac')) {
 559             return hash_hmac('md5', $data, $key);
 560         }
 561 
 562         // The following borrowed from
 563         // http://php.net/manual/en/function.mhash.php#27225
 564 
 565         // RFC 2104 HMAC implementation for php.
 566         // Creates an md5 HMAC.
 567         // Eliminates the need to install mhash to compute a HMAC
 568         // by Lance Rushing
 569 
 570         $bytelen = 64; // byte length for md5
 571         if (strlen($key) > $bytelen) {
 572             $key = pack('H*', md5($key));
 573         }
 574         $key = str_pad($key, $bytelen, chr(0x00));
 575         $ipad = str_pad('', $bytelen, chr(0x36));
 576         $opad = str_pad('', $bytelen, chr(0x5c));
 577         $k_ipad = $key ^ $ipad;
 578         $k_opad = $key ^ $opad;
 579 
 580         return md5($k_opad . pack('H*', md5($k_ipad . $data)));
 581     }
 582 
 583     /**
 584      * Check connection state.
 585      * @access public
 586      * @return boolean True if connected.
 587      */
 588     public function connected()
 589     {
 590         if (is_resource($this->smtp_conn)) {
 591             $sock_status = stream_get_meta_data($this->smtp_conn);
 592             if ($sock_status['eof']) {
 593                 // The socket is valid but we are not connected
 594                 $this->edebug(
 595                     'SMTP NOTICE: EOF caught while checking if connected',
 596                     self::DEBUG_CLIENT
 597                 );
 598                 $this->close();
 599                 return false;
 600             }
 601             return true; // everything looks good
 602         }
 603         return false;
 604     }
 605 
 606     /**
 607      * Close the socket and clean up the state of the class.
 608      * Don't use this function without first trying to use QUIT.
 609      * @see quit()
 610      * @access public
 611      * @return void
 612      */
 613     public function close()
 614     {
 615         $this->setError('');
 616         $this->server_caps = null;
 617         $this->helo_rply = null;
 618         if (is_resource($this->smtp_conn)) {
 619             // close the connection and cleanup
 620             fclose($this->smtp_conn);
 621             $this->smtp_conn = null; //Makes for cleaner serialization
 622             $this->edebug('Connection: closed', self::DEBUG_CONNECTION);
 623         }
 624     }
 625 
 626     /**
 627      * Send an SMTP DATA command.
 628      * Issues a data command and sends the msg_data to the server,
 629      * finializing the mail transaction. $msg_data is the message
 630      * that is to be send with the headers. Each header needs to be
 631      * on a single line followed by a <CRLF> with the message headers
 632      * and the message body being separated by and additional <CRLF>.
 633      * Implements rfc 821: DATA <CRLF>
 634      * @param string $msg_data Message data to send
 635      * @access public
 636      * @return boolean
 637      */
 638     public function data($msg_data)
 639     {
 640         //This will use the standard timelimit
 641         if (!$this->sendCommand('DATA', 'DATA', 354)) {
 642             return false;
 643         }
 644 
 645         /* The server is ready to accept data!
 646          * According to rfc821 we should not send more than 1000 characters on a single line (including the CRLF)
 647          * so we will break the data up into lines by \r and/or \n then if needed we will break each of those into
 648          * smaller lines to fit within the limit.
 649          * We will also look for lines that start with a '.' and prepend an additional '.'.
 650          * NOTE: this does not count towards line-length limit.
 651          */
 652 
 653         // Normalize line breaks before exploding
 654         $lines = explode("\n", str_replace(array("\r\n", "\r"), "\n", $msg_data));
 655 
 656         /* To distinguish between a complete RFC822 message and a plain message body, we check if the first field
 657          * of the first line (':' separated) does not contain a space then it _should_ be a header and we will
 658          * process all lines before a blank line as headers.
 659          */
 660 
 661         $field = substr($lines[0], 0, strpos($lines[0], ':'));
 662         $in_headers = false;
 663         if (!empty($field) && strpos($field, ' ') === false) {
 664             $in_headers = true;
 665         }
 666 
 667         foreach ($lines as $line) {
 668             $lines_out = array();
 669             if ($in_headers and $line == '') {
 670                 $in_headers = false;
 671             }
 672             //Break this line up into several smaller lines if it's too long
 673             //Micro-optimisation: isset($str[$len]) is faster than (strlen($str) > $len),
 674             while (isset($line[self::MAX_LINE_LENGTH])) {
 675                 //Working backwards, try to find a space within the last MAX_LINE_LENGTH chars of the line to break on
 676                 //so as to avoid breaking in the middle of a word
 677                 $pos = strrpos(substr($line, 0, self::MAX_LINE_LENGTH), ' ');
 678                 //Deliberately matches both false and 0
 679                 if (!$pos) {
 680                     //No nice break found, add a hard break
 681                     $pos = self::MAX_LINE_LENGTH - 1;
 682                     $lines_out[] = substr($line, 0, $pos);
 683                     $line = substr($line, $pos);
 684                 } else {
 685                     //Break at the found point
 686                     $lines_out[] = substr($line, 0, $pos);
 687                     //Move along by the amount we dealt with
 688                     $line = substr($line, $pos + 1);
 689                 }
 690                 //If processing headers add a LWSP-char to the front of new line RFC822 section 3.1.1
 691                 if ($in_headers) {
 692                     $line = "\t" . $line;
 693                 }
 694             }
 695             $lines_out[] = $line;
 696 
 697             //Send the lines to the server
 698             foreach ($lines_out as $line_out) {
 699                 //RFC2821 section 4.5.2
 700                 if (!empty($line_out) and $line_out[0] == '.') {
 701                     $line_out = '.' . $line_out;
 702                 }
 703                 $this->client_send($line_out . self::CRLF);
 704             }
 705         }
 706 
 707         //Message data has been sent, complete the command
 708         //Increase timelimit for end of DATA command
 709         $savetimelimit = $this->Timelimit;
 710         $this->Timelimit = $this->Timelimit * 2;
 711         $result = $this->sendCommand('DATA END', '.', 250);
 712         //Restore timelimit
 713         $this->Timelimit = $savetimelimit;
 714         return $result;
 715     }
 716 
 717     /**
 718      * Send an SMTP HELO or EHLO command.
 719      * Used to identify the sending server to the receiving server.
 720      * This makes sure that client and server are in a known state.
 721      * Implements RFC 821: HELO <SP> <domain> <CRLF>
 722      * and RFC 2821 EHLO.
 723      * @param string $host The host name or IP to connect to
 724      * @access public
 725      * @return boolean
 726      */
 727     public function hello($host = '')
 728     {
 729         //Try extended hello first (RFC 2821)
 730         return (boolean)($this->sendHello('EHLO', $host) or $this->sendHello('HELO', $host));
 731     }
 732 
 733     /**
 734      * Send an SMTP HELO or EHLO command.
 735      * Low-level implementation used by hello()
 736      * @see hello()
 737      * @param string $hello The HELO string
 738      * @param string $host The hostname to say we are
 739      * @access protected
 740      * @return boolean
 741      */
 742     protected function sendHello($hello, $host)
 743     {
 744         $noerror = $this->sendCommand($hello, $hello . ' ' . $host, 250);
 745         $this->helo_rply = $this->last_reply;
 746         if ($noerror) {
 747             $this->parseHelloFields($hello);
 748         } else {
 749             $this->server_caps = null;
 750         }
 751         return $noerror;
 752     }
 753 
 754     /**
 755      * Parse a reply to HELO/EHLO command to discover server extensions.
 756      * In case of HELO, the only parameter that can be discovered is a server name.
 757      * @access protected
 758      * @param string $type - 'HELO' or 'EHLO'
 759      */
 760     protected function parseHelloFields($type)
 761     {
 762         $this->server_caps = array();
 763         $lines = explode("\n", $this->helo_rply);
 764 
 765         foreach ($lines as $n => $s) {
 766             //First 4 chars contain response code followed by - or space
 767             $s = trim(substr($s, 4));
 768             if (empty($s)) {
 769                 continue;
 770             }
 771             $fields = explode(' ', $s);
 772             if (!empty($fields)) {
 773                 if (!$n) {
 774                     $name = $type;
 775                     $fields = $fields[0];
 776                 } else {
 777                     $name = array_shift($fields);
 778                     switch ($name) {
 779                         case 'SIZE':
 780                             $fields = ($fields ? $fields[0] : 0);
 781                             break;
 782                         case 'AUTH':
 783                             if (!is_array($fields)) {
 784                                 $fields = array();
 785                             }
 786                             break;
 787                         default:
 788                             $fields = true;
 789                     }
 790                 }
 791                 $this->server_caps[$name] = $fields;
 792             }
 793         }
 794     }
 795 
 796     /**
 797      * Send an SMTP MAIL command.
 798      * Starts a mail transaction from the email address specified in
 799      * $from. Returns true if successful or false otherwise. If True
 800      * the mail transaction is started and then one or more recipient
 801      * commands may be called followed by a data command.
 802      * Implements rfc 821: MAIL <SP> FROM:<reverse-path> <CRLF>
 803      * @param string $from Source address of this message
 804      * @access public
 805      * @return boolean
 806      */
 807     public function mail($from)
 808     {
 809         $useVerp = ($this->do_verp ? ' XVERP' : '');
 810         return $this->sendCommand(
 811             'MAIL FROM',
 812             'MAIL FROM:<' . $from . '>' . $useVerp,
 813             250
 814         );
 815     }
 816 
 817     /**
 818      * Send an SMTP QUIT command.
 819      * Closes the socket if there is no error or the $close_on_error argument is true.
 820      * Implements from rfc 821: QUIT <CRLF>
 821      * @param boolean $close_on_error Should the connection close if an error occurs?
 822      * @access public
 823      * @return boolean
 824      */
 825     public function quit($close_on_error = true)
 826     {
 827         $noerror = $this->sendCommand('QUIT', 'QUIT', 221);
 828         $err = $this->error; //Save any error
 829         if ($noerror or $close_on_error) {
 830             $this->close();
 831             $this->error = $err; //Restore any error from the quit command
 832         }
 833         return $noerror;
 834     }
 835 
 836     /**
 837      * Send an SMTP RCPT command.
 838      * Sets the TO argument to $toaddr.
 839      * Returns true if the recipient was accepted false if it was rejected.
 840      * Implements from rfc 821: RCPT <SP> TO:<forward-path> <CRLF>
 841      * @param string $address The address the message is being sent to
 842      * @access public
 843      * @return boolean
 844      */
 845     public function recipient($address)
 846     {
 847         return $this->sendCommand(
 848             'RCPT TO',
 849             'RCPT TO:<' . $address . '>',
 850             array(250, 251)
 851         );
 852     }
 853 
 854     /**
 855      * Send an SMTP RSET command.
 856      * Abort any transaction that is currently in progress.
 857      * Implements rfc 821: RSET <CRLF>
 858      * @access public
 859      * @return boolean True on success.
 860      */
 861     public function reset()
 862     {
 863         return $this->sendCommand('RSET', 'RSET', 250);
 864     }
 865 
 866     /**
 867      * Send a command to an SMTP server and check its return code.
 868      * @param string $command The command name - not sent to the server
 869      * @param string $commandstring The actual command to send
 870      * @param integer|array $expect One or more expected integer success codes
 871      * @access protected
 872      * @return boolean True on success.
 873      */
 874     protected function sendCommand($command, $commandstring, $expect)
 875     {
 876         if (!$this->connected()) {
 877             $this->setError("Called $command without being connected");
 878             return false;
 879         }
 880         //Reject line breaks in all commands
 881         if (strpos($commandstring, "\n") !== false or strpos($commandstring, "\r") !== false) {
 882             $this->setError("Command '$command' contained line breaks");
 883             return false;
 884         }
 885         $this->client_send($commandstring . self::CRLF);
 886 
 887         $this->last_reply = $this->get_lines();
 888         // Fetch SMTP code and possible error code explanation
 889         $matches = array();
 890         if (preg_match("/^([0-9]{3})[ -](?:([0-9]\\.[0-9]\\.[0-9]) )?/", $this->last_reply, $matches)) {
 891             $code = $matches[1];
 892             $code_ex = (count($matches) > 2 ? $matches[2] : null);
 893             // Cut off error code from each response line
 894             $detail = preg_replace(
 895                 "/{$code}[ -]" .
 896                 ($code_ex ? str_replace('.', '\\.', $code_ex) . ' ' : '') . "/m",
 897                 '',
 898                 $this->last_reply
 899             );
 900         } else {
 901             // Fall back to simple parsing if regex fails
 902             $code = substr($this->last_reply, 0, 3);
 903             $code_ex = null;
 904             $detail = substr($this->last_reply, 4);
 905         }
 906 
 907         $this->edebug('SERVER -> CLIENT: ' . $this->last_reply, self::DEBUG_SERVER);
 908 
 909         if (!in_array($code, (array)$expect)) {
 910             $this->setError(
 911                 "$command command failed",
 912                 $detail,
 913                 $code,
 914                 $code_ex
 915             );
 916             $this->edebug(
 917                 'SMTP ERROR: ' . $this->error['error'] . ': ' . $this->last_reply,
 918                 self::DEBUG_CLIENT
 919             );
 920             return false;
 921         }
 922 
 923         $this->setError('');
 924         return true;
 925     }
 926 
 927     /**
 928      * Send an SMTP SAML command.
 929      * Starts a mail transaction from the email address specified in $from.
 930      * Returns true if successful or false otherwise. If True
 931      * the mail transaction is started and then one or more recipient
 932      * commands may be called followed by a data command. This command
 933      * will send the message to the users terminal if they are logged
 934      * in and send them an email.
 935      * Implements rfc 821: SAML <SP> FROM:<reverse-path> <CRLF>
 936      * @param string $from The address the message is from
 937      * @access public
 938      * @return boolean
 939      */
 940     public function sendAndMail($from)
 941     {
 942         return $this->sendCommand('SAML', "SAML FROM:$from", 250);
 943     }
 944 
 945     /**
 946      * Send an SMTP VRFY command.
 947      * @param string $name The name to verify
 948      * @access public
 949      * @return boolean
 950      */
 951     public function verify($name)
 952     {
 953         return $this->sendCommand('VRFY', "VRFY $name", array(250, 251));
 954     }
 955 
 956     /**
 957      * Send an SMTP NOOP command.
 958      * Used to keep keep-alives alive, doesn't actually do anything
 959      * @access public
 960      * @return boolean
 961      */
 962     public function noop()
 963     {
 964         return $this->sendCommand('NOOP', 'NOOP', 250);
 965     }
 966 
 967     /**
 968      * Send an SMTP TURN command.
 969      * This is an optional command for SMTP that this class does not support.
 970      * This method is here to make the RFC821 Definition complete for this class
 971      * and _may_ be implemented in future
 972      * Implements from rfc 821: TURN <CRLF>
 973      * @access public
 974      * @return boolean
 975      */
 976     public function turn()
 977     {
 978         $this->setError('The SMTP TURN command is not implemented');
 979         $this->edebug('SMTP NOTICE: ' . $this->error['error'], self::DEBUG_CLIENT);
 980         return false;
 981     }
 982 
 983     /**
 984      * Send raw data to the server.
 985      * @param string $data The data to send
 986      * @access public
 987      * @return integer|boolean The number of bytes sent to the server or false on error
 988      */
 989     public function client_send($data)
 990     {
 991         $this->edebug("CLIENT -> SERVER: $data", self::DEBUG_CLIENT);
 992         return fwrite($this->smtp_conn, $data);
 993     }
 994 
 995     /**
 996      * Get the latest error.
 997      * @access public
 998      * @return array
 999      */
1000     public function getError()
1001     {
1002         return $this->error;
1003     }
1004 
1005     /**
1006      * Get SMTP extensions available on the server
1007      * @access public
1008      * @return array|null
1009      */
1010     public function getServerExtList()
1011     {
1012         return $this->server_caps;
1013     }
1014 
1015     /**
1016      * A multipurpose method
1017      * The method works in three ways, dependent on argument value and current state
1018      *   1. HELO/EHLO was not sent - returns null and set up $this->error
1019      *   2. HELO was sent
1020      *     $name = 'HELO': returns server name
1021      *     $name = 'EHLO': returns boolean false
1022      *     $name = any string: returns null and set up $this->error
1023      *   3. EHLO was sent
1024      *     $name = 'HELO'|'EHLO': returns server name
1025      *     $name = any string: if extension $name exists, returns boolean True
1026      *       or its options. Otherwise returns boolean False
1027      * In other words, one can use this method to detect 3 conditions:
1028      *  - null returned: handshake was not or we don't know about ext (refer to $this->error)
1029      *  - false returned: the requested feature exactly not exists
1030      *  - positive value returned: the requested feature exists
1031      * @param string $name Name of SMTP extension or 'HELO'|'EHLO'
1032      * @return mixed
1033      */
1034     public function getServerExt($name)
1035     {
1036         if (!$this->server_caps) {
1037             $this->setError('No HELO/EHLO was sent');
1038             return null;
1039         }
1040 
1041         // the tight logic knot ;)
1042         if (!array_key_exists($name, $this->server_caps)) {
1043             if ($name == 'HELO') {
1044                 return $this->server_caps['EHLO'];
1045             }
1046             if ($name == 'EHLO' || array_key_exists('EHLO', $this->server_caps)) {
1047                 return false;
1048             }
1049             $this->setError('HELO handshake was used. Client knows nothing about server extensions');
1050             return null;
1051         }
1052 
1053         return $this->server_caps[$name];
1054     }
1055 
1056     /**
1057      * Get the last reply from the server.
1058      * @access public
1059      * @return string
1060      */
1061     public function getLastReply()
1062     {
1063         return $this->last_reply;
1064     }
1065 
1066     /**
1067      * Read the SMTP server's response.
1068      * Either before eof or socket timeout occurs on the operation.
1069      * With SMTP we can tell if we have more lines to read if the
1070      * 4th character is '-' symbol. If it is a space then we don't
1071      * need to read anything else.
1072      * @access protected
1073      * @return string
1074      */
1075     protected function get_lines()
1076     {
1077         // If the connection is bad, give up straight away
1078         if (!is_resource($this->smtp_conn)) {
1079             return '';
1080         }
1081         $data = '';
1082         $endtime = 0;
1083         stream_set_timeout($this->smtp_conn, $this->Timeout);
1084         if ($this->Timelimit > 0) {
1085             $endtime = time() + $this->Timelimit;
1086         }
1087         while (is_resource($this->smtp_conn) && !feof($this->smtp_conn)) {
1088             $str = @fgets($this->smtp_conn, 515);
1089             $this->edebug("SMTP -> get_lines(): \$data is \"$data\"", self::DEBUG_LOWLEVEL);
1090             $this->edebug("SMTP -> get_lines(): \$str is  \"$str\"", self::DEBUG_LOWLEVEL);
1091             $data .= $str;
1092             // If 4th character is a space, we are done reading, break the loop, micro-optimisation over strlen
1093             if ((isset($str[3]) and $str[3] == ' ')) {
1094                 break;
1095             }
1096             // Timed-out? Log and break
1097             $info = stream_get_meta_data($this->smtp_conn);
1098             if ($info['timed_out']) {
1099                 $this->edebug(
1100                     'SMTP -> get_lines(): timed-out (' . $this->Timeout . ' sec)',
1101                     self::DEBUG_LOWLEVEL
1102                 );
1103                 break;
1104             }
1105             // Now check if reads took too long
1106             if ($endtime and time() > $endtime) {
1107                 $this->edebug(
1108                     'SMTP -> get_lines(): timelimit reached (' .
1109                     $this->Timelimit . ' sec)',
1110                     self::DEBUG_LOWLEVEL
1111                 );
1112                 break;
1113             }
1114         }
1115         return $data;
1116     }
1117 
1118     /**
1119      * Enable or disable VERP address generation.
1120      * @param boolean $enabled
1121      */
1122     public function setVerp($enabled = false)
1123     {
1124         $this->do_verp = $enabled;
1125     }
1126 
1127     /**
1128      * Get VERP address generation mode.
1129      * @return boolean
1130      */
1131     public function getVerp()
1132     {
1133         return $this->do_verp;
1134     }
1135 
1136     /**
1137      * Set error messages and codes.
1138      * @param string $message The error message
1139      * @param string $detail Further detail on the error
1140      * @param string $smtp_code An associated SMTP error code
1141      * @param string $smtp_code_ex Extended SMTP code
1142      */
1143     protected function setError($message, $detail = '', $smtp_code = '', $smtp_code_ex = '')
1144     {
1145         $this->error = array(
1146             'error' => $message,
1147             'detail' => $detail,
1148             'smtp_code' => $smtp_code,
1149             'smtp_code_ex' => $smtp_code_ex
1150         );
1151     }
1152 
1153     /**
1154      * Set debug output method.
1155      * @param string|callable $method The name of the mechanism to use for debugging output, or a callable to handle it.
1156      */
1157     public function setDebugOutput($method = 'echo')
1158     {
1159         $this->Debugoutput = $method;
1160     }
1161 
1162     /**
1163      * Get debug output method.
1164      * @return string
1165      */
1166     public function getDebugOutput()
1167     {
1168         return $this->Debugoutput;
1169     }
1170 
1171     /**
1172      * Set debug output level.
1173      * @param integer $level
1174      */
1175     public function setDebugLevel($level = 0)
1176     {
1177         $this->do_debug = $level;
1178     }
1179 
1180     /**
1181      * Get debug output level.
1182      * @return integer
1183      */
1184     public function getDebugLevel()
1185     {
1186         return $this->do_debug;
1187     }
1188 
1189     /**
1190      * Set SMTP timeout.
1191      * @param integer $timeout
1192      */
1193     public function setTimeout($timeout = 0)
1194     {
1195         $this->Timeout = $timeout;
1196     }
1197 
1198     /**
1199      * Get SMTP timeout.
1200      * @return integer
1201      */
1202     public function getTimeout()
1203     {
1204         return $this->Timeout;
1205     }
1206 
1207     /**
1208      * Reports an error number and string.
1209      * @param integer $errno The error number returned by PHP.
1210      * @param string $errmsg The error message returned by PHP.
1211      * @param string $errfile The file the error occurred in
1212      * @param integer $errline The line number the error occurred on
1213      */
1214     protected function errorHandler($errno, $errmsg, $errfile = '', $errline = 0)
1215     {
1216         $notice = 'Connection failed.';
1217         $this->setError(
1218             $notice,
1219             $errno,
1220             $errmsg
1221         );
1222         $this->edebug(
1223             $notice . ' Error #' . $errno . ': ' . $errmsg . " [$errfile line $errline]",
1224             self::DEBUG_CONNECTION
1225         );
1226     }
1227 
1228     /**
1229      * Will return the ID of the last smtp transaction based on a list of patterns provided
1230      * in SMTP::$smtp_transaction_id_patterns.
1231      * If no reply has been received yet, it will return null.
1232      * If no pattern has been matched, it will return false.
1233      * @return bool|null|string
1234      */
1235     public function getLastTransactionID()
1236     {
1237         $reply = $this->getLastReply();
1238 
1239         if (empty($reply)) {
1240             return null;
1241         }
1242 
1243         foreach ($this->smtp_transaction_id_patterns as $smtp_transaction_id_pattern) {
1244             if (preg_match($smtp_transaction_id_pattern, $reply, $matches)) {
1245                 return $matches[1];
1246             }
1247         }
1248 
1249         return false;
1250     }
1251 }
1252 
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.