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  * SimplePie
   4  *
   5  * A PHP-Based RSS and Atom Feed Framework.
   6  * Takes the hard work out of managing a complete RSS/Atom solution.
   7  *
   8  * Copyright (c) 2004-2012, Ryan Parman, Geoffrey Sneddon, Ryan McCue, and contributors
   9  * All rights reserved.
  10  *
  11  * Redistribution and use in source and binary forms, with or without modification, are
  12  * permitted provided that the following conditions are met:
  13  *
  14  *  * Redistributions of source code must retain the above copyright notice, this list of
  15  *    conditions and the following disclaimer.
  16  *
  17  *  * Redistributions in binary form must reproduce the above copyright notice, this list
  18  *    of conditions and the following disclaimer in the documentation and/or other materials
  19  *    provided with the distribution.
  20  *
  21  *  * Neither the name of the SimplePie Team nor the names of its contributors may be used
  22  *    to endorse or promote products derived from this software without specific prior
  23  *    written permission.
  24  *
  25  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
  26  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
  27  * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS
  28  * AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  29  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  30  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  31  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
  32  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  33  * POSSIBILITY OF SUCH DAMAGE.
  34  *
  35  * @package SimplePie
  36  * @version 1.3.1
  37  * @copyright 2004-2012 Ryan Parman, Geoffrey Sneddon, Ryan McCue
  38  * @author Ryan Parman
  39  * @author Geoffrey Sneddon
  40  * @author Ryan McCue
  41  * @link http://simplepie.org/ SimplePie
  42  * @license http://www.opensource.org/licenses/bsd-license.php BSD License
  43  */
  44 
  45 /**
  46  * SimplePie Name
  47  */
  48 define('SIMPLEPIE_NAME', 'SimplePie');
  49 
  50 /**
  51  * SimplePie Version
  52  */
  53 define('SIMPLEPIE_VERSION', '1.3.1');
  54 
  55 /**
  56  * SimplePie Build
  57  * @todo Hardcode for release (there's no need to have to call SimplePie_Misc::get_build() only every load of simplepie.inc)
  58  */
  59 define('SIMPLEPIE_BUILD', gmdate('YmdHis', SimplePie_Misc::get_build()));
  60 
  61 /**
  62  * SimplePie Website URL
  63  */
  64 define('SIMPLEPIE_URL', 'http://simplepie.org');
  65 
  66 /**
  67  * SimplePie Useragent
  68  * @see SimplePie::set_useragent()
  69  */
  70 define('SIMPLEPIE_USERAGENT', SIMPLEPIE_NAME . '/' . SIMPLEPIE_VERSION . ' (Feed Parser; ' . SIMPLEPIE_URL . '; Allow like Gecko) Build/' . SIMPLEPIE_BUILD);
  71 
  72 /**
  73  * SimplePie Linkback
  74  */
  75 define('SIMPLEPIE_LINKBACK', '<a href="' . SIMPLEPIE_URL . '" title="' . SIMPLEPIE_NAME . ' ' . SIMPLEPIE_VERSION . '">' . SIMPLEPIE_NAME . '</a>');
  76 
  77 /**
  78  * No Autodiscovery
  79  * @see SimplePie::set_autodiscovery_level()
  80  */
  81 define('SIMPLEPIE_LOCATOR_NONE', 0);
  82 
  83 /**
  84  * Feed Link Element Autodiscovery
  85  * @see SimplePie::set_autodiscovery_level()
  86  */
  87 define('SIMPLEPIE_LOCATOR_AUTODISCOVERY', 1);
  88 
  89 /**
  90  * Local Feed Extension Autodiscovery
  91  * @see SimplePie::set_autodiscovery_level()
  92  */
  93 define('SIMPLEPIE_LOCATOR_LOCAL_EXTENSION', 2);
  94 
  95 /**
  96  * Local Feed Body Autodiscovery
  97  * @see SimplePie::set_autodiscovery_level()
  98  */
  99 define('SIMPLEPIE_LOCATOR_LOCAL_BODY', 4);
 100 
 101 /**
 102  * Remote Feed Extension Autodiscovery
 103  * @see SimplePie::set_autodiscovery_level()
 104  */
 105 define('SIMPLEPIE_LOCATOR_REMOTE_EXTENSION', 8);
 106 
 107 /**
 108  * Remote Feed Body Autodiscovery
 109  * @see SimplePie::set_autodiscovery_level()
 110  */
 111 define('SIMPLEPIE_LOCATOR_REMOTE_BODY', 16);
 112 
 113 /**
 114  * All Feed Autodiscovery
 115  * @see SimplePie::set_autodiscovery_level()
 116  */
 117 define('SIMPLEPIE_LOCATOR_ALL', 31);
 118 
 119 /**
 120  * No known feed type
 121  */
 122 define('SIMPLEPIE_TYPE_NONE', 0);
 123 
 124 /**
 125  * RSS 0.90
 126  */
 127 define('SIMPLEPIE_TYPE_RSS_090', 1);
 128 
 129 /**
 130  * RSS 0.91 (Netscape)
 131  */
 132 define('SIMPLEPIE_TYPE_RSS_091_NETSCAPE', 2);
 133 
 134 /**
 135  * RSS 0.91 (Userland)
 136  */
 137 define('SIMPLEPIE_TYPE_RSS_091_USERLAND', 4);
 138 
 139 /**
 140  * RSS 0.91 (both Netscape and Userland)
 141  */
 142 define('SIMPLEPIE_TYPE_RSS_091', 6);
 143 
 144 /**
 145  * RSS 0.92
 146  */
 147 define('SIMPLEPIE_TYPE_RSS_092', 8);
 148 
 149 /**
 150  * RSS 0.93
 151  */
 152 define('SIMPLEPIE_TYPE_RSS_093', 16);
 153 
 154 /**
 155  * RSS 0.94
 156  */
 157 define('SIMPLEPIE_TYPE_RSS_094', 32);
 158 
 159 /**
 160  * RSS 1.0
 161  */
 162 define('SIMPLEPIE_TYPE_RSS_10', 64);
 163 
 164 /**
 165  * RSS 2.0
 166  */
 167 define('SIMPLEPIE_TYPE_RSS_20', 128);
 168 
 169 /**
 170  * RDF-based RSS
 171  */
 172 define('SIMPLEPIE_TYPE_RSS_RDF', 65);
 173 
 174 /**
 175  * Non-RDF-based RSS (truly intended as syndication format)
 176  */
 177 define('SIMPLEPIE_TYPE_RSS_SYNDICATION', 190);
 178 
 179 /**
 180  * All RSS
 181  */
 182 define('SIMPLEPIE_TYPE_RSS_ALL', 255);
 183 
 184 /**
 185  * Atom 0.3
 186  */
 187 define('SIMPLEPIE_TYPE_ATOM_03', 256);
 188 
 189 /**
 190  * Atom 1.0
 191  */
 192 define('SIMPLEPIE_TYPE_ATOM_10', 512);
 193 
 194 /**
 195  * All Atom
 196  */
 197 define('SIMPLEPIE_TYPE_ATOM_ALL', 768);
 198 
 199 /**
 200  * All feed types
 201  */
 202 define('SIMPLEPIE_TYPE_ALL', 1023);
 203 
 204 /**
 205  * No construct
 206  */
 207 define('SIMPLEPIE_CONSTRUCT_NONE', 0);
 208 
 209 /**
 210  * Text construct
 211  */
 212 define('SIMPLEPIE_CONSTRUCT_TEXT', 1);
 213 
 214 /**
 215  * HTML construct
 216  */
 217 define('SIMPLEPIE_CONSTRUCT_HTML', 2);
 218 
 219 /**
 220  * XHTML construct
 221  */
 222 define('SIMPLEPIE_CONSTRUCT_XHTML', 4);
 223 
 224 /**
 225  * base64-encoded construct
 226  */
 227 define('SIMPLEPIE_CONSTRUCT_BASE64', 8);
 228 
 229 /**
 230  * IRI construct
 231  */
 232 define('SIMPLEPIE_CONSTRUCT_IRI', 16);
 233 
 234 /**
 235  * A construct that might be HTML
 236  */
 237 define('SIMPLEPIE_CONSTRUCT_MAYBE_HTML', 32);
 238 
 239 /**
 240  * All constructs
 241  */
 242 define('SIMPLEPIE_CONSTRUCT_ALL', 63);
 243 
 244 /**
 245  * Don't change case
 246  */
 247 define('SIMPLEPIE_SAME_CASE', 1);
 248 
 249 /**
 250  * Change to lowercase
 251  */
 252 define('SIMPLEPIE_LOWERCASE', 2);
 253 
 254 /**
 255  * Change to uppercase
 256  */
 257 define('SIMPLEPIE_UPPERCASE', 4);
 258 
 259 /**
 260  * PCRE for HTML attributes
 261  */
 262 define('SIMPLEPIE_PCRE_HTML_ATTRIBUTE', '((?:[\x09\x0A\x0B\x0C\x0D\x20]+[^\x09\x0A\x0B\x0C\x0D\x20\x2F\x3E][^\x09\x0A\x0B\x0C\x0D\x20\x2F\x3D\x3E]*(?:[\x09\x0A\x0B\x0C\x0D\x20]*=[\x09\x0A\x0B\x0C\x0D\x20]*(?:"(?:[^"]*)"|\'(?:[^\']*)\'|(?:[^\x09\x0A\x0B\x0C\x0D\x20\x22\x27\x3E][^\x09\x0A\x0B\x0C\x0D\x20\x3E]*)?))?)*)[\x09\x0A\x0B\x0C\x0D\x20]*');
 263 
 264 /**
 265  * PCRE for XML attributes
 266  */
 267 define('SIMPLEPIE_PCRE_XML_ATTRIBUTE', '((?:\s+(?:(?:[^\s:]+:)?[^\s:]+)\s*=\s*(?:"(?:[^"]*)"|\'(?:[^\']*)\'))*)\s*');
 268 
 269 /**
 270  * XML Namespace
 271  */
 272 define('SIMPLEPIE_NAMESPACE_XML', 'http://www.w3.org/XML/1998/namespace');
 273 
 274 /**
 275  * Atom 1.0 Namespace
 276  */
 277 define('SIMPLEPIE_NAMESPACE_ATOM_10', 'http://www.w3.org/2005/Atom');
 278 
 279 /**
 280  * Atom 0.3 Namespace
 281  */
 282 define('SIMPLEPIE_NAMESPACE_ATOM_03', 'http://purl.org/atom/ns#');
 283 
 284 /**
 285  * RDF Namespace
 286  */
 287 define('SIMPLEPIE_NAMESPACE_RDF', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#');
 288 
 289 /**
 290  * RSS 0.90 Namespace
 291  */
 292 define('SIMPLEPIE_NAMESPACE_RSS_090', 'http://my.netscape.com/rdf/simple/0.9/');
 293 
 294 /**
 295  * RSS 1.0 Namespace
 296  */
 297 define('SIMPLEPIE_NAMESPACE_RSS_10', 'http://purl.org/rss/1.0/');
 298 
 299 /**
 300  * RSS 1.0 Content Module Namespace
 301  */
 302 define('SIMPLEPIE_NAMESPACE_RSS_10_MODULES_CONTENT', 'http://purl.org/rss/1.0/modules/content/');
 303 
 304 /**
 305  * RSS 2.0 Namespace
 306  * (Stupid, I know, but I'm certain it will confuse people less with support.)
 307  */
 308 define('SIMPLEPIE_NAMESPACE_RSS_20', '');
 309 
 310 /**
 311  * DC 1.0 Namespace
 312  */
 313 define('SIMPLEPIE_NAMESPACE_DC_10', 'http://purl.org/dc/elements/1.0/');
 314 
 315 /**
 316  * DC 1.1 Namespace
 317  */
 318 define('SIMPLEPIE_NAMESPACE_DC_11', 'http://purl.org/dc/elements/1.1/');
 319 
 320 /**
 321  * W3C Basic Geo (WGS84 lat/long) Vocabulary Namespace
 322  */
 323 define('SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO', 'http://www.w3.org/2003/01/geo/wgs84_pos#');
 324 
 325 /**
 326  * GeoRSS Namespace
 327  */
 328 define('SIMPLEPIE_NAMESPACE_GEORSS', 'http://www.georss.org/georss');
 329 
 330 /**
 331  * Media RSS Namespace
 332  */
 333 define('SIMPLEPIE_NAMESPACE_MEDIARSS', 'http://search.yahoo.com/mrss/');
 334 
 335 /**
 336  * Wrong Media RSS Namespace. Caused by a long-standing typo in the spec.
 337  */
 338 define('SIMPLEPIE_NAMESPACE_MEDIARSS_WRONG', 'http://search.yahoo.com/mrss');
 339 
 340 /**
 341  * Wrong Media RSS Namespace #2. New namespace introduced in Media RSS 1.5.
 342  */
 343 define('SIMPLEPIE_NAMESPACE_MEDIARSS_WRONG2', 'http://video.search.yahoo.com/mrss');
 344 
 345 /**
 346  * Wrong Media RSS Namespace #3. A possible typo of the Media RSS 1.5 namespace.
 347  */
 348 define('SIMPLEPIE_NAMESPACE_MEDIARSS_WRONG3', 'http://video.search.yahoo.com/mrss/');
 349 
 350 /**
 351  * Wrong Media RSS Namespace #4. New spec location after the RSS Advisory Board takes it over, but not a valid namespace.
 352  */
 353 define('SIMPLEPIE_NAMESPACE_MEDIARSS_WRONG4', 'http://www.rssboard.org/media-rss');
 354 
 355 /**
 356  * Wrong Media RSS Namespace #5. A possible typo of the RSS Advisory Board URL.
 357  */
 358 define('SIMPLEPIE_NAMESPACE_MEDIARSS_WRONG5', 'http://www.rssboard.org/media-rss/');
 359 
 360 /**
 361  * iTunes RSS Namespace
 362  */
 363 define('SIMPLEPIE_NAMESPACE_ITUNES', 'http://www.itunes.com/dtds/podcast-1.0.dtd');
 364 
 365 /**
 366  * XHTML Namespace
 367  */
 368 define('SIMPLEPIE_NAMESPACE_XHTML', 'http://www.w3.org/1999/xhtml');
 369 
 370 /**
 371  * IANA Link Relations Registry
 372  */
 373 define('SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY', 'http://www.iana.org/assignments/relation/');
 374 
 375 /**
 376  * No file source
 377  */
 378 define('SIMPLEPIE_FILE_SOURCE_NONE', 0);
 379 
 380 /**
 381  * Remote file source
 382  */
 383 define('SIMPLEPIE_FILE_SOURCE_REMOTE', 1);
 384 
 385 /**
 386  * Local file source
 387  */
 388 define('SIMPLEPIE_FILE_SOURCE_LOCAL', 2);
 389 
 390 /**
 391  * fsockopen() file source
 392  */
 393 define('SIMPLEPIE_FILE_SOURCE_FSOCKOPEN', 4);
 394 
 395 /**
 396  * cURL file source
 397  */
 398 define('SIMPLEPIE_FILE_SOURCE_CURL', 8);
 399 
 400 /**
 401  * file_get_contents() file source
 402  */
 403 define('SIMPLEPIE_FILE_SOURCE_FILE_GET_CONTENTS', 16);
 404 
 405 
 406 
 407 /**
 408  * SimplePie
 409  *
 410  * @package SimplePie
 411  * @subpackage API
 412  */
 413 class SimplePie
 414 {
 415     /**
 416      * @var array Raw data
 417      * @access private
 418      */
 419     public $data = array();
 420 
 421     /**
 422      * @var mixed Error string
 423      * @access private
 424      */
 425     public $error;
 426 
 427     /**
 428      * @var object Instance of SimplePie_Sanitize (or other class)
 429      * @see SimplePie::set_sanitize_class()
 430      * @access private
 431      */
 432     public $sanitize;
 433 
 434     /**
 435      * @var string SimplePie Useragent
 436      * @see SimplePie::set_useragent()
 437      * @access private
 438      */
 439     public $useragent = SIMPLEPIE_USERAGENT;
 440 
 441     /**
 442      * @var string Feed URL
 443      * @see SimplePie::set_feed_url()
 444      * @access private
 445      */
 446     public $feed_url;
 447 
 448     /**
 449      * @var object Instance of SimplePie_File to use as a feed
 450      * @see SimplePie::set_file()
 451      * @access private
 452      */
 453     public $file;
 454 
 455     /**
 456      * @var string Raw feed data
 457      * @see SimplePie::set_raw_data()
 458      * @access private
 459      */
 460     public $raw_data;
 461 
 462     /**
 463      * @var int Timeout for fetching remote files
 464      * @see SimplePie::set_timeout()
 465      * @access private
 466      */
 467     public $timeout = 10;
 468 
 469     /**
 470      * @var bool Forces fsockopen() to be used for remote files instead
 471      * of cURL, even if a new enough version is installed
 472      * @see SimplePie::force_fsockopen()
 473      * @access private
 474      */
 475     public $force_fsockopen = false;
 476 
 477     /**
 478      * @var bool Force the given data/URL to be treated as a feed no matter what
 479      * it appears like
 480      * @see SimplePie::force_feed()
 481      * @access private
 482      */
 483     public $force_feed = false;
 484 
 485     /**
 486      * @var bool Enable/Disable Caching
 487      * @see SimplePie::enable_cache()
 488      * @access private
 489      */
 490     public $cache = true;
 491 
 492     /**
 493      * @var int Cache duration (in seconds)
 494      * @see SimplePie::set_cache_duration()
 495      * @access private
 496      */
 497     public $cache_duration = 3600;
 498 
 499     /**
 500      * @var int Auto-discovery cache duration (in seconds)
 501      * @see SimplePie::set_autodiscovery_cache_duration()
 502      * @access private
 503      */
 504     public $autodiscovery_cache_duration = 604800; // 7 Days.
 505 
 506     /**
 507      * @var string Cache location (relative to executing script)
 508      * @see SimplePie::set_cache_location()
 509      * @access private
 510      */
 511     public $cache_location = './cache';
 512 
 513     /**
 514      * @var string Function that creates the cache filename
 515      * @see SimplePie::set_cache_name_function()
 516      * @access private
 517      */
 518     public $cache_name_function = 'md5';
 519 
 520     /**
 521      * @var bool Reorder feed by date descending
 522      * @see SimplePie::enable_order_by_date()
 523      * @access private
 524      */
 525     public $order_by_date = true;
 526 
 527     /**
 528      * @var mixed Force input encoding to be set to the follow value
 529      * (false, or anything type-cast to false, disables this feature)
 530      * @see SimplePie::set_input_encoding()
 531      * @access private
 532      */
 533     public $input_encoding = false;
 534 
 535     /**
 536      * @var int Feed Autodiscovery Level
 537      * @see SimplePie::set_autodiscovery_level()
 538      * @access private
 539      */
 540     public $autodiscovery = SIMPLEPIE_LOCATOR_ALL;
 541 
 542     /**
 543      * Class registry object
 544      *
 545      * @var SimplePie_Registry
 546      */
 547     public $registry;
 548 
 549     /**
 550      * @var int Maximum number of feeds to check with autodiscovery
 551      * @see SimplePie::set_max_checked_feeds()
 552      * @access private
 553      */
 554     public $max_checked_feeds = 10;
 555 
 556     /**
 557      * @var array All the feeds found during the autodiscovery process
 558      * @see SimplePie::get_all_discovered_feeds()
 559      * @access private
 560      */
 561     public $all_discovered_feeds = array();
 562 
 563     /**
 564      * @var string Web-accessible path to the handler_image.php file.
 565      * @see SimplePie::set_image_handler()
 566      * @access private
 567      */
 568     public $image_handler = '';
 569 
 570     /**
 571      * @var array Stores the URLs when multiple feeds are being initialized.
 572      * @see SimplePie::set_feed_url()
 573      * @access private
 574      */
 575     public $multifeed_url = array();
 576 
 577     /**
 578      * @var array Stores SimplePie objects when multiple feeds initialized.
 579      * @access private
 580      */
 581     public $multifeed_objects = array();
 582 
 583     /**
 584      * @var array Stores the get_object_vars() array for use with multifeeds.
 585      * @see SimplePie::set_feed_url()
 586      * @access private
 587      */
 588     public $config_settings = null;
 589 
 590     /**
 591      * @var integer Stores the number of items to return per-feed with multifeeds.
 592      * @see SimplePie::set_item_limit()
 593      * @access private
 594      */
 595     public $item_limit = 0;
 596 
 597     /**
 598      * @var array Stores the default attributes to be stripped by strip_attributes().
 599      * @see SimplePie::strip_attributes()
 600      * @access private
 601      */
 602     public $strip_attributes = array('bgsound', 'class', 'expr', 'id', 'style', 'onclick', 'onerror', 'onfinish', 'onmouseover', 'onmouseout', 'onfocus', 'onblur', 'lowsrc', 'dynsrc');
 603 
 604     /**
 605      * @var array Stores the default tags to be stripped by strip_htmltags().
 606      * @see SimplePie::strip_htmltags()
 607      * @access private
 608      */
 609     public $strip_htmltags = array('base', 'blink', 'body', 'doctype', 'embed', 'font', 'form', 'frame', 'frameset', 'html', 'iframe', 'input', 'marquee', 'meta', 'noscript', 'object', 'param', 'script', 'style');
 610 
 611     /**
 612      * The SimplePie class contains feed level data and options
 613      *
 614      * To use SimplePie, create the SimplePie object with no parameters. You can
 615      * then set configuration options using the provided methods. After setting
 616      * them, you must initialise the feed using $feed->init(). At that point the
 617      * object's methods and properties will be available to you.
 618      *
 619      * Previously, it was possible to pass in the feed URL along with cache
 620      * options directly into the constructor. This has been removed as of 1.3 as
 621      * it caused a lot of confusion.
 622      *
 623      * @since 1.0 Preview Release
 624      */
 625     public function __construct()
 626     {
 627         if (version_compare(PHP_VERSION, '5.2', '<'))
 628         {
 629             trigger_error('PHP 4.x, 5.0 and 5.1 are no longer supported. Please upgrade to PHP 5.2 or newer.');
 630             die();
 631         }
 632 
 633         // Other objects, instances created here so we can set options on them
 634         $this->sanitize = new SimplePie_Sanitize();
 635         $this->registry = new SimplePie_Registry();
 636 
 637         if (func_num_args() > 0)
 638         {
 639             $level = defined('E_USER_DEPRECATED') ? E_USER_DEPRECATED : E_USER_WARNING;
 640             trigger_error('Passing parameters to the constructor is no longer supported. Please use set_feed_url(), set_cache_location(), and set_cache_location() directly.', $level);
 641 
 642             $args = func_get_args();
 643             switch (count($args)) {
 644                 case 3:
 645                     $this->set_cache_duration($args[2]);
 646                 case 2:
 647                     $this->set_cache_location($args[1]);
 648                 case 1:
 649                     $this->set_feed_url($args[0]);
 650                     $this->init();
 651             }
 652         }
 653     }
 654 
 655     /**
 656      * Used for converting object to a string
 657      */
 658     public function __toString()
 659     {
 660         return md5(serialize($this->data));
 661     }
 662 
 663     /**
 664      * Remove items that link back to this before destroying this object
 665      */
 666     public function __destruct()
 667     {
 668         if ((version_compare(PHP_VERSION, '5.3', '<') || !gc_enabled()) && !ini_get('zend.ze1_compatibility_mode'))
 669         {
 670             if (!empty($this->data['items']))
 671             {
 672                 foreach ($this->data['items'] as $item)
 673                 {
 674                     $item->__destruct();
 675                 }
 676                 unset($item, $this->data['items']);
 677             }
 678             if (!empty($this->data['ordered_items']))
 679             {
 680                 foreach ($this->data['ordered_items'] as $item)
 681                 {
 682                     $item->__destruct();
 683                 }
 684                 unset($item, $this->data['ordered_items']);
 685             }
 686         }
 687     }
 688 
 689     /**
 690      * Force the given data/URL to be treated as a feed
 691      *
 692      * This tells SimplePie to ignore the content-type provided by the server.
 693      * Be careful when using this option, as it will also disable autodiscovery.
 694      *
 695      * @since 1.1
 696      * @param bool $enable Force the given data/URL to be treated as a feed
 697      */
 698     public function force_feed($enable = false)
 699     {
 700         $this->force_feed = (bool) $enable;
 701     }
 702 
 703     /**
 704      * Set the URL of the feed you want to parse
 705      *
 706      * This allows you to enter the URL of the feed you want to parse, or the
 707      * website you want to try to use auto-discovery on. This takes priority
 708      * over any set raw data.
 709      *
 710      * You can set multiple feeds to mash together by passing an array instead
 711      * of a string for the $url. Remember that with each additional feed comes
 712      * additional processing and resources.
 713      *
 714      * @since 1.0 Preview Release
 715      * @see set_raw_data()
 716      * @param string|array $url This is the URL (or array of URLs) that you want to parse.
 717      */
 718     public function set_feed_url($url)
 719     {
 720         $this->multifeed_url = array();
 721         if (is_array($url))
 722         {
 723             foreach ($url as $value)
 724             {
 725                 $this->multifeed_url[] = $this->registry->call('Misc', 'fix_protocol', array($value, 1));
 726             }
 727         }
 728         else
 729         {
 730             $this->feed_url = $this->registry->call('Misc', 'fix_protocol', array($url, 1));
 731         }
 732     }
 733 
 734     /**
 735      * Set an instance of {@see SimplePie_File} to use as a feed
 736      *
 737      * @param SimplePie_File &$file
 738      * @return bool True on success, false on failure
 739      */
 740     public function set_file(&$file)
 741     {
 742         if ($file instanceof SimplePie_File)
 743         {
 744             $this->feed_url = $file->url;
 745             $this->file =& $file;
 746             return true;
 747         }
 748         return false;
 749     }
 750 
 751     /**
 752      * Set the raw XML data to parse
 753      *
 754      * Allows you to use a string of RSS/Atom data instead of a remote feed.
 755      *
 756      * If you have a feed available as a string in PHP, you can tell SimplePie
 757      * to parse that data string instead of a remote feed. Any set feed URL
 758      * takes precedence.
 759      *
 760      * @since 1.0 Beta 3
 761      * @param string $data RSS or Atom data as a string.
 762      * @see set_feed_url()
 763      */
 764     public function set_raw_data($data)
 765     {
 766         $this->raw_data = $data;
 767     }
 768 
 769     /**
 770      * Set the the default timeout for fetching remote feeds
 771      *
 772      * This allows you to change the maximum time the feed's server to respond
 773      * and send the feed back.
 774      *
 775      * @since 1.0 Beta 3
 776      * @param int $timeout The maximum number of seconds to spend waiting to retrieve a feed.
 777      */
 778     public function set_timeout($timeout = 10)
 779     {
 780         $this->timeout = (int) $timeout;
 781     }
 782 
 783     /**
 784      * Force SimplePie to use fsockopen() instead of cURL
 785      *
 786      * @since 1.0 Beta 3
 787      * @param bool $enable Force fsockopen() to be used
 788      */
 789     public function force_fsockopen($enable = false)
 790     {
 791         $this->force_fsockopen = (bool) $enable;
 792     }
 793 
 794     /**
 795      * Enable/disable caching in SimplePie.
 796      *
 797      * This option allows you to disable caching all-together in SimplePie.
 798      * However, disabling the cache can lead to longer load times.
 799      *
 800      * @since 1.0 Preview Release
 801      * @param bool $enable Enable caching
 802      */
 803     public function enable_cache($enable = true)
 804     {
 805         $this->cache = (bool) $enable;
 806     }
 807 
 808     /**
 809      * Set the length of time (in seconds) that the contents of a feed will be
 810      * cached
 811      *
 812      * @param int $seconds The feed content cache duration
 813      */
 814     public function set_cache_duration($seconds = 3600)
 815     {
 816         $this->cache_duration = (int) $seconds;
 817     }
 818 
 819     /**
 820      * Set the length of time (in seconds) that the autodiscovered feed URL will
 821      * be cached
 822      *
 823      * @param int $seconds The autodiscovered feed URL cache duration.
 824      */
 825     public function set_autodiscovery_cache_duration($seconds = 604800)
 826     {
 827         $this->autodiscovery_cache_duration = (int) $seconds;
 828     }
 829 
 830     /**
 831      * Set the file system location where the cached files should be stored
 832      *
 833      * @param string $location The file system location.
 834      */
 835     public function set_cache_location($location = './cache')
 836     {
 837         $this->cache_location = (string) $location;
 838     }
 839 
 840     /**
 841      * Set whether feed items should be sorted into reverse chronological order
 842      *
 843      * @param bool $enable Sort as reverse chronological order.
 844      */
 845     public function enable_order_by_date($enable = true)
 846     {
 847         $this->order_by_date = (bool) $enable;
 848     }
 849 
 850     /**
 851      * Set the character encoding used to parse the feed
 852      *
 853      * This overrides the encoding reported by the feed, however it will fall
 854      * back to the normal encoding detection if the override fails
 855      *
 856      * @param string $encoding Character encoding
 857      */
 858     public function set_input_encoding($encoding = false)
 859     {
 860         if ($encoding)
 861         {
 862             $this->input_encoding = (string) $encoding;
 863         }
 864         else
 865         {
 866             $this->input_encoding = false;
 867         }
 868     }
 869 
 870     /**
 871      * Set how much feed autodiscovery to do
 872      *
 873      * @see SIMPLEPIE_LOCATOR_NONE
 874      * @see SIMPLEPIE_LOCATOR_AUTODISCOVERY
 875      * @see SIMPLEPIE_LOCATOR_LOCAL_EXTENSION
 876      * @see SIMPLEPIE_LOCATOR_LOCAL_BODY
 877      * @see SIMPLEPIE_LOCATOR_REMOTE_EXTENSION
 878      * @see SIMPLEPIE_LOCATOR_REMOTE_BODY
 879      * @see SIMPLEPIE_LOCATOR_ALL
 880      * @param int $level Feed Autodiscovery Level (level can be a combination of the above constants, see bitwise OR operator)
 881      */
 882     public function set_autodiscovery_level($level = SIMPLEPIE_LOCATOR_ALL)
 883     {
 884         $this->autodiscovery = (int) $level;
 885     }
 886 
 887     /**
 888      * Get the class registry
 889      *
 890      * Use this to override SimplePie's default classes
 891      * @see SimplePie_Registry
 892      * @return SimplePie_Registry
 893      */
 894     public function &get_registry()
 895     {
 896         return $this->registry;
 897     }
 898 
 899     /**#@+
 900      * Useful when you are overloading or extending SimplePie's default classes.
 901      *
 902      * @deprecated Use {@see get_registry()} instead
 903      * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
 904      * @param string $class Name of custom class
 905      * @return boolean True on success, false otherwise
 906      */
 907     /**
 908      * Set which class SimplePie uses for caching
 909      */
 910     public function set_cache_class($class = 'SimplePie_Cache')
 911     {
 912         return $this->registry->register('Cache', $class, true);
 913     }
 914 
 915     /**
 916      * Set which class SimplePie uses for auto-discovery
 917      */
 918     public function set_locator_class($class = 'SimplePie_Locator')
 919     {
 920         return $this->registry->register('Locator', $class, true);
 921     }
 922 
 923     /**
 924      * Set which class SimplePie uses for XML parsing
 925      */
 926     public function set_parser_class($class = 'SimplePie_Parser')
 927     {
 928         return $this->registry->register('Parser', $class, true);
 929     }
 930 
 931     /**
 932      * Set which class SimplePie uses for remote file fetching
 933      */
 934     public function set_file_class($class = 'SimplePie_File')
 935     {
 936         return $this->registry->register('File', $class, true);
 937     }
 938 
 939     /**
 940      * Set which class SimplePie uses for data sanitization
 941      */
 942     public function set_sanitize_class($class = 'SimplePie_Sanitize')
 943     {
 944         return $this->registry->register('Sanitize', $class, true);
 945     }
 946 
 947     /**
 948      * Set which class SimplePie uses for handling feed items
 949      */
 950     public function set_item_class($class = 'SimplePie_Item')
 951     {
 952         return $this->registry->register('Item', $class, true);
 953     }
 954 
 955     /**
 956      * Set which class SimplePie uses for handling author data
 957      */
 958     public function set_author_class($class = 'SimplePie_Author')
 959     {
 960         return $this->registry->register('Author', $class, true);
 961     }
 962 
 963     /**
 964      * Set which class SimplePie uses for handling category data
 965      */
 966     public function set_category_class($class = 'SimplePie_Category')
 967     {
 968         return $this->registry->register('Category', $class, true);
 969     }
 970 
 971     /**
 972      * Set which class SimplePie uses for feed enclosures
 973      */
 974     public function set_enclosure_class($class = 'SimplePie_Enclosure')
 975     {
 976         return $this->registry->register('Enclosure', $class, true);
 977     }
 978 
 979     /**
 980      * Set which class SimplePie uses for `<media:text>` captions
 981      */
 982     public function set_caption_class($class = 'SimplePie_Caption')
 983     {
 984         return $this->registry->register('Caption', $class, true);
 985     }
 986 
 987     /**
 988      * Set which class SimplePie uses for `<media:copyright>`
 989      */
 990     public function set_copyright_class($class = 'SimplePie_Copyright')
 991     {
 992         return $this->registry->register('Copyright', $class, true);
 993     }
 994 
 995     /**
 996      * Set which class SimplePie uses for `<media:credit>`
 997      */
 998     public function set_credit_class($class = 'SimplePie_Credit')
 999     {
1000         return $this->registry->register('Credit', $class, true);
1001     }
1002 
1003     /**
1004      * Set which class SimplePie uses for `<media:rating>`
1005      */
1006     public function set_rating_class($class = 'SimplePie_Rating')
1007     {
1008         return $this->registry->register('Rating', $class, true);
1009     }
1010 
1011     /**
1012      * Set which class SimplePie uses for `<media:restriction>`
1013      */
1014     public function set_restriction_class($class = 'SimplePie_Restriction')
1015     {
1016         return $this->registry->register('Restriction', $class, true);
1017     }
1018 
1019     /**
1020      * Set which class SimplePie uses for content-type sniffing
1021      */
1022     public function set_content_type_sniffer_class($class = 'SimplePie_Content_Type_Sniffer')
1023     {
1024         return $this->registry->register('Content_Type_Sniffer', $class, true);
1025     }
1026 
1027     /**
1028      * Set which class SimplePie uses item sources
1029      */
1030     public function set_source_class($class = 'SimplePie_Source')
1031     {
1032         return $this->registry->register('Source', $class, true);
1033     }
1034     /**#@-*/
1035 
1036     /**
1037      * Set the user agent string
1038      *
1039      * @param string $ua New user agent string.
1040      */
1041     public function set_useragent($ua = SIMPLEPIE_USERAGENT)
1042     {
1043         $this->useragent = (string) $ua;
1044     }
1045 
1046     /**
1047      * Set callback function to create cache filename with
1048      *
1049      * @param mixed $function Callback function
1050      */
1051     public function set_cache_name_function($function = 'md5')
1052     {
1053         if (is_callable($function))
1054         {
1055             $this->cache_name_function = $function;
1056         }
1057     }
1058 
1059     /**
1060      * Set options to make SP as fast as possible
1061      *
1062      * Forgoes a substantial amount of data sanitization in favor of speed. This
1063      * turns SimplePie into a dumb parser of feeds.
1064      *
1065      * @param bool $set Whether to set them or not
1066      */
1067     public function set_stupidly_fast($set = false)
1068     {
1069         if ($set)
1070         {
1071             $this->enable_order_by_date(false);
1072             $this->remove_div(false);
1073             $this->strip_comments(false);
1074             $this->strip_htmltags(false);
1075             $this->strip_attributes(false);
1076             $this->set_image_handler(false);
1077         }
1078     }
1079 
1080     /**
1081      * Set maximum number of feeds to check with autodiscovery
1082      *
1083      * @param int $max Maximum number of feeds to check
1084      */
1085     public function set_max_checked_feeds($max = 10)
1086     {
1087         $this->max_checked_feeds = (int) $max;
1088     }
1089 
1090     public function remove_div($enable = true)
1091     {
1092         $this->sanitize->remove_div($enable);
1093     }
1094 
1095     public function strip_htmltags($tags = '', $encode = null)
1096     {
1097         if ($tags === '')
1098         {
1099             $tags = $this->strip_htmltags;
1100         }
1101         $this->sanitize->strip_htmltags($tags);
1102         if ($encode !== null)
1103         {
1104             $this->sanitize->encode_instead_of_strip($tags);
1105         }
1106     }
1107 
1108     public function encode_instead_of_strip($enable = true)
1109     {
1110         $this->sanitize->encode_instead_of_strip($enable);
1111     }
1112 
1113     public function strip_attributes($attribs = '')
1114     {
1115         if ($attribs === '')
1116         {
1117             $attribs = $this->strip_attributes;
1118         }
1119         $this->sanitize->strip_attributes($attribs);
1120     }
1121 
1122     /**
1123      * Set the output encoding
1124      *
1125      * Allows you to override SimplePie's output to match that of your webpage.
1126      * This is useful for times when your webpages are not being served as
1127      * UTF-8.  This setting will be obeyed by {@see handle_content_type()}, and
1128      * is similar to {@see set_input_encoding()}.
1129      *
1130      * It should be noted, however, that not all character encodings can support
1131      * all characters.  If your page is being served as ISO-8859-1 and you try
1132      * to display a Japanese feed, you'll likely see garbled characters.
1133      * Because of this, it is highly recommended to ensure that your webpages
1134      * are served as UTF-8.
1135      *
1136      * The number of supported character encodings depends on whether your web
1137      * host supports {@link http://php.net/mbstring mbstring},
1138      * {@link http://php.net/iconv iconv}, or both. See
1139      * {@link http://simplepie.org/wiki/faq/Supported_Character_Encodings} for
1140      * more information.
1141      *
1142      * @param string $encoding
1143      */
1144     public function set_output_encoding($encoding = 'UTF-8')
1145     {
1146         $this->sanitize->set_output_encoding($encoding);
1147     }
1148 
1149     public function strip_comments($strip = false)
1150     {
1151         $this->sanitize->strip_comments($strip);
1152     }
1153 
1154     /**
1155      * Set element/attribute key/value pairs of HTML attributes
1156      * containing URLs that need to be resolved relative to the feed
1157      *
1158      * Defaults to |a|@href, |area|@href, |blockquote|@cite, |del|@cite,
1159      * |form|@action, |img|@longdesc, |img|@src, |input|@src, |ins|@cite,
1160      * |q|@cite
1161      *
1162      * @since 1.0
1163      * @param array|null $element_attribute Element/attribute key/value pairs, null for default
1164      */
1165     public function set_url_replacements($element_attribute = null)
1166     {
1167         $this->sanitize->set_url_replacements($element_attribute);
1168     }
1169 
1170     /**
1171      * Set the handler to enable the display of cached images.
1172      *
1173      * @param str $page Web-accessible path to the handler_image.php file.
1174      * @param str $qs The query string that the value should be passed to.
1175      */
1176     public function set_image_handler($page = false, $qs = 'i')
1177     {
1178         if ($page !== false)
1179         {
1180             $this->sanitize->set_image_handler($page . '?' . $qs . '=');
1181         }
1182         else
1183         {
1184             $this->image_handler = '';
1185         }
1186     }
1187 
1188     /**
1189      * Set the limit for items returned per-feed with multifeeds
1190      *
1191      * @param integer $limit The maximum number of items to return.
1192      */
1193     public function set_item_limit($limit = 0)
1194     {
1195         $this->item_limit = (int) $limit;
1196     }
1197 
1198     /**
1199      * Initialize the feed object
1200      *
1201      * This is what makes everything happen.  Period.  This is where all of the
1202      * configuration options get processed, feeds are fetched, cached, and
1203      * parsed, and all of that other good stuff.
1204      *
1205      * @return boolean True if successful, false otherwise
1206      */
1207     public function init()
1208     {
1209         // Check absolute bare minimum requirements.
1210         if (!extension_loaded('xml') || !extension_loaded('pcre'))
1211         {
1212             return false;
1213         }
1214         // Then check the xml extension is sane (i.e., libxml 2.7.x issue on PHP < 5.2.9 and libxml 2.7.0 to 2.7.2 on any version) if we don't have xmlreader.
1215         elseif (!extension_loaded('xmlreader'))
1216         {
1217             static $xml_is_sane = null;
1218             if ($xml_is_sane === null)
1219             {
1220                 $parser_check = xml_parser_create();
1221                 xml_parse_into_struct($parser_check, '<foo>&amp;</foo>', $values);
1222                 xml_parser_free($parser_check);
1223                 $xml_is_sane = isset($values[0]['value']);
1224             }
1225             if (!$xml_is_sane)
1226             {
1227                 return false;
1228             }
1229         }
1230 
1231         if (method_exists($this->sanitize, 'set_registry'))
1232         {
1233             $this->sanitize->set_registry($this->registry);
1234         }
1235 
1236         // Pass whatever was set with config options over to the sanitizer.
1237         // Pass the classes in for legacy support; new classes should use the registry instead
1238         $this->sanitize->pass_cache_data($this->cache, $this->cache_location, $this->cache_name_function, $this->registry->get_class('Cache'));
1239         $this->sanitize->pass_file_data($this->registry->get_class('File'), $this->timeout, $this->useragent, $this->force_fsockopen);
1240 
1241         if (!empty($this->multifeed_url))
1242         {
1243             $i = 0;
1244             $success = 0;
1245             $this->multifeed_objects = array();
1246             $this->error = array();
1247             foreach ($this->multifeed_url as $url)
1248             {
1249                 $this->multifeed_objects[$i] = clone $this;
1250                 $this->multifeed_objects[$i]->set_feed_url($url);
1251                 $single_success = $this->multifeed_objects[$i]->init();
1252                 $success |= $single_success;
1253                 if (!$single_success)
1254                 {
1255                     $this->error[$i] = $this->multifeed_objects[$i]->error();
1256                 }
1257                 $i++;
1258             }
1259             return (bool) $success;
1260         }
1261         elseif ($this->feed_url === null && $this->raw_data === null)
1262         {
1263             return false;
1264         }
1265 
1266         $this->error = null;
1267         $this->data = array();
1268         $this->multifeed_objects = array();
1269         $cache = false;
1270 
1271         if ($this->feed_url !== null)
1272         {
1273             $parsed_feed_url = $this->registry->call('Misc', 'parse_url', array($this->feed_url));
1274 
1275             // Decide whether to enable caching
1276             if ($this->cache && $parsed_feed_url['scheme'] !== '')
1277             {
1278                 $cache = $this->registry->call('Cache', 'get_handler', array($this->cache_location, call_user_func($this->cache_name_function, $this->feed_url), 'spc'));
1279             }
1280 
1281             // Fetch the data via SimplePie_File into $this->raw_data
1282             if (($fetched = $this->fetch_data($cache)) === true)
1283             {
1284                 return true;
1285             }
1286             elseif ($fetched === false) {
1287                 return false;
1288             }
1289 
1290             list($headers, $sniffed) = $fetched;
1291         }
1292 
1293         // Set up array of possible encodings
1294         $encodings = array();
1295 
1296         // First check to see if input has been overridden.
1297         if ($this->input_encoding !== false)
1298         {
1299             $encodings[] = $this->input_encoding;
1300         }
1301 
1302         $application_types = array('application/xml', 'application/xml-dtd', 'application/xml-external-parsed-entity');
1303         $text_types = array('text/xml', 'text/xml-external-parsed-entity');
1304 
1305         // RFC 3023 (only applies to sniffed content)
1306         if (isset($sniffed))
1307         {
1308             if (in_array($sniffed, $application_types) || substr($sniffed, 0, 12) === 'application/' && substr($sniffed, -4) === '+xml')
1309             {
1310                 if (isset($headers['content-type']) && preg_match('/;\x20?charset=([^;]*)/i', $headers['content-type'], $charset))
1311                 {
1312                     $encodings[] = strtoupper($charset[1]);
1313                 }
1314                 $encodings = array_merge($encodings, $this->registry->call('Misc', 'xml_encoding', array($this->raw_data, &$this->registry)));
1315                 $encodings[] = 'UTF-8';
1316             }
1317             elseif (in_array($sniffed, $text_types) || substr($sniffed, 0, 5) === 'text/' && substr($sniffed, -4) === '+xml')
1318             {
1319                 if (isset($headers['content-type']) && preg_match('/;\x20?charset=([^;]*)/i', $headers['content-type'], $charset))
1320                 {
1321                     $encodings[] = $charset[1];
1322                 }
1323                 $encodings[] = 'US-ASCII';
1324             }
1325             // Text MIME-type default
1326             elseif (substr($sniffed, 0, 5) === 'text/')
1327             {
1328                 $encodings[] = 'US-ASCII';
1329             }
1330         }
1331 
1332         // Fallback to XML 1.0 Appendix F.1/UTF-8/ISO-8859-1
1333         $encodings = array_merge($encodings, $this->registry->call('Misc', 'xml_encoding', array($this->raw_data, &$this->registry)));
1334         $encodings[] = 'UTF-8';
1335         $encodings[] = 'ISO-8859-1';
1336 
1337         // There's no point in trying an encoding twice
1338         $encodings = array_unique($encodings);
1339 
1340         // Loop through each possible encoding, till we return something, or run out of possibilities
1341         foreach ($encodings as $encoding)
1342         {
1343             // Change the encoding to UTF-8 (as we always use UTF-8 internally)
1344             if ($utf8_data = $this->registry->call('Misc', 'change_encoding', array($this->raw_data, $encoding, 'UTF-8')))
1345             {
1346                 // Create new parser
1347                 $parser = $this->registry->create('Parser');
1348 
1349                 // If it's parsed fine
1350                 if ($parser->parse($utf8_data, 'UTF-8'))
1351                 {
1352                     $this->data = $parser->get_data();
1353                     if (!($this->get_type() & ~SIMPLEPIE_TYPE_NONE))
1354                     {
1355                         $this->error = "A feed could not be found at $this->feed_url. This does not appear to be a valid RSS or Atom feed.";
1356                         $this->registry->call('Misc', 'error', array($this->error, E_USER_NOTICE, __FILE__, __LINE__));
1357                         return false;
1358                     }
1359 
1360                     if (isset($headers))
1361                     {
1362                         $this->data['headers'] = $headers;
1363                     }
1364                     $this->data['build'] = SIMPLEPIE_BUILD;
1365 
1366                     // Cache the file if caching is enabled
1367                     if ($cache && !$cache->save($this))
1368                     {
1369                         trigger_error("$this->cache_location is not writeable. Make sure you've set the correct relative or absolute path, and that the location is server-writable.", E_USER_WARNING);
1370                     }
1371                     return true;
1372                 }
1373             }
1374         }
1375 
1376         if (isset($parser))
1377         {
1378             // We have an error, just set SimplePie_Misc::error to it and quit
1379             $this->error = sprintf('This XML document is invalid, likely due to invalid characters. XML error: %s at line %d, column %d', $parser->get_error_string(), $parser->get_current_line(), $parser->get_current_column());
1380         }
1381         else
1382         {
1383             $this->error = 'The data could not be converted to UTF-8. You MUST have either the iconv or mbstring extension installed. Upgrading to PHP 5.x (which includes iconv) is highly recommended.';
1384         }
1385 
1386         $this->registry->call('Misc', 'error', array($this->error, E_USER_NOTICE, __FILE__, __LINE__));
1387 
1388         return false;
1389     }
1390 
1391     /**
1392      * Fetch the data via SimplePie_File
1393      *
1394      * If the data is already cached, attempt to fetch it from there instead
1395      * @param SimplePie_Cache|false $cache Cache handler, or false to not load from the cache
1396      * @return array|true Returns true if the data was loaded from the cache, or an array of HTTP headers and sniffed type
1397      */
1398     protected function fetch_data(&$cache)
1399     {
1400         // If it's enabled, use the cache
1401         if ($cache)
1402         {
1403             // Load the Cache
1404             $this->data = $cache->load();
1405             if (!empty($this->data))
1406             {
1407                 // If the cache is for an outdated build of SimplePie
1408                 if (!isset($this->data['build']) || $this->data['build'] !== SIMPLEPIE_BUILD)
1409                 {
1410                     $cache->unlink();
1411                     $this->data = array();
1412                 }
1413                 // If we've hit a collision just rerun it with caching disabled
1414                 elseif (isset($this->data['url']) && $this->data['url'] !== $this->feed_url)
1415                 {
1416                     $cache = false;
1417                     $this->data = array();
1418                 }
1419                 // If we've got a non feed_url stored (if the page isn't actually a feed, or is a redirect) use that URL.
1420                 elseif (isset($this->data['feed_url']))
1421                 {
1422                     // If the autodiscovery cache is still valid use it.
1423                     if ($cache->mtime() + $this->autodiscovery_cache_duration > time())
1424                     {
1425                         // Do not need to do feed autodiscovery yet.
1426                         if ($this->data['feed_url'] !== $this->data['url'])
1427                         {
1428                             $this->set_feed_url($this->data['feed_url']);
1429                             return $this->init();
1430                         }
1431 
1432                         $cache->unlink();
1433                         $this->data = array();
1434                     }
1435                 }
1436                 // Check if the cache has been updated
1437                 elseif ($cache->mtime() + $this->cache_duration < time())
1438                 {
1439                     // If we have last-modified and/or etag set
1440                     if (isset($this->data['headers']['last-modified']) || isset($this->data['headers']['etag']))
1441                     {
1442                         $headers = array(
1443                             'Accept' => 'application/atom+xml, application/rss+xml, application/rdf+xml;q=0.9, application/xml;q=0.8, text/xml;q=0.8, text/html;q=0.7, unknown/unknown;q=0.1, application/unknown;q=0.1, */*;q=0.1',
1444                         );
1445                         if (isset($this->data['headers']['last-modified']))
1446                         {
1447                             $headers['if-modified-since'] = $this->data['headers']['last-modified'];
1448                         }
1449                         if (isset($this->data['headers']['etag']))
1450                         {
1451                             $headers['if-none-match'] = $this->data['headers']['etag'];
1452                         }
1453 
1454                         $file = $this->registry->create('File', array($this->feed_url, $this->timeout/10, 5, $headers, $this->useragent, $this->force_fsockopen));
1455 
1456                         if ($file->success)
1457                         {
1458                             if ($file->status_code === 304)
1459                             {
1460                                 $cache->touch();
1461                                 return true;
1462                             }
1463                         }
1464                         else
1465                         {
1466                             unset($file);
1467                         }
1468                     }
1469                 }
1470                 // If the cache is still valid, just return true
1471                 else
1472                 {
1473                     $this->raw_data = false;
1474                     return true;
1475                 }
1476             }
1477             // If the cache is empty, delete it
1478             else
1479             {
1480                 $cache->unlink();
1481                 $this->data = array();
1482             }
1483         }
1484         // If we don't already have the file (it'll only exist if we've opened it to check if the cache has been modified), open it.
1485         if (!isset($file))
1486         {
1487             if ($this->file instanceof SimplePie_File && $this->file->url === $this->feed_url)
1488             {
1489                 $file =& $this->file;
1490             }
1491             else
1492             {
1493                 $headers = array(
1494                     'Accept' => 'application/atom+xml, application/rss+xml, application/rdf+xml;q=0.9, application/xml;q=0.8, text/xml;q=0.8, text/html;q=0.7, unknown/unknown;q=0.1, application/unknown;q=0.1, */*;q=0.1',
1495                 );
1496                 $file = $this->registry->create('File', array($this->feed_url, $this->timeout, 5, $headers, $this->useragent, $this->force_fsockopen));
1497             }
1498         }
1499         // If the file connection has an error, set SimplePie::error to that and quit
1500         if (!$file->success && !($file->method & SIMPLEPIE_FILE_SOURCE_REMOTE === 0 || ($file->status_code === 200 || $file->status_code > 206 && $file->status_code < 300)))
1501         {
1502             $this->error = $file->error;
1503             return !empty($this->data);
1504         }
1505 
1506         if (!$this->force_feed)
1507         {
1508             // Check if the supplied URL is a feed, if it isn't, look for it.
1509             $locate = $this->registry->create('Locator', array(&$file, $this->timeout, $this->useragent, $this->max_checked_feeds));
1510 
1511             if (!$locate->is_feed($file))
1512             {
1513                 // We need to unset this so that if SimplePie::set_file() has been called that object is untouched
1514                 unset($file);
1515                 try
1516                 {
1517                     if (!($file = $locate->find($this->autodiscovery, $this->all_discovered_feeds)))
1518                     {
1519                         $this->error = "A feed could not be found at $this->feed_url. A feed with an invalid mime type may fall victim to this error, or " . SIMPLEPIE_NAME . " was unable to auto-discover it.. Use force_feed() if you are certain this URL is a real feed.";
1520                         $this->registry->call('Misc', 'error', array($this->error, E_USER_NOTICE, __FILE__, __LINE__));
1521                         return false;
1522                     }
1523                 }
1524                 catch (SimplePie_Exception $e)
1525                 {
1526                     // This is usually because DOMDocument doesn't exist
1527                     $this->error = $e->getMessage();
1528                     $this->registry->call('Misc', 'error', array($this->error, E_USER_NOTICE, $e->getFile(), $e->getLine()));
1529                     return false;
1530                 }
1531                 if ($cache)
1532                 {
1533                     $this->data = array('url' => $this->feed_url, 'feed_url' => $file->url, 'build' => SIMPLEPIE_BUILD);
1534                     if (!$cache->save($this))
1535                     {
1536                         trigger_error("$this->cache_location is not writeable. Make sure you've set the correct relative or absolute path, and that the location is server-writable.", E_USER_WARNING);
1537                     }
1538                     $cache = $this->registry->call('Cache', 'get_handler', array($this->cache_location, call_user_func($this->cache_name_function, $file->url), 'spc'));
1539                 }
1540                 $this->feed_url = $file->url;
1541             }
1542             $locate = null;
1543         }
1544 
1545         $this->raw_data = $file->body;
1546 
1547         $headers = $file->headers;
1548         $sniffer = $this->registry->create('Content_Type_Sniffer', array(&$file));
1549         $sniffed = $sniffer->get_type();
1550 
1551         return array($headers, $sniffed);
1552     }
1553 
1554     /**
1555      * Get the error message for the occured error
1556      *
1557      * @return string|array Error message, or array of messages for multifeeds
1558      */
1559     public function error()
1560     {
1561         return $this->error;
1562     }
1563 
1564     /**
1565      * Get the raw XML
1566      *
1567      * This is the same as the old `$feed->enable_xml_dump(true)`, but returns
1568      * the data instead of printing it.
1569      *
1570      * @return string|boolean Raw XML data, false if the cache is used
1571      */
1572     public function get_raw_data()
1573     {
1574         return $this->raw_data;
1575     }
1576 
1577     /**
1578      * Get the character encoding used for output
1579      *
1580      * @since Preview Release
1581      * @return string
1582      */
1583     public function get_encoding()
1584     {
1585         return $this->sanitize->output_encoding;
1586     }
1587 
1588     /**
1589      * Send the content-type header with correct encoding
1590      *
1591      * This method ensures that the SimplePie-enabled page is being served with
1592      * the correct {@link http://www.iana.org/assignments/media-types/ mime-type}
1593      * and character encoding HTTP headers (character encoding determined by the
1594      * {@see set_output_encoding} config option).
1595      *
1596      * This won't work properly if any content or whitespace has already been
1597      * sent to the browser, because it relies on PHP's
1598      * {@link http://php.net/header header()} function, and these are the
1599      * circumstances under which the function works.
1600      *
1601      * Because it's setting these settings for the entire page (as is the nature
1602      * of HTTP headers), this should only be used once per page (again, at the
1603      * top).
1604      *
1605      * @param string $mime MIME type to serve the page as
1606      */
1607     public function handle_content_type($mime = 'text/html')
1608     {
1609         if (!headers_sent())
1610         {
1611             $header = "Content-type: $mime;";
1612             if ($this->get_encoding())
1613             {
1614                 $header .= ' charset=' . $this->get_encoding();
1615             }
1616             else
1617             {
1618                 $header .= ' charset=UTF-8';
1619             }
1620             header($header);
1621         }
1622     }
1623 
1624     /**
1625      * Get the type of the feed
1626      *
1627      * This returns a SIMPLEPIE_TYPE_* constant, which can be tested against
1628      * using {@link http://php.net/language.operators.bitwise bitwise operators}
1629      *
1630      * @since 0.8 (usage changed to using constants in 1.0)
1631      * @see SIMPLEPIE_TYPE_NONE Unknown.
1632      * @see SIMPLEPIE_TYPE_RSS_090 RSS 0.90.
1633      * @see SIMPLEPIE_TYPE_RSS_091_NETSCAPE RSS 0.91 (Netscape).
1634      * @see SIMPLEPIE_TYPE_RSS_091_USERLAND RSS 0.91 (Userland).
1635      * @see SIMPLEPIE_TYPE_RSS_091 RSS 0.91.
1636      * @see SIMPLEPIE_TYPE_RSS_092 RSS 0.92.
1637      * @see SIMPLEPIE_TYPE_RSS_093 RSS 0.93.
1638      * @see SIMPLEPIE_TYPE_RSS_094 RSS 0.94.
1639      * @see SIMPLEPIE_TYPE_RSS_10 RSS 1.0.
1640      * @see SIMPLEPIE_TYPE_RSS_20 RSS 2.0.x.
1641      * @see SIMPLEPIE_TYPE_RSS_RDF RDF-based RSS.
1642      * @see SIMPLEPIE_TYPE_RSS_SYNDICATION Non-RDF-based RSS (truly intended as syndication format).
1643      * @see SIMPLEPIE_TYPE_RSS_ALL Any version of RSS.
1644      * @see SIMPLEPIE_TYPE_ATOM_03 Atom 0.3.
1645      * @see SIMPLEPIE_TYPE_ATOM_10 Atom 1.0.
1646      * @see SIMPLEPIE_TYPE_ATOM_ALL Any version of Atom.
1647      * @see SIMPLEPIE_TYPE_ALL Any known/supported feed type.
1648      * @return int SIMPLEPIE_TYPE_* constant
1649      */
1650     public function get_type()
1651     {
1652         if (!isset($this->data['type']))
1653         {
1654             $this->data['type'] = SIMPLEPIE_TYPE_ALL;
1655             if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed']))
1656             {
1657                 $this->data['type'] &= SIMPLEPIE_TYPE_ATOM_10;
1658             }
1659             elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed']))
1660             {
1661                 $this->data['type'] &= SIMPLEPIE_TYPE_ATOM_03;
1662             }
1663             elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF']))
1664             {
1665                 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['channel'])
1666                 || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['image'])
1667                 || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['item'])
1668                 || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['textinput']))
1669                 {
1670                     $this->data['type'] &= SIMPLEPIE_TYPE_RSS_10;
1671                 }
1672                 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['channel'])
1673                 || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['image'])
1674                 || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['item'])
1675                 || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['textinput']))
1676                 {
1677                     $this->data['type'] &= SIMPLEPIE_TYPE_RSS_090;
1678                 }
1679             }
1680             elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss']))
1681             {
1682                 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_ALL;
1683                 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0]['attribs']['']['version']))
1684                 {
1685                     switch (trim($this->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0]['attribs']['']['version']))
1686                     {
1687                         case '0.91':
1688                             $this->data['type'] &= SIMPLEPIE_TYPE_RSS_091;
1689                             if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_20]['skiphours']['hour'][0]['data']))
1690                             {
1691                                 switch (trim($this->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_20]['skiphours']['hour'][0]['data']))
1692                                 {
1693                                     case '0':
1694                                         $this->data['type'] &= SIMPLEPIE_TYPE_RSS_091_NETSCAPE;
1695                                         break;
1696 
1697                                     case '24':
1698                                         $this->data['type'] &= SIMPLEPIE_TYPE_RSS_091_USERLAND;
1699                                         break;
1700                                 }
1701                             }
1702                             break;
1703 
1704                         case '0.92':
1705                             $this->data['type'] &= SIMPLEPIE_TYPE_RSS_092;
1706                             break;
1707 
1708                         case '0.93':
1709                             $this->data['type'] &= SIMPLEPIE_TYPE_RSS_093;
1710                             break;
1711 
1712                         case '0.94':
1713                             $this->data['type'] &= SIMPLEPIE_TYPE_RSS_094;
1714                             break;
1715 
1716                         case '2.0':
1717                             $this->data['type'] &= SIMPLEPIE_TYPE_RSS_20;
1718                             break;
1719                     }
1720                 }
1721             }
1722             else
1723             {
1724                 $this->data['type'] = SIMPLEPIE_TYPE_NONE;
1725             }
1726         }
1727         return $this->data['type'];
1728     }
1729 
1730     /**
1731      * Get the URL for the feed
1732      *
1733      * May or may not be different from the URL passed to {@see set_feed_url()},
1734      * depending on whether auto-discovery was used.
1735      *
1736      * @since Preview Release (previously called `get_feed_url()` since SimplePie 0.8.)
1737      * @todo If we have a perm redirect we should return the new URL
1738      * @todo When we make the above change, let's support <itunes:new-feed-url> as well
1739      * @todo Also, |atom:link|@rel=self
1740      * @return string|null
1741      */
1742     public function subscribe_url()
1743     {
1744         if ($this->feed_url !== null)
1745         {
1746             return $this->sanitize($this->feed_url, SIMPLEPIE_CONSTRUCT_IRI);
1747         }
1748         else
1749         {
1750             return null;
1751         }
1752     }
1753 
1754     /**
1755      * Get data for an feed-level element
1756      *
1757      * This method allows you to get access to ANY element/attribute that is a
1758      * sub-element of the opening feed tag.
1759      *
1760      * The return value is an indexed array of elements matching the given
1761      * namespace and tag name. Each element has `attribs`, `data` and `child`
1762      * subkeys. For `attribs` and `child`, these contain namespace subkeys.
1763      * `attribs` then has one level of associative name => value data (where
1764      * `value` is a string) after the namespace. `child` has tag-indexed keys
1765      * after the namespace, each member of which is an indexed array matching
1766      * this same format.
1767      *
1768      * For example:
1769      * <pre>
1770      * // This is probably a bad example because we already support
1771      * // <media:content> natively, but it shows you how to parse through
1772      * // the nodes.
1773      * $group = $item->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'group');
1774      * $content = $group[0]['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['content'];
1775      * $file = $content[0]['attribs']['']['url'];
1776      * echo $file;
1777      * </pre>
1778      *
1779      * @since 1.0
1780      * @see http://simplepie.org/wiki/faq/supported_xml_namespaces
1781      * @param string $namespace The URL of the XML namespace of the elements you're trying to access
1782      * @param string $tag Tag name
1783      * @return array
1784      */
1785     public function get_feed_tags($namespace, $tag)
1786     {
1787         $type = $this->get_type();
1788         if ($type & SIMPLEPIE_TYPE_ATOM_10)
1789         {
1790             if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['child'][$namespace][$tag]))
1791             {
1792                 return $this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['child'][$namespace][$tag];
1793             }
1794         }
1795         if ($type & SIMPLEPIE_TYPE_ATOM_03)
1796         {
1797             if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['child'][$namespace][$tag]))
1798             {
1799                 return $this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['child'][$namespace][$tag];
1800             }
1801         }
1802         if ($type & SIMPLEPIE_TYPE_RSS_RDF)
1803         {
1804             if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][$namespace][$tag]))
1805             {
1806                 return $this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][$namespace][$tag];
1807             }
1808         }
1809         if ($type & SIMPLEPIE_TYPE_RSS_SYNDICATION)
1810         {
1811             if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0]['child'][$namespace][$tag]))
1812             {
1813                 return $this->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0]['child'][$namespace][$tag];
1814             }
1815         }
1816         return null;
1817     }
1818 
1819     /**
1820      * Get data for an channel-level element
1821      *
1822      * This method allows you to get access to ANY element/attribute in the
1823      * channel/header section of the feed.
1824      *
1825      * See {@see SimplePie::get_feed_tags()} for a description of the return value
1826      *
1827      * @since 1.0
1828      * @see http://simplepie.org/wiki/faq/supported_xml_namespaces
1829      * @param string $namespace The URL of the XML namespace of the elements you're trying to access
1830      * @param string $tag Tag name
1831      * @return array
1832      */
1833     public function get_channel_tags($namespace, $tag)
1834     {
1835         $type = $this->get_type();
1836         if ($type & SIMPLEPIE_TYPE_ATOM_ALL)
1837         {
1838             if ($return = $this->get_feed_tags($namespace, $tag))
1839             {
1840                 return $return;
1841             }
1842         }
1843         if ($type & SIMPLEPIE_TYPE_RSS_10)
1844         {
1845             if ($channel = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'channel'))
1846             {
1847                 if (isset($channel[0]['child'][$namespace][$tag]))
1848                 {
1849                     return $channel[0]['child'][$namespace][$tag];
1850                 }
1851             }
1852         }
1853         if ($type & SIMPLEPIE_TYPE_RSS_090)
1854         {
1855             if ($channel = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'channel'))
1856             {
1857                 if (isset($channel[0]['child'][$namespace][$tag]))
1858                 {
1859                     return $channel[0]['child'][$namespace][$tag];
1860                 }
1861             }
1862         }
1863         if ($type & SIMPLEPIE_TYPE_RSS_SYNDICATION)
1864         {
1865             if ($channel = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'channel'))
1866             {
1867                 if (isset($channel[0]['child'][$namespace][$tag]))
1868                 {
1869                     return $channel[0]['child'][$namespace][$tag];
1870                 }
1871             }
1872         }
1873         return null;
1874     }
1875 
1876     /**
1877      * Get data for an channel-level element
1878      *
1879      * This method allows you to get access to ANY element/attribute in the
1880      * image/logo section of the feed.
1881      *
1882      * See {@see SimplePie::get_feed_tags()} for a description of the return value
1883      *
1884      * @since 1.0
1885      * @see http://simplepie.org/wiki/faq/supported_xml_namespaces
1886      * @param string $namespace The URL of the XML namespace of the elements you're trying to access
1887      * @param string $tag Tag name
1888      * @return array
1889      */
1890     public function get_image_tags($namespace, $tag)
1891     {
1892         $type = $this->get_type();
1893         if ($type & SIMPLEPIE_TYPE_RSS_10)
1894         {
1895             if ($image = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'image'))
1896             {
1897                 if (isset($image[0]['child'][$namespace][$tag]))
1898                 {
1899                     return $image[0]['child'][$namespace][$tag];
1900                 }
1901             }
1902         }
1903         if ($type & SIMPLEPIE_TYPE_RSS_090)
1904         {
1905             if ($image = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'image'))
1906             {
1907                 if (isset($image[0]['child'][$namespace][$tag]))
1908                 {
1909                     return $image[0]['child'][$namespace][$tag];
1910                 }
1911             }
1912         }
1913         if ($type & SIMPLEPIE_TYPE_RSS_SYNDICATION)
1914         {
1915             if ($image = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'image'))
1916             {
1917                 if (isset($image[0]['child'][$namespace][$tag]))
1918                 {
1919                     return $image[0]['child'][$namespace][$tag];
1920                 }
1921             }
1922         }
1923         return null;
1924     }
1925 
1926     /**
1927      * Get the base URL value from the feed
1928      *
1929      * Uses `<xml:base>` if available, otherwise uses the first link in the
1930      * feed, or failing that, the URL of the feed itself.
1931      *
1932      * @see get_link
1933      * @see subscribe_url
1934      *
1935      * @param array $element
1936      * @return string
1937      */
1938     public function get_base($element = array())
1939     {
1940         if (!($this->get_type() & SIMPLEPIE_TYPE_RSS_SYNDICATION) && !empty($element['xml_base_explicit']) && isset($element['xml_base']))
1941         {
1942             return $element['xml_base'];
1943         }
1944         elseif ($this->get_link() !== null)
1945         {
1946             return $this->get_link();
1947         }
1948         else
1949         {
1950             return $this->subscribe_url();
1951         }
1952     }
1953 
1954     /**
1955      * Sanitize feed data
1956      *
1957      * @access private
1958      * @see SimplePie_Sanitize::sanitize()
1959      * @param string $data Data to sanitize
1960      * @param int $type One of the SIMPLEPIE_CONSTRUCT_* constants
1961      * @param string $base Base URL to resolve URLs against
1962      * @return string Sanitized data
1963      */
1964     public function sanitize($data, $type, $base = '')
1965     {
1966         return $this->sanitize->sanitize($data, $type, $base);
1967     }
1968 
1969     /**
1970      * Get the title of the feed
1971      *
1972      * Uses `<atom:title>`, `<title>` or `<dc:title>`
1973      *
1974      * @since 1.0 (previously called `get_feed_title` since 0.8)
1975      * @return string|null
1976      */
1977     public function get_title()
1978     {
1979         if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'title'))
1980         {
1981             return $this->sanitize($return[0]['data'], $this->registry->call('Misc', 'atom_10_construct_type', array($return[0]['attribs'])), $this->get_base($return[0]));
1982         }
1983         elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'title'))
1984         {
1985             return $this->sanitize($return[0]['data'], $this->registry->call('Misc', 'atom_03_construct_type', array($return[0]['attribs'])), $this->get_base($return[0]));
1986         }
1987         elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'title'))
1988         {
1989             return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
1990         }
1991         elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'title'))
1992         {
1993             return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
1994         }
1995         elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'title'))
1996         {
1997             return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
1998         }
1999         elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'title'))
2000         {
2001             return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2002         }
2003         elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'title'))
2004         {
2005             return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2006         }
2007         else
2008         {
2009             return null;
2010         }
2011     }
2012 
2013     /**
2014      * Get a category for the feed
2015      *
2016      * @since Unknown
2017      * @param int $key The category that you want to return.  Remember that arrays begin with 0, not 1
2018      * @return SimplePie_Category|null
2019      */
2020     public function get_category($key = 0)
2021     {
2022         $categories = $this->get_categories();
2023         if (isset($categories[$key]))
2024         {
2025             return $categories[$key];
2026         }
2027         else
2028         {
2029             return null;
2030         }
2031     }
2032 
2033     /**
2034      * Get all categories for the feed
2035      *
2036      * Uses `<atom:category>`, `<category>` or `<dc:subject>`
2037      *
2038      * @since Unknown
2039      * @return array|null List of {@see SimplePie_Category} objects
2040      */
2041     public function get_categories()
2042     {
2043         $categories = array();
2044 
2045         foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'category') as $category)
2046         {
2047             $term = null;
2048             $scheme = null;
2049             $label = null;
2050             if (isset($category['attribs']['']['term']))
2051             {
2052                 $term = $this->sanitize($category['attribs']['']['term'], SIMPLEPIE_CONSTRUCT_TEXT);
2053             }
2054             if (isset($category['attribs']['']['scheme']))
2055             {
2056                 $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
2057             }
2058             if (isset($category['attribs']['']['label']))
2059             {
2060                 $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
2061             }
2062             $categories[] = $this->registry->create('Category', array($term, $scheme, $label));
2063         }
2064         foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'category') as $category)
2065         {
2066             // This is really the label, but keep this as the term also for BC.
2067             // Label will also work on retrieving because that falls back to term.
2068             $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2069             if (isset($category['attribs']['']['domain']))
2070             {
2071                 $scheme = $this->sanitize($category['attribs']['']['domain'], SIMPLEPIE_CONSTRUCT_TEXT);
2072             }
2073             else
2074             {
2075                 $scheme = null;
2076             }
2077             $categories[] = $this->registry->create('Category', array($term, $scheme, null));
2078         }
2079         foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'subject') as $category)
2080         {
2081             $categories[] = $this->registry->create('Category', array($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null));
2082         }
2083         foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'subject') as $category)
2084         {
2085             $categories[] = $this->registry->create('Category', array($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null));
2086         }
2087 
2088         if (!empty($categories))
2089         {
2090             return array_unique($categories);
2091         }
2092         else
2093         {
2094             return null;
2095         }
2096     }
2097 
2098     /**
2099      * Get an author for the feed
2100      *
2101      * @since 1.1
2102      * @param int $key The author that you want to return.  Remember that arrays begin with 0, not 1
2103      * @return SimplePie_Author|null
2104      */
2105     public function get_author($key = 0)
2106     {
2107         $authors = $this->get_authors();
2108         if (isset($authors[$key]))
2109         {
2110             return $authors[$key];
2111         }
2112         else
2113         {
2114             return null;
2115         }
2116     }
2117 
2118     /**
2119      * Get all authors for the feed
2120      *
2121      * Uses `<atom:author>`, `<author>`, `<dc:creator>` or `<itunes:author>`
2122      *
2123      * @since 1.1
2124      * @return array|null List of {@see SimplePie_Author} objects
2125      */
2126     public function get_authors()
2127     {
2128         $authors = array();
2129         foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'author') as $author)
2130         {
2131             $name = null;
2132             $uri = null;
2133             $email = null;
2134             if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
2135             {
2136                 $name = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2137             }
2138             if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
2139             {
2140                 $uri = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]));
2141             }
2142             if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
2143             {
2144                 $email = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2145             }
2146             if ($name !== null || $email !== null || $uri !== null)
2147             {
2148                 $authors[] = $this->registry->create('Author', array($name, $uri, $email));
2149             }
2150         }
2151         if ($author = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'author'))
2152         {
2153             $name = null;
2154             $url = null;
2155             $email = null;
2156             if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
2157             {
2158                 $name = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2159             }
2160             if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
2161             {
2162                 $url = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]));
2163             }
2164             if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
2165             {
2166                 $email = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2167             }
2168             if ($name !== null || $email !== null || $url !== null)
2169             {
2170                 $authors[] = $this->registry->create('Author', array($name, $url, $email));
2171             }
2172         }
2173         foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'creator') as $author)
2174         {
2175             $authors[] = $this->registry->create('Author', array($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null));
2176         }
2177         foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'creator') as $author)
2178         {
2179             $authors[] = $this->registry->create('Author', array($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null));
2180         }
2181         foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'author') as $author)
2182         {
2183             $authors[] = $this->registry->create('Author', array($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null));
2184         }
2185 
2186         if (!empty($authors))
2187         {
2188             return array_unique($authors);
2189         }
2190         else
2191         {
2192             return null;
2193         }
2194     }
2195 
2196     /**
2197      * Get a contributor for the feed
2198      *
2199      * @since 1.1
2200      * @param int $key The contrbutor that you want to return.  Remember that arrays begin with 0, not 1
2201      * @return SimplePie_Author|null
2202      */
2203     public function get_contributor($key = 0)
2204     {
2205         $contributors = $this->get_contributors();
2206         if (isset($contributors[$key]))
2207         {
2208             return $contributors[$key];
2209         }
2210         else
2211         {
2212             return null;
2213         }
2214     }
2215 
2216     /**
2217      * Get all contributors for the feed
2218      *
2219      * Uses `<atom:contributor>`
2220      *
2221      * @since 1.1
2222      * @return array|null List of {@see SimplePie_Author} objects
2223      */
2224     public function get_contributors()
2225     {
2226         $contributors = array();
2227         foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'contributor') as $contributor)
2228         {
2229             $name = null;
2230             $uri = null;
2231             $email = null;
2232             if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
2233             {
2234                 $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2235             }
2236             if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
2237             {
2238                 $uri = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]));
2239             }
2240             if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
2241             {
2242                 $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2243             }
2244             if ($name !== null || $email !== null || $uri !== null)
2245             {
2246                 $contributors[] = $this->registry->create('Author', array($name, $uri, $email));
2247             }
2248         }
2249         foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'contributor') as $contributor)
2250         {
2251             $name = null;
2252             $url = null;
2253             $email = null;
2254             if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
2255             {
2256                 $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2257             }
2258             if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
2259             {
2260                 $url = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]));
2261             }
2262             if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
2263             {
2264                 $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2265             }
2266             if ($name !== null || $email !== null || $url !== null)
2267             {
2268                 $contributors[] = $this->registry->create('Author', array($name, $url, $email));
2269             }
2270         }
2271 
2272         if (!empty($contributors))
2273         {
2274             return array_unique($contributors);
2275         }
2276         else
2277         {
2278             return null;
2279         }
2280     }
2281 
2282     /**
2283      * Get a single link for the feed
2284      *
2285      * @since 1.0 (previously called `get_feed_link` since Preview Release, `get_feed_permalink()` since 0.8)
2286      * @param int $key The link that you want to return.  Remember that arrays begin with 0, not 1
2287      * @param string $rel The relationship of the link to return
2288      * @return string|null Link URL
2289      */
2290     public function get_link($key = 0, $rel = 'alternate')
2291     {
2292         $links = $this->get_links($rel);
2293         if (isset($links[$key]))
2294         {
2295             return $links[$key];
2296         }
2297         else
2298         {
2299             return null;
2300         }
2301     }
2302 
2303     /**
2304      * Get the permalink for the item
2305      *
2306      * Returns the first link available with a relationship of "alternate".
2307      * Identical to {@see get_link()} with key 0
2308      *
2309      * @see get_link
2310      * @since 1.0 (previously called `get_feed_link` since Preview Release, `get_feed_permalink()` since 0.8)
2311      * @internal Added for parity between the parent-level and the item/entry-level.
2312      * @return string|null Link URL
2313      */
2314     public function get_permalink()
2315     {
2316         return $this->get_link(0);
2317     }
2318 
2319     /**
2320      * Get all links for the feed
2321      *
2322      * Uses `<atom:link>` or `<link>`
2323      *
2324      * @since Beta 2
2325      * @param string $rel The relationship of links to return
2326      * @return array|null Links found for the feed (strings)
2327      */
2328     public function get_links($rel = 'alternate')
2329     {
2330         if (!isset($this->data['links']))
2331         {
2332             $this->data['links'] = array();
2333             if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'link'))
2334             {
2335                 foreach ($links as $link)
2336                 {
2337                     if (isset($link['attribs']['']['href']))
2338                     {
2339                         $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
2340                         $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
2341                     }
2342                 }
2343             }
2344             if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'link'))
2345             {
2346                 foreach ($links as $link)
2347                 {
2348                     if (isset($link['attribs']['']['href']))
2349                     {
2350                         $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
2351                         $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
2352 
2353                     }
2354                 }
2355             }
2356             if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'link'))
2357             {
2358                 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
2359             }
2360             if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'link'))
2361             {
2362                 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
2363             }
2364             if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'link'))
2365             {
2366                 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
2367             }
2368 
2369             $keys = array_keys($this->data['links']);
2370             foreach ($keys as $key)
2371             {
2372                 if ($this->registry->call('Misc', 'is_isegment_nz_nc', array($key)))
2373                 {
2374                     if (isset($this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]))
2375                     {
2376                         $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] = array_merge($this->data['links'][$key], $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]);
2377                         $this->data['links'][$key] =& $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key];
2378                     }
2379                     else
2380                     {
2381                         $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] =& $this->data['links'][$key];
2382                     }
2383                 }
2384                 elseif (substr($key, 0, 41) === SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY)
2385                 {
2386                     $this->data['links'][substr($key, 41)] =& $this->data['links'][$key];
2387                 }
2388                 $this->data['links'][$key] = array_unique($this->data['links'][$key]);
2389             }
2390         }
2391 
2392         if (isset($this->data['links'][$rel]))
2393         {
2394             return $this->data['links'][$rel];
2395         }
2396         else
2397         {
2398             return null;
2399         }
2400     }
2401 
2402     public function get_all_discovered_feeds()
2403     {
2404         return $this->all_discovered_feeds;
2405     }
2406 
2407     /**
2408      * Get the content for the item
2409      *
2410      * Uses `<atom:subtitle>`, `<atom:tagline>`, `<description>`,
2411      * `<dc:description>`, `<itunes:summary>` or `<itunes:subtitle>`
2412      *
2413      * @since 1.0 (previously called `get_feed_description()` since 0.8)
2414      * @return string|null
2415      */
2416     public function get_description()
2417     {
2418         if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'subtitle'))
2419         {
2420             return $this->sanitize($return[0]['data'], $this->registry->call('Misc', 'atom_10_construct_type', array($return[0]['attribs'])), $this->get_base($return[0]));
2421         }
2422         elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'tagline'))
2423         {
2424             return $this->sanitize($return[0]['data'], $this->registry->call('Misc', 'atom_03_construct_type', array($return[0]['attribs'])), $this->get_base($return[0]));
2425         }
2426         elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'description'))
2427         {
2428             return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2429         }
2430         elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'description'))
2431         {
2432             return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2433         }
2434         elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'description'))
2435         {
2436             return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
2437         }
2438         elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'description'))
2439         {
2440             return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2441         }
2442         elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'description'))
2443         {
2444             return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2445         }
2446         elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'summary'))
2447         {
2448             return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
2449         }
2450         elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'subtitle'))
2451         {
2452             return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
2453         }
2454         else
2455         {
2456             return null;
2457         }
2458     }
2459 
2460     /**
2461      * Get the copyright info for the feed
2462      *
2463      * Uses `<atom:rights>`, `<atom:copyright>` or `<dc:rights>`
2464      *
2465      * @since 1.0 (previously called `get_feed_copyright()` since 0.8)
2466      * @return string|null
2467      */
2468     public function get_copyright()
2469     {
2470         if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'rights'))
2471         {
2472             return $this->sanitize($return[0]['data'], $this->registry->call('Misc', 'atom_10_construct_type', array($return[0]['attribs'])), $this->get_base($return[0]));
2473         }
2474         elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'copyright'))
2475         {
2476             return $this->sanitize($return[0]['data'], $this->registry->call('Misc', 'atom_03_construct_type', array($return[0]['attribs'])), $this->get_base($return[0]));
2477         }
2478         elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'copyright'))
2479         {
2480             return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2481         }
2482         elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'rights'))
2483         {
2484             return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2485         }
2486         elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'rights'))
2487         {
2488             return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2489         }
2490         else
2491         {
2492             return null;
2493         }
2494     }
2495 
2496     /**
2497      * Get the language for the feed
2498      *
2499      * Uses `<language>`, `<dc:language>`, or @xml_lang
2500      *
2501      * @since 1.0 (previously called `get_feed_language()` since 0.8)
2502      * @return string|null
2503      */
2504     public function get_language()
2505     {
2506         if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'language'))
2507         {
2508             return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2509         }
2510         elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'language'))
2511         {
2512             return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2513         }
2514         elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'language'))
2515         {
2516             return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2517         }
2518         elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['xml_lang']))
2519         {
2520             return $this->sanitize($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT);
2521         }
2522         elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['xml_lang']))
2523         {
2524             return $this->sanitize($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT);
2525         }
2526         elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['xml_lang']))
2527         {
2528             return $this->sanitize($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT);
2529         }
2530         elseif (isset($this->data['headers']['content-language']))
2531         {
2532             return $this->sanitize($this->data['headers']['content-language'], SIMPLEPIE_CONSTRUCT_TEXT);
2533         }
2534         else
2535         {
2536             return null;
2537         }
2538     }
2539 
2540     /**
2541      * Get the latitude coordinates for the item
2542      *
2543      * Compatible with the W3C WGS84 Basic Geo and GeoRSS specifications
2544      *
2545      * Uses `<geo:lat>` or `<georss:point>`
2546      *
2547      * @since 1.0
2548      * @link http://www.w3.org/2003/01/geo/ W3C WGS84 Basic Geo
2549      * @link http://www.georss.org/ GeoRSS
2550      * @return string|null
2551      */
2552     public function get_latitude()
2553     {
2554 
2555         if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lat'))
2556         {
2557             return (float) $return[0]['data'];
2558         }
2559         elseif (($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', trim($return[0]['data']), $match))
2560         {
2561             return (float) $match[1];
2562         }
2563         else
2564         {
2565             return null;
2566         }
2567     }
2568 
2569     /**
2570      * Get the longitude coordinates for the feed
2571      *
2572      * Compatible with the W3C WGS84 Basic Geo and GeoRSS specifications
2573      *
2574      * Uses `<geo:long>`, `<geo:lon>` or `<georss:point>`
2575      *
2576      * @since 1.0
2577      * @link http://www.w3.org/2003/01/geo/ W3C WGS84 Basic Geo
2578      * @link http://www.georss.org/ GeoRSS
2579      * @return string|null
2580      */
2581     public function get_longitude()
2582     {
2583         if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'long'))
2584         {
2585             return (float) $return[0]['data'];
2586         }
2587         elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lon'))
2588         {
2589             return (float) $return[0]['data'];
2590         }
2591         elseif (($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', trim($return[0]['data']), $match))
2592         {
2593             return (float) $match[2];
2594         }
2595         else
2596         {
2597             return null;
2598         }
2599     }
2600 
2601     /**
2602      * Get the feed logo's title
2603      *
2604      * RSS 0.9.0, 1.0 and 2.0 feeds are allowed to have a "feed logo" title.
2605      *
2606      * Uses `<image><title>` or `<image><dc:title>`
2607      *
2608      * @return string|null
2609      */
2610     public function get_image_title()
2611     {
2612         if ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'title'))
2613         {
2614             return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2615         }
2616         elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'title'))
2617         {
2618             return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2619         }
2620         elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'title'))
2621         {
2622             return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2623         }
2624         elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_DC_11, 'title'))
2625         {
2626             return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2627         }
2628         elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_DC_10, 'title'))
2629         {
2630             return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2631         }
2632         else
2633         {
2634             return null;
2635         }
2636     }
2637 
2638     /**
2639      * Get the feed logo's URL
2640      *
2641      * RSS 0.9.0, 2.0, Atom 1.0, and feeds with iTunes RSS tags are allowed to
2642      * have a "feed logo" URL. This points directly to the image itself.
2643      *
2644      * Uses `<itunes:image>`, `<atom:logo>`, `<atom:icon>`,
2645      * `<image><title>` or `<image><dc:title>`
2646      *
2647      * @return string|null
2648      */
2649     public function get_image_url()
2650     {
2651         if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'image'))
2652         {
2653             return $this->sanitize($return[0]['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI);
2654         }
2655         elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'logo'))
2656         {
2657             return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2658         }
2659         elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'icon'))
2660         {
2661             return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2662         }
2663         elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'url'))
2664         {
2665             return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2666         }
2667         elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'url'))
2668         {
2669             return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2670         }
2671         elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'url'))
2672         {
2673             return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2674         }
2675         else
2676         {
2677             return null;
2678         }
2679     }
2680 
2681 
2682     /**
2683      * Get the feed logo's link
2684      *
2685      * RSS 0.9.0, 1.0 and 2.0 feeds are allowed to have a "feed logo" link. This
2686      * points to a human-readable page that the image should link to.
2687      *
2688      * Uses `<itunes:image>`, `<atom:logo>`, `<atom:icon>`,
2689      * `<image><title>` or `<image><dc:title>`
2690      *
2691      * @return string|null
2692      */
2693     public function get_image_link()
2694     {
2695         if ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'link'))
2696         {
2697             return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2698         }
2699         elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'link'))
2700         {
2701             return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2702         }
2703         elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'link'))
2704         {
2705             return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2706         }
2707         else
2708         {
2709             return null;
2710         }
2711     }
2712 
2713     /**
2714      * Get the feed logo's link
2715      *
2716      * RSS 2.0 feeds are allowed to have a "feed logo" width.
2717      *
2718      * Uses `<image><width>` or defaults to 88.0 if no width is specified and
2719      * the feed is an RSS 2.0 feed.
2720      *
2721      * @return int|float|null
2722      */
2723     public function get_image_width()
2724     {
2725         if ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'width'))
2726         {
2727             return round($return[0]['data']);
2728         }
2729         elseif ($this->get_type() & SIMPLEPIE_TYPE_RSS_SYNDICATION && $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'url'))
2730         {
2731             return 88.0;
2732         }
2733         else
2734         {
2735             return null;
2736         }
2737     }
2738 
2739     /**
2740      * Get the feed logo's height
2741      *
2742      * RSS 2.0 feeds are allowed to have a "feed logo" height.
2743      *
2744      * Uses `<image><height>` or defaults to 31.0 if no height is specified and
2745      * the feed is an RSS 2.0 feed.
2746      *
2747      * @return int|float|null
2748      */
2749     public function get_image_height()
2750     {
2751         if ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'height'))
2752         {
2753             return round($return[0]['data']);
2754         }
2755         elseif ($this->get_type() & SIMPLEPIE_TYPE_RSS_SYNDICATION && $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'url'))
2756         {
2757             return 31.0;
2758         }
2759         else
2760         {
2761             return null;
2762         }
2763     }
2764 
2765     /**
2766      * Get the number of items in the feed
2767      *
2768      * This is well-suited for {@link http://php.net/for for()} loops with
2769      * {@see get_item()}
2770      *
2771      * @param int $max Maximum value to return. 0 for no limit
2772      * @return int Number of items in the feed
2773      */
2774     public function get_item_quantity($max = 0)
2775     {
2776         $max = (int) $max;
2777         $qty = count($this->get_items());
2778         if ($max === 0)
2779         {
2780             return $qty;
2781         }
2782         else
2783         {
2784             return ($qty > $max) ? $max : $qty;
2785         }
2786     }
2787 
2788     /**
2789      * Get a single item from the feed
2790      *
2791      * This is better suited for {@link http://php.net/for for()} loops, whereas
2792      * {@see get_items()} is better suited for
2793      * {@link http://php.net/foreach foreach()} loops.
2794      *
2795      * @see get_item_quantity()
2796      * @since Beta 2
2797      * @param int $key The item that you want to return.  Remember that arrays begin with 0, not 1
2798      * @return SimplePie_Item|null
2799      */
2800     public function get_item($key = 0)
2801     {
2802         $items = $this->get_items();
2803         if (isset($items[$key]))
2804         {
2805             return $items[$key];
2806         }
2807         else
2808         {
2809             return null;
2810         }
2811     }
2812 
2813     /**
2814      * Get all items from the feed
2815      *
2816      * This is better suited for {@link http://php.net/for for()} loops, whereas
2817      * {@see get_items()} is better suited for
2818      * {@link http://php.net/foreach foreach()} loops.
2819      *
2820      * @see get_item_quantity
2821      * @since Beta 2
2822      * @param int $start Index to start at
2823      * @param int $end Number of items to return. 0 for all items after `$start`
2824      * @return array|null List of {@see SimplePie_Item} objects
2825      */
2826     public function get_items($start = 0, $end = 0)
2827     {
2828         if (!isset($this->data['items']))
2829         {
2830             if (!empty($this->multifeed_objects))
2831             {
2832                 $this->data['items'] = SimplePie::merge_items($this->multifeed_objects, $start, $end, $this->item_limit);
2833             }
2834             else
2835             {
2836                 $this->data['items'] = array();
2837                 if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'entry'))
2838                 {
2839                     $keys = array_keys($items);
2840                     foreach ($keys as $key)
2841                     {
2842                         $this->data['items'][] = $this->registry->create('Item', array($this, $items[$key]));
2843                     }
2844                 }
2845                 if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'entry'))
2846                 {
2847                     $keys = array_keys($items);
2848                     foreach ($keys as $key)
2849                     {
2850                         $this->data['items'][] = $this->registry->create('Item', array($this, $items[$key]));
2851                     }
2852                 }
2853                 if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'item'))
2854                 {
2855                     $keys = array_keys($items);
2856                     foreach ($keys as $key)
2857                     {
2858                         $this->data['items'][] = $this->registry->create('Item', array($this, $items[$key]));
2859                     }
2860                 }
2861                 if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'item'))
2862                 {
2863                     $keys = array_keys($items);
2864                     foreach ($keys as $key)
2865                     {
2866                         $this->data['items'][] = $this->registry->create('Item', array($this, $items[$key]));
2867                     }
2868                 }
2869                 if ($items = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'item'))
2870                 {
2871                     $keys = array_keys($items);
2872                     foreach ($keys as $key)
2873                     {
2874                         $this->data['items'][] = $this->registry->create('Item', array($this, $items[$key]));
2875                     }
2876                 }
2877             }
2878         }
2879 
2880         if (!empty($this->data['items']))
2881         {
2882             // If we want to order it by date, check if all items have a date, and then sort it
2883             if ($this->order_by_date && empty($this->multifeed_objects))
2884             {
2885                 if (!isset($this->data['ordered_items']))
2886                 {
2887                     $do_sort = true;
2888                     foreach ($this->data['items'] as $item)
2889                     {
2890                         if (!$item->get_date('U'))
2891                         {
2892                             $do_sort = false;
2893                             break;
2894                         }
2895                     }
2896                     $item = null;
2897                     $this->data['ordered_items'] = $this->data['items'];
2898                     if ($do_sort)
2899                     {
2900                         usort($this->data['ordered_items'], array(get_class($this), 'sort_items'));
2901                     }
2902                 }
2903                 $items = $this->data['ordered_items'];
2904             }
2905             else
2906             {
2907                 $items = $this->data['items'];
2908             }
2909 
2910             // Slice the data as desired
2911             if ($end === 0)
2912             {
2913                 return array_slice($items, $start);
2914             }
2915             else
2916             {
2917                 return array_slice($items, $start, $end);
2918             }
2919         }
2920         else
2921         {
2922             return array();
2923         }
2924     }
2925 
2926     /**
2927      * Set the favicon handler
2928      *
2929      * @deprecated Use your own favicon handling instead
2930      */
2931     public function set_favicon_handler($page = false, $qs = 'i')
2932     {
2933         $level = defined('E_USER_DEPRECATED') ? E_USER_DEPRECATED : E_USER_WARNING;
2934         trigger_error('Favicon handling has been removed, please use your own handling', $level);
2935         return false;
2936     }
2937 
2938     /**
2939      * Get the favicon for the current feed
2940      *
2941      * @deprecated Use your own favicon handling instead
2942      */
2943     public function get_favicon()
2944     {
2945         $level = defined('E_USER_DEPRECATED') ? E_USER_DEPRECATED : E_USER_WARNING;
2946         trigger_error('Favicon handling has been removed, please use your own handling', $level);
2947 
2948         if (($url = $this->get_link()) !== null)
2949         {
2950             return 'http://g.etfv.co/' . urlencode($url);
2951         }
2952 
2953         return false;
2954     }
2955 
2956     /**
2957      * Magic method handler
2958      *
2959      * @param string $method Method name
2960      * @param array $args Arguments to the method
2961      * @return mixed
2962      */
2963     public function __call($method, $args)
2964     {
2965         if (strpos($method, 'subscribe_') === 0)
2966         {
2967             $level = defined('E_USER_DEPRECATED') ? E_USER_DEPRECATED : E_USER_WARNING;
2968             trigger_error('subscribe_*() has been deprecated, implement the callback yourself', $level);
2969             return '';
2970         }
2971         if ($method === 'enable_xml_dump')
2972         {
2973             $level = defined('E_USER_DEPRECATED') ? E_USER_DEPRECATED : E_USER_WARNING;
2974             trigger_error('enable_xml_dump() has been deprecated, use get_raw_data() instead', $level);
2975             return false;
2976         }
2977 
2978         $class = get_class($this);
2979         $trace = debug_backtrace();
2980         $file = $trace[0]['file'];
2981         $line = $trace[0]['line'];
2982         trigger_error("Call to undefined method $class::$method() in $file on line $line", E_USER_ERROR);
2983     }
2984 
2985     /**
2986      * Sorting callback for items
2987      *
2988      * @access private
2989      * @param SimplePie $a
2990      * @param SimplePie $b
2991      * @return boolean
2992      */
2993     public static function sort_items($a, $b)
2994     {
2995         return $a->get_date('U') <= $b->get_date('U');
2996     }
2997 
2998     /**
2999      * Merge items from several feeds into one
3000      *
3001      * If you're merging multiple feeds together, they need to all have dates
3002      * for the items or else SimplePie will refuse to sort them.
3003      *
3004      * @link http://simplepie.org/wiki/tutorial/sort_multiple_feeds_by_time_and_date#if_feeds_require_separate_per-feed_settings
3005      * @param array $urls List of SimplePie feed objects to merge
3006      * @param int $start Starting item
3007      * @param int $end Number of items to return
3008      * @param int $limit Maximum number of items per feed
3009      * @return array
3010      */
3011     public static function merge_items($urls, $start = 0, $end = 0, $limit = 0)
3012     {
3013         if (is_array($urls) && sizeof($urls) > 0)
3014         {
3015             $items = array();
3016             foreach ($urls as $arg)
3017             {
3018                 if ($arg instanceof SimplePie)
3019                 {
3020                     $items = array_merge($items, $arg->get_items(0, $limit));
3021                 }
3022                 else
3023                 {
3024                     trigger_error('Arguments must be SimplePie objects', E_USER_WARNING);
3025                 }
3026             }
3027 
3028             $do_sort = true;
3029             foreach ($items as $item)
3030             {
3031                 if (!$item->get_date('U'))
3032                 {
3033                     $do_sort = false;
3034                     break;
3035                 }
3036             }
3037             $item = null;
3038             if ($do_sort)
3039             {
3040                 usort($items, array(get_class($urls[0]), 'sort_items'));
3041             }
3042 
3043             if ($end === 0)
3044             {
3045                 return array_slice($items, $start);
3046             }
3047             else
3048             {
3049                 return array_slice($items, $start, $end);
3050             }
3051         }
3052         else
3053         {
3054             trigger_error('Cannot merge zero SimplePie objects', E_USER_WARNING);
3055             return array();
3056         }
3057     }
3058 }
3059 
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.