├── .gitattributes
├── .gitignore
├── .gitmodules
├── .idea
├── .gitignore
├── .name
├── FOF 4.iml
├── codeStyleSettings.xml
├── codeStyles
│ ├── Project.xml
│ └── codeStyleConfig.xml
├── composerJson.xml
├── copyright
│ ├── FOF.xml
│ └── profiles_settings.xml
├── cssxfire.xml
├── deployment.xml
├── dictionaries
│ └── nicholas.xml
├── encodings.xml
├── inspectionProfiles
│ └── Project_Default.xml
├── libraries
│ └── Generated_files.xml
├── markdown.xml
├── misc.xml
├── modules.xml
├── phing.xml
├── php-test-framework.xml
├── php.xml
├── phpunit.xml
├── scopes
│ ├── Copyright.xml
│ ├── Plugin_CSS_Files.xml
│ ├── Plugin_JS_Files.xml
│ └── scope_settings.xml
├── sqldialects.xml
├── vcs.xml
└── watcherTasks.xml
├── .travis.yml
├── CHANGELOG
├── DESCRIPTION.html
├── MIGRATION_3_TO_4.md
├── README.md
├── RELEASENOTES.html
├── TODO.txt
├── Tests
├── Configuration
│ ├── ConfigurationTest.php
│ └── Domain
│ │ ├── AuthenticationTest.php
│ │ ├── ContainerTest.php
│ │ ├── DispatcherTest.php
│ │ ├── ModelsTest.php
│ │ └── ViewsTest.php
├── Controller
│ ├── ControllerDataprovider.php
│ ├── ControllerTest.php
│ ├── DataControllerDataprovider.php
│ └── DataControllerTest.php
├── Database
│ └── InstallerTest.php
├── Date
│ ├── TimezoneWranglerProvider.php
│ └── TimezoneWranglerTest.php
├── Dispatcher
│ ├── DispatcherDataprovider.php
│ └── DispatcherTest.php
├── Download
│ ├── Adapter
│ │ ├── CurlDataprovider.php
│ │ ├── CurlTest.php
│ │ ├── FopenDataprovider.php
│ │ └── FopenTest.php
│ ├── DownloadDataprovider.php
│ └── DownloadTest.php
├── Encrypt
│ ├── AesTest.php
│ ├── Base32Test.php
│ └── TotpTest.php
├── Event
│ ├── DispatcherTest.php
│ └── ObserverTest.php
├── Factory
│ ├── BasicFactoryDataprovider.php
│ ├── BasicFactoryTest.php
│ ├── Magic
│ │ ├── BaseFactoryTest.php
│ │ ├── ControllerFactoryDataprovider.php
│ │ ├── ControllerFactoryTest.php
│ │ ├── DispatcherFactoryTest.php
│ │ └── TranspAuthFactoryTest.php
│ ├── MagicFactoryDataprovider.php
│ ├── MagicFactoryTest.php
│ ├── MagicSwitchFactoryDataprovider.php
│ ├── MagicSwitchFactoryTest.php
│ ├── SwitchFactoryDataprovider.php
│ └── SwitchFactoryTest.php
├── Helpers
│ ├── Application
│ │ ├── AppWithLanguageFilter.php
│ │ ├── MockApplicationBase.php
│ │ ├── MockApplicationCli.php
│ │ ├── MockApplicationCms.php
│ │ ├── MockApplicationWeb.php
│ │ ├── MockDocument.php
│ │ ├── MockLanguage.php
│ │ ├── MockMenu.php
│ │ └── MockSession.php
│ ├── ApplicationTestCase.php
│ ├── ClosureHelper.php
│ ├── DatabaseTest.php
│ ├── Download
│ │ ├── FakeBase.php
│ │ ├── FakeCurl.php
│ │ ├── FakeCurlImporter.php
│ │ ├── FakeFopen.php
│ │ ├── FakeFopenImporter.php
│ │ └── data.dat
│ ├── FOFTestCase.php
│ ├── MockSession.php
│ ├── ObserverClosure.php
│ ├── Platform
│ │ └── UserForAdminAuth.php
│ ├── ReflectionHelper.php
│ ├── TestContainer.php
│ ├── TestHelper.php
│ ├── TestJoomlaPlatform.php
│ ├── Timer
│ │ ├── FakeTimer.php
│ │ └── FakeTimerImporter.php
│ ├── TravisLogger.php
│ └── VfsHelper.php
├── IP
│ ├── IPHelperTest.php
│ └── IpDataprovider.php
├── Inflector
│ └── InflectorTest.php
├── Input
│ ├── InputProvider.php
│ └── InputTest.php
├── Layout
│ ├── LayoutFileTest.php
│ ├── LayoutFileTestProvider.php
│ ├── LayoutHelperTest.php
│ └── LayoutHelperTestProvider.php
├── Model
│ ├── DataModel
│ │ ├── Behaviour
│ │ │ ├── AccessDataprovider.php
│ │ │ ├── AccessTest.php
│ │ │ ├── AssetsDataprovider.php
│ │ │ ├── AssetsTest.php
│ │ │ ├── ContentHistoryDataprovider.php
│ │ │ ├── ContentHistoryTest.php
│ │ │ ├── CreatedDataprovider.php
│ │ │ ├── CreatedTest.php
│ │ │ ├── EnabledDataprovider.php
│ │ │ ├── EnabledTest.php
│ │ │ ├── FiltersDataprovider.php
│ │ │ ├── FiltersTest.php
│ │ │ ├── LanguageDataprovider.php
│ │ │ ├── LanguageTest.php
│ │ │ ├── ModifiedDataprovider.php
│ │ │ ├── ModifiedTest.php
│ │ │ ├── OwnDataprovider.php
│ │ │ ├── OwnTest.php
│ │ │ ├── PageParametersToStateDataprovider.php
│ │ │ ├── PageParametersToStateTest.php
│ │ │ ├── RelationFiltersDataprovider.php
│ │ │ ├── RelationFiltersTest.php
│ │ │ ├── TagsDataprovider.php
│ │ │ └── TagsTest.php
│ │ ├── Collection
│ │ │ ├── CollectionDataprovider.php
│ │ │ └── CollectionTest.php
│ │ ├── CrudDataprovider.php
│ │ ├── CrudTest.php
│ │ ├── Filter
│ │ │ ├── AbstractFilterDataprovider.php
│ │ │ ├── AbstractFilterTest.php
│ │ │ ├── BooleanDataprovider.php
│ │ │ ├── BooleanTest.php
│ │ │ ├── DateDataprovider.php
│ │ │ ├── DateTest.php
│ │ │ ├── NumberDataprovider.php
│ │ │ ├── NumberTest.php
│ │ │ ├── RelationTest.php
│ │ │ ├── TextDataprovider.php
│ │ │ └── TextTest.php
│ │ ├── GenericDataprovider.php
│ │ ├── GenericTest.php
│ │ ├── MagicMethodsDataprovider.php
│ │ ├── MagicMethodsTest.php
│ │ ├── PublishDataprovider.php
│ │ ├── PublishTest.php
│ │ ├── Relation
│ │ │ ├── BelongsToDataprovider.php
│ │ │ ├── BelongsToManyDataprovider.php
│ │ │ ├── BelongsToManyTest.php
│ │ │ ├── BelongsToTest.php
│ │ │ ├── HasManyDataprovider.php
│ │ │ ├── HasManyTest.php
│ │ │ ├── RelationDataprovider.php
│ │ │ ├── RelationManagerDataprovider.php
│ │ │ ├── RelationManagerTest.php
│ │ │ └── RelationTest.php
│ │ ├── RelationDataprovider.php
│ │ ├── RelationTest.php
│ │ ├── SpecialColumnsDataprovider.php
│ │ └── SpecialColumnsTest.php
│ ├── ModelDataprovider.php
│ ├── ModelTest.php
│ ├── TreeModelDataprovider.php
│ └── TreeModelTest.php
├── Platform
│ ├── PlatformJoomlaProvider.php
│ └── PlatformJoomlaTest.php
├── README.md
├── Stubs
│ ├── Controller
│ │ ├── ControllerStub.php
│ │ └── DataControllerStub.php
│ ├── Dispatcher
│ │ └── DispatcherStub.php
│ ├── Dummyapp
│ │ └── Admin
│ │ │ └── fof.xml
│ ├── Encrypt
│ │ └── MockPhpfunc.php
│ ├── Event
│ │ ├── FirstObserver.php
│ │ └── SecondObserver.php
│ ├── Fakeapp
│ │ ├── Admin
│ │ │ ├── Controller
│ │ │ │ └── Bare.php
│ │ │ ├── Dispatcher
│ │ │ │ └── Dispatcher.php
│ │ │ ├── TransparentAuthentication
│ │ │ │ └── TransparentAuthentication.php
│ │ │ ├── View
│ │ │ │ ├── Bare
│ │ │ │ │ └── Html.php
│ │ │ │ └── Foobar
│ │ │ │ │ ├── Html.php
│ │ │ │ │ └── tmpl
│ │ │ │ │ └── default.php
│ │ │ └── fof.xml
│ │ ├── MagicSite
│ │ │ └── index.html
│ │ ├── Site
│ │ │ ├── Controller
│ │ │ │ ├── DefaultDataController.php
│ │ │ │ └── Foobars.php
│ │ │ ├── Dispatcher
│ │ │ │ └── DefaultDispatcher.php
│ │ │ ├── Form
│ │ │ │ └── Field
│ │ │ │ │ ├── Calendar.php
│ │ │ │ │ └── Customfield.php
│ │ │ ├── Model
│ │ │ │ ├── Behaviour
│ │ │ │ │ ├── Foofilters.php
│ │ │ │ │ └── Nestedset
│ │ │ │ │ │ └── NamedBehaviour.php
│ │ │ │ ├── Children.php
│ │ │ │ ├── Datafoobars.php
│ │ │ │ ├── Foobar.php
│ │ │ │ ├── Groups.php
│ │ │ │ ├── Parents.php
│ │ │ │ └── Parts.php
│ │ │ ├── Toolbar
│ │ │ │ └── Toolbar.php
│ │ │ ├── TransparentAuthentication
│ │ │ │ └── DefaultTransparentAuthentication.php
│ │ │ └── View
│ │ │ │ ├── Foobars
│ │ │ │ └── Html.php
│ │ │ │ └── Parents
│ │ │ │ └── Html.php
│ │ └── Standalone.php
│ ├── Joomla
│ │ └── JToolbarHelper.php
│ ├── Model
│ │ ├── DataModel
│ │ │ └── Filter
│ │ │ │ └── FilterStub.php
│ │ ├── DataModelStub.php
│ │ ├── ModelStub.php
│ │ ├── RelationStub.php
│ │ └── TreeModelStub.php
│ ├── Pimple
│ │ ├── Invokable.php
│ │ ├── NonInvokable.php
│ │ ├── PimpleServiceProvider.php
│ │ └── Service.php
│ ├── Session
│ │ └── FakeSession.php
│ ├── Toolbar
│ │ └── ToolbarStub.php
│ ├── Utils
│ │ └── IpStub.php
│ ├── View
│ │ ├── DataView
│ │ │ └── RawStub.php
│ │ └── ViewStub.php
│ └── schema
│ │ ├── database.xml
│ │ └── schema.xml
├── Template
│ └── TemplateTest.php
├── Timer
│ └── TimerTest.php
├── Toolbar
│ ├── ToolbarDataprovider.php
│ └── ToolbarTest.php
├── TransparentAuthentication
│ └── TransparentAuthenticationTest.php
├── Utils
│ ├── BufferTest.php
│ └── CollectionTest.php
├── View
│ ├── DataView
│ │ ├── RawDataprovider.php
│ │ └── RawTest.php
│ ├── ViewDataprovider.php
│ ├── ViewTemplateFinderProvider.php
│ ├── ViewTemplateFinderTest.php
│ └── ViewTest.php
├── _data
│ ├── configuration
│ │ ├── authentication.xml
│ │ ├── container.xml
│ │ ├── dispatcher.xml
│ │ ├── fof.xml
│ │ ├── models.xml
│ │ └── views.xml
│ ├── fake_test_template
│ │ ├── html
│ │ │ └── com_foobar
│ │ │ │ └── css
│ │ │ │ └── test.css
│ │ ├── index.php
│ │ └── media
│ │ │ └── com_foobar
│ │ │ ├── css
│ │ │ └── test.css
│ │ │ └── js
│ │ │ └── test.js
│ ├── installer
│ │ ├── pick_right
│ │ │ ├── foobar.xml
│ │ │ └── mysql.xml
│ │ ├── test_canfail.xml
│ │ ├── test_equals.xml
│ │ ├── test_fail.xml
│ │ └── test_type.xml
│ └── layout
│ │ ├── layouts
│ │ └── test
│ │ │ ├── bar.fof.php
│ │ │ ├── bat.fof.php
│ │ │ ├── foo.php
│ │ │ └── overridden.php
│ │ └── templates
│ │ └── system
│ │ └── html
│ │ └── layouts
│ │ └── test
│ │ ├── bat.php
│ │ ├── baz.fof.php
│ │ └── overridden.php
├── bootstrap.php
├── config.dist.php
├── config_travis.php
├── environments.php
├── environments
│ └── .gitinclude
└── tmp
│ └── index.html
├── assets
├── logo-100.png
├── logo.png
└── logo.svg
├── build
├── autoloader_for_rector.php
├── build.properties
├── build.xml
├── fakes
│ └── MasterFakeClass.php
└── templates
│ ├── file_fof40.xml
│ ├── include.php
│ ├── link.php
│ ├── release.yaml
│ └── version.txt
├── composer.json
├── fof
├── .htaccess
├── Autoloader
│ └── Autoloader.php
├── Cli
│ ├── Application.php
│ ├── Joomla3.php
│ ├── Joomla4.php
│ ├── Traits
│ │ ├── CGIModeAware.php
│ │ ├── CustomOptionsAware.php
│ │ ├── JoomlaConfigAware.php
│ │ ├── MemStatsAware.php
│ │ ├── MessageAware.php
│ │ └── TimeAgoAware.php
│ └── wrong_php.php
├── Configuration
│ ├── Configuration.php
│ └── Domain
│ │ ├── Authentication.php
│ │ ├── Container.php
│ │ ├── Dispatcher.php
│ │ ├── DomainInterface.php
│ │ ├── Models.php
│ │ └── Views.php
├── Container
│ ├── Container.php
│ ├── ContainerBase.php
│ └── Exception
│ │ └── NoComponent.php
├── Controller
│ ├── Controller.php
│ ├── DataController.php
│ ├── Exception
│ │ ├── CannotGetName.php
│ │ ├── ItemNotFound.php
│ │ ├── LockedRecord.php
│ │ ├── NotADataModel.php
│ │ ├── NotADataView.php
│ │ └── TaskNotFound.php
│ └── Mixin
│ │ └── PredefinedTaskList.php
├── Database
│ └── Installer.php
├── Date
│ ├── Date.php
│ ├── DateDecorator.php
│ └── TimezoneWrangler.php
├── Dispatcher
│ ├── Dispatcher.php
│ ├── Exception
│ │ └── AccessForbidden.php
│ └── Mixin
│ │ └── ViewAliases.php
├── Download
│ ├── Adapter
│ │ ├── AbstractAdapter.php
│ │ ├── Curl.php
│ │ └── Fopen.php
│ ├── Download.php
│ ├── DownloadInterface.php
│ └── Exception
│ │ └── DownloadError.php
├── Encrypt
│ ├── Aes.php
│ ├── AesAdapter
│ │ ├── AbstractAdapter.php
│ │ ├── AdapterInterface.php
│ │ └── OpenSSL.php
│ ├── Base32.php
│ ├── EncryptService.php
│ ├── Randval.php
│ ├── RandvalInterface.php
│ └── Totp.php
├── Event
│ ├── Dispatcher.php
│ ├── Observable.php
│ └── Observer.php
├── Factory
│ ├── BasicFactory.php
│ ├── Exception
│ │ ├── ControllerNotFound.php
│ │ ├── DispatcherNotFound.php
│ │ ├── ModelNotFound.php
│ │ ├── ToolbarNotFound.php
│ │ ├── TransparentAuthenticationNotFound.php
│ │ └── ViewNotFound.php
│ ├── FactoryInterface.php
│ ├── Magic
│ │ ├── BaseFactory.php
│ │ ├── ControllerFactory.php
│ │ ├── DispatcherFactory.php
│ │ ├── ModelFactory.php
│ │ ├── TransparentAuthenticationFactory.php
│ │ └── ViewFactory.php
│ ├── MagicFactory.php
│ ├── MagicSwitchFactory.php
│ └── SwitchFactory.php
├── Html
│ ├── FEFHelper
│ │ ├── BrowseView.php
│ │ ├── browse.php
│ │ ├── edit.php
│ │ └── select.php
│ ├── Fields
│ │ └── fancyradio.php
│ └── SelectOptions.php
├── IP
│ └── IPHelper.php
├── Inflector
│ └── Inflector.php
├── Input
│ └── Input.php
├── InstallScript
│ ├── BaseInstaller.php
│ ├── Component.php
│ ├── Module.php
│ └── Plugin.php
├── JoomlaAbstraction
│ ├── CacheCleaner.php
│ ├── ComponentVersion.php
│ └── DynamicGroups.php
├── LICENSE.txt
├── Layout
│ ├── LayoutFile.php
│ └── LayoutHelper.php
├── Model
│ ├── DataModel.php
│ ├── DataModel
│ │ ├── Behaviour
│ │ │ ├── Access.php
│ │ │ ├── Assets.php
│ │ │ ├── ContentHistory.php
│ │ │ ├── Created.php
│ │ │ ├── EmptyNonZero.php
│ │ │ ├── Enabled.php
│ │ │ ├── Filters.php
│ │ │ ├── Language.php
│ │ │ ├── Modified.php
│ │ │ ├── Own.php
│ │ │ ├── PageParametersToState.php
│ │ │ ├── RelationFilters.php
│ │ │ └── Tags.php
│ │ ├── Collection.php
│ │ ├── Exception
│ │ │ ├── BaseException.php
│ │ │ ├── CannotLockNotLoadedRecord.php
│ │ │ ├── InvalidSearchMethod.php
│ │ │ ├── NoAssetKey.php
│ │ │ ├── NoContentType.php
│ │ │ ├── NoItemsFound.php
│ │ │ ├── NoTableColumns.php
│ │ │ ├── RecordNotLoaded.php
│ │ │ ├── SpecialColumnMissing.php
│ │ │ ├── TreeIncompatibleTable.php
│ │ │ ├── TreeInvalidLftRgt.php
│ │ │ ├── TreeInvalidLftRgtCurrent.php
│ │ │ ├── TreeInvalidLftRgtOther.php
│ │ │ ├── TreeInvalidLftRgtParent.php
│ │ │ ├── TreeInvalidLftRgtSibling.php
│ │ │ ├── TreeMethodOnlyAllowedInRoot.php
│ │ │ ├── TreeRootNotFound.php
│ │ │ ├── TreeUnexpectedPrimaryKey.php
│ │ │ └── TreeUnsupportedMethod.php
│ │ ├── Filter
│ │ │ ├── AbstractFilter.php
│ │ │ ├── Boolean.php
│ │ │ ├── Date.php
│ │ │ ├── Exception
│ │ │ │ ├── InvalidFieldObject.php
│ │ │ │ └── NoDatabaseObject.php
│ │ │ ├── Number.php
│ │ │ ├── Relation.php
│ │ │ └── Text.php
│ │ ├── Relation.php
│ │ ├── Relation
│ │ │ ├── BelongsTo.php
│ │ │ ├── BelongsToMany.php
│ │ │ ├── Exception
│ │ │ │ ├── ForeignModelNotFound.php
│ │ │ │ ├── NewNotSupported.php
│ │ │ │ ├── PivotTableNotFound.php
│ │ │ │ ├── RelationNotFound.php
│ │ │ │ ├── RelationTypeNotFound.php
│ │ │ │ └── SaveNotSupported.php
│ │ │ ├── HasMany.php
│ │ │ └── HasOne.php
│ │ └── RelationManager.php
│ ├── Exception
│ │ └── CannotGetName.php
│ ├── Mixin
│ │ ├── Assertions.php
│ │ ├── DateManipulation.php
│ │ ├── Generators.php
│ │ ├── ImplodedArrays.php
│ │ └── JsonData.php
│ ├── Model.php
│ └── TreeModel.php
├── Params
│ └── Params.php
├── Pimple
│ ├── Container.php
│ └── ServiceProviderInterface.php
├── Platform
│ ├── Base
│ │ ├── Filesystem.php
│ │ └── Platform.php
│ ├── FilesystemInterface.php
│ ├── Joomla
│ │ ├── Filesystem.php
│ │ └── Platform.php
│ └── PlatformInterface.php
├── Render
│ ├── FEF.php
│ ├── Joomla.php
│ ├── Joomla3.php
│ ├── Joomla4.php
│ ├── RenderBase.php
│ └── RenderInterface.php
├── Template
│ └── Template.php
├── Timer
│ └── Timer.php
├── Toolbar
│ ├── Exception
│ │ ├── MissingAttribute.php
│ │ └── UnknownButtonType.php
│ └── Toolbar.php
├── TransparentAuthentication
│ └── TransparentAuthentication.php
├── Update
│ ├── Collection.php
│ ├── Extension.php
│ ├── Joomla.php
│ └── Update.php
├── Utils
│ ├── ArrayHelper.php
│ ├── Buffer.php
│ ├── CliSessionHandler.php
│ ├── Collection.php
│ ├── FilesCheck.php
│ ├── MediaVersion.php
│ ├── ModelTypeHints.php
│ ├── ViewManifestMigration.php
│ └── helpers.php
├── View
│ ├── Compiler
│ │ ├── Blade.php
│ │ └── CompilerInterface.php
│ ├── DataView
│ │ ├── Csv.php
│ │ ├── DataViewInterface.php
│ │ ├── Html.php
│ │ ├── Json.php
│ │ └── Raw.php
│ ├── Engine
│ │ ├── AbstractEngine.php
│ │ ├── BladeEngine.php
│ │ ├── CompilingEngine.php
│ │ ├── EngineInterface.php
│ │ └── PhpEngine.php
│ ├── Exception
│ │ ├── AccessForbidden.php
│ │ ├── CannotGetName.php
│ │ ├── EmptyStack.php
│ │ ├── ModelNotFound.php
│ │ ├── PossiblySuhosin.php
│ │ └── UnrecognisedExtension.php
│ ├── View.php
│ └── ViewTemplateFinder.php
├── ViewTemplates
│ └── Common
│ │ ├── browse.fef.blade.php
│ │ ├── edit.fef.blade.php
│ │ ├── user_select.j3.blade.php
│ │ ├── user_select.j3.fef.blade.php
│ │ ├── user_select.j4.blade.php
│ │ ├── user_select.j4.fef.blade.php
│ │ └── user_show.fef.blade.php
├── language
│ └── index.html
├── script.fof.php
├── sql
│ ├── mysql.xml
│ ├── postgresql.xml
│ └── sqlsrv.xml
└── web.config
├── icon.png
├── phpunit-5.phar
├── phpunit.xml
├── plugins
└── user
│ └── foftoken
│ ├── .htaccess
│ ├── fields
│ ├── fancyradio.php
│ └── fofencryptedtoken.php
│ ├── foftoken.php
│ ├── foftoken.xml
│ ├── foftoken
│ └── foftoken.xml
│ ├── language
│ └── .gitinclude
│ ├── script.php
│ └── web.config
├── rector.php
└── translations
├── library
└── fof
│ └── en-GB
│ └── en-GB.lib_fof40.ini
└── plugins
└── user
└── foftoken
└── en-GB
├── en-GB.plg_user_foftoken.ini
└── en-GB.plg_user_foftoken.sys.ini
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Set the default behavior, in case people don't have core.autocrlf set.
2 | * text eol=lf
3 |
4 | # Explicitly declare text files you want to always be normalized and converted
5 | # to native line endings on checkout.
6 | *.php text eol=lf
7 | *.phps text eol=lf
8 | *.inc text eol=lf
9 | *.js text eol=lf
10 | *.css text eol=lf
11 | *.ini text eol=lf
12 | *.json text eol=lf
13 | *.htm text eol=lf
14 | *.html text eol=lf
15 | *.xml text eol=lf
16 | *.xslt text eol=lf
17 | *.svg text eol=lf
18 | *.txt text eol=lf
19 | *.md text eol=lf
20 | *.sh text eol=lf
21 | CHANGELOG text eol=lf
22 | README text eol=lf
23 | RELEASENOTES text eol=lf
24 |
25 | # Declare files that will always have CRLF line endings on checkout.
26 | *.sln text eol=crlf
27 |
28 | # Denote all files that are truly binary and should not be modified.
29 | *.acorn binary
30 | *.png binary
31 | *.jpg binary
32 | *.jpeg binary
33 | *.z binary
34 | *.gif binary
35 | *.jpa binary
36 | *.jps binary
37 | *.zip binary
38 | *.dll binary
39 | *.exe binary
40 | *.jar binary
41 | *.phar binary
42 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | ### phpStorm
2 | .idea/webServers.xml
3 | .idea/sshConfigs.xml
4 | .idea/dataSources.xml
5 |
6 | ### Composer
7 | # We can't include composer.lock since the testing framework dependencies vary by PHP version we are testing against
8 | composer.lock
9 | # The dependencies folder itself
10 | /vendor/
11 |
12 | ### Automatically generated files
13 | # Library loader
14 | /fof/include.php
15 | /fof/file_fof40.xml
16 | /fof/version.txt
17 | # Internal language symlinks
18 | /fof/language/en-GB
19 | /plugins/user/foftoken/language/**
20 |
21 | ### Release packages
22 | /release/*.zip
23 |
24 | ### Test files
25 | # Temporary Joomla! installations, used by Travis CI
26 | /Tests/environments/**
27 | # Test coverage output files
28 | /Tests/coverage
29 | # Tests configuration
30 | /Tests/config.php
31 | # Log file, used when running tests under Travis CI
32 | /Tests/debug.txt
33 |
--------------------------------------------------------------------------------
/.gitmodules:
--------------------------------------------------------------------------------
1 | [submodule "Tests/environments/staging"]
2 | path = Tests/environments/staging
3 | url = git@github.com:joomla/joomla-cms.git
4 | branch = staging
5 |
--------------------------------------------------------------------------------
/.idea/.gitignore:
--------------------------------------------------------------------------------
1 | # Default ignored files
2 | /shelf/
3 | /workspace.xml
4 | # Datasource local storage ignored files
5 | /dataSources/
6 | /dataSources.local.xml
7 | # Editor-based HTTP Client requests
8 | /httpRequests/
9 |
--------------------------------------------------------------------------------
/.idea/.name:
--------------------------------------------------------------------------------
1 | FOF 4
--------------------------------------------------------------------------------
/.idea/FOF 4.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/.idea/codeStyleSettings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/codeStyles/Project.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/.idea/codeStyles/codeStyleConfig.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/.idea/composerJson.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/.idea/copyright/FOF.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/.idea/copyright/profiles_settings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/.idea/cssxfire.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/.idea/deployment.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/.idea/dictionaries/nicholas.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/.idea/encodings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/inspectionProfiles/Project_Default.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/.idea/libraries/Generated_files.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/.idea/markdown.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/.idea/phing.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 | $USER_HOME$/.composer/vendor/bin/phing
14 |
15 |
--------------------------------------------------------------------------------
/.idea/php-test-framework.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/.idea/php.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/.idea/phpunit.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/.idea/scopes/Copyright.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/.idea/scopes/Plugin_CSS_Files.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/.idea/scopes/Plugin_JS_Files.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/.idea/scopes/scope_settings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/.idea/sqldialects.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | sudo: false
2 |
3 | git:
4 | submodules: false
5 |
6 | language: php
7 | php:
8 | - 8.0
9 | - 7.4
10 | - 7.3
11 | - 7.2
12 |
13 | env:
14 | - JVERSION_TEST=staging
15 |
16 | matrix:
17 | fast_finish: true
18 | allow_failures:
19 | - php: 8.0
20 |
21 | branches:
22 | only:
23 | - development
24 | - feature/fof4
25 | - debug-travis
26 |
27 | before_install:
28 | - git clone -b "$JVERSION_TEST" https://github.com/joomla/joomla-cms.git Tests/environments/"$JVERSION_TEST"
29 |
30 | install:
31 | - composer selfupdate
32 | - composer install
33 |
34 | before_script:
35 | - mysql -u root -e 'create database fof_test;'
36 | - mysql -u root -e "CREATE USER 'fof_db'@'localhost' IDENTIFIED BY 'fof';"
37 | - mysql -u root -e "GRANT ALL PRIVILEGES ON fof_test.* TO 'fof_db'@'%' IDENTIFIED BY 'fof';"
38 | - mysql -u root -e "GRANT ALL PRIVILEGES ON fof_test.* TO 'fof_db'@'localhost' IDENTIFIED BY 'fof';"
39 | - mysql -u root -e 'FLUSH PRIVILEGES;'
40 |
41 | after_script:
42 | - cat Tests/debug.txt
43 |
44 | notifications:
45 | email: false
46 |
--------------------------------------------------------------------------------
/DESCRIPTION.html:
--------------------------------------------------------------------------------
1 |
2 | Maintenance release.
3 |
--------------------------------------------------------------------------------
/RELEASENOTES.html:
--------------------------------------------------------------------------------
1 |
2 | We regularly release new versions of FOF to fix known issues and introduce new features. You can find
3 | an overview of this version's changes below.
4 |
--------------------------------------------------------------------------------
/TODO.txt:
--------------------------------------------------------------------------------
1 | [ ] Refactor classes to include parameter and return value type hints
2 | [ ] View
3 | [ ] Engine/
4 | [ ] DataView/
5 | [ ] View
6 | [ ] ViewTemplateFinder
7 | [ ] Model
8 |
9 |
10 | [ ] Encrypt: unit test EncryptService
11 |
12 | [ ] Encrypt: can I add Sodium support to replace the defunct mcrypt support?
13 |
14 | [ ] Each renderer should add FEF extensions for the following elements:
15 |
16 | * `@sortgrid`
17 | * `@filedtitle`
18 | * `@modelfilter`
19 | * `@selectfilter`
20 | * `@searchfilter`
21 |
22 | The default implementation can go through JHtml, I guess?
23 |
24 |
25 | [ ] MAYBE Blade keywords for common form elements, e.g @startEditWrapper / @endEditWrapper, @label, @startEditField / @endEditField, @checkBoxField -- defined by each Renderer
26 |
27 |
28 | [ ] Rewrite scaffolding (Layout) to produce Blade templates
--------------------------------------------------------------------------------
/Tests/Configuration/ConfigurationTest.php:
--------------------------------------------------------------------------------
1 |
15 | * @covers FOF40\Configuration\Configuration::
16 | */
17 | class ConfigurationTest extends FOFTestCase
18 | {
19 | /** @var array The data returned from parsing the XML file, used to test fetching data */
20 | protected $data = [];
21 |
22 | /**
23 | * @return void
24 | */
25 | protected function setUp()
26 | {
27 | self::$container->backEndPath = realpath(__DIR__ . '/../_data/configuration');
28 | }
29 |
30 | /**
31 | * @covers FOF40\Configuration\Configuration::__construct
32 | * @covers FOF40\Configuration\Configuration::parseComponent
33 | * @covers FOF40\Configuration\Configuration::parseComponentArea
34 | * @covers FOF40\Configuration\Configuration::getDomains
35 | * @covers FOF40\Configuration\Configuration::get
36 | *
37 | * @return void
38 | */
39 | public function testConstructor()
40 | {
41 | $x = self::$container->appConfig;
42 |
43 | $this->assertInstanceOf('\\FOF40\\Configuration\\Configuration', $x, 'Configuration object must be of correct type');
44 |
45 | $actual = $x->get('models.Orders.field.enabled', null);
46 |
47 | $this->assertEquals('published', $actual, 'get() must return valid domain data');
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/Tests/Event/ObserverTest.php:
--------------------------------------------------------------------------------
1 | dispatcher);
27 |
28 | $this->assertEquals($dummy, self::$attachArguments);
29 | $this->assertEquals($this->dispatcher, ReflectionHelper::getValue($dummy, 'subject'));
30 | }
31 |
32 | public function testGetObservableEvents()
33 | {
34 | $dummy = new FirstObserver($this->dispatcher);
35 |
36 | $observableEvents = $dummy->getObservableEvents();
37 |
38 | $this->assertEquals([
39 | 'returnConditional',
40 | 'identifyYourself',
41 | 'chain',
42 | ], $observableEvents);
43 | }
44 |
45 | protected function setUp()
46 | {
47 | $this->dispatcher = $this->getMockBuilder('\\FOF40\\Event\\Observable')
48 | ->disableOriginalConstructor()
49 | ->setMethods(['attach', 'detach', 'trigger'])
50 | ->getMock();
51 |
52 | $this->dispatcher
53 | ->method('attach')
54 | ->will($this->returnCallback(function ($arg) {
55 | ObserverTest::$attachArguments = $arg;
56 | }));
57 |
58 | $this->dispatcher
59 | ->method('detach')
60 | ->willReturnSelf();
61 |
62 | $this->dispatcher
63 | ->method('trigger')
64 | ->willReturn([]);
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/Tests/Factory/Magic/BaseFactoryTest.php:
--------------------------------------------------------------------------------
1 |
16 | * @covers FOF40\Factory\Magic\BaseFactory::
17 | * @package FOF40\Tests\Factory
18 | */
19 | class BaseFactoryTest extends FOFTestCase
20 | {
21 | /**
22 | * @covers FOF40\Factory\Magic\BaseFactory::__construct
23 | */
24 | public function test__construct()
25 | {
26 | $container = static::$container;
27 |
28 | $factory = $this->getMockForAbstractClass('FOF40\Factory\Magic\BaseFactory', [$container]);
29 |
30 | $this->assertSame($container, ReflectionHelper::getValue($factory, 'container'));
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/Tests/Helpers/Application/AppWithLanguageFilter.php:
--------------------------------------------------------------------------------
1 | languageFilter = $filter;
18 | }
19 |
20 | public function getLanguageFilter()
21 | {
22 | return $this->languageFilter;
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/Tests/Helpers/Application/MockApplicationCli.php:
--------------------------------------------------------------------------------
1 | getMockBuilder('\Joomla\CMS\Application\CliApplication')
55 | ->setMethods($methods)
56 | ->setConstructorArgs([])
57 | ->setMockClassName('')
58 | ->getMock();
59 |
60 | $mockObject = self::addBehaviours($test, $mockObject, $options);
61 |
62 | return $mockObject;
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/Tests/Helpers/Application/MockDocument.php:
--------------------------------------------------------------------------------
1 | getMockBuilder('\Joomla\CMS\Document\Document')
35 | ->setMethods($methods)
36 | ->setConstructorArgs([])
37 | ->setMockClassName('')
38 | ->disableOriginalConstructor()
39 | ->getMock();
40 |
41 | // Mock selected methods.
42 | $test->assignMockReturns(
43 | $mockObject, [
44 | 'parse' => $mockObject,
45 | // An additional 'test' method for confirming this object is successfully mocked.
46 | 'test' => 'ok',
47 | ]
48 | );
49 |
50 | return $mockObject;
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/Tests/Helpers/ApplicationTestCase.php:
--------------------------------------------------------------------------------
1 | platform;
31 |
32 | if ($platform instanceof TestJoomlaPlatform)
33 | {
34 | $platform->reset();
35 | }
36 |
37 | static::$container = null;
38 | }
39 |
40 | public static function rebuildContainer()
41 | {
42 | static::$container = null;
43 | static::$container = new TestContainer([
44 | 'componentName' => 'com_fakeapp',
45 | ]);
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/Tests/Helpers/ClosureHelper.php:
--------------------------------------------------------------------------------
1 | function(){ return 'Foobar'; }
21 | * )
22 | *
23 | * @param array $methods
24 | */
25 | public function __construct(array $methods = [])
26 | {
27 | foreach ($methods as $method => $function)
28 | {
29 | $this->mockedMethods[$method] = $function;
30 | }
31 | }
32 |
33 | public function __call($method, $args)
34 | {
35 | if (isset($this->mockedMethods[$method]))
36 | {
37 | $func = $this->mockedMethods[$method];
38 |
39 | // Let's pass an instance of ourselves, so we can manipulate other closures
40 | array_unshift($args, $this);
41 |
42 | return call_user_func_array($func, $args);
43 | }
44 |
45 | return null;
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/Tests/Helpers/Download/FakeBase.php:
--------------------------------------------------------------------------------
1 | allowedAuths);
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/Tests/Helpers/TestContainer.php:
--------------------------------------------------------------------------------
1 | contents.
16 | * Example:
17 | *
18 | * $paths = array(
19 | * 'administrator/components/com_foftest/views/bare',
20 | * 'administrator/components/com_foftest/views/bares',
21 | * 'administrator/components/com_foftest/views/foobar',
22 | * 'administrator/components/com_foftest/views/foobars/metadata.xml'
23 | * );
24 | *
25 | * $contents = array(
26 | * 'metadata.xml' => 'your content goes here'
27 | * );
28 | *
29 | * @param array $paths
30 | * @param array $contents
31 | *
32 | * @return array
33 | */
34 | public static function createArrayDir($paths, $contents = [])
35 | {
36 | $tree = [];
37 |
38 | foreach ($paths as $path)
39 | {
40 | $pathParts = explode('/', $path);
41 | $subTree = [array_pop($pathParts)];
42 |
43 | if (strpos($subTree[0], '.') !== false)
44 | {
45 | $content = '';
46 |
47 | if (isset($contents[$subTree[0]]))
48 | {
49 | $content = $contents[$subTree[0]];
50 | }
51 |
52 | $subTree = [$subTree[0] => $content];
53 | }
54 | else
55 | {
56 | $subTree = [$subTree[0] => []];
57 | }
58 |
59 | foreach (array_reverse($pathParts) as $dir)
60 | {
61 | $subTree = [$dir => $subTree];
62 | }
63 |
64 | $tree = array_merge_recursive($tree, $subTree);
65 | }
66 |
67 | return $tree;
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/Tests/IP/IPHelperTest.php:
--------------------------------------------------------------------------------
1 |
18 | * @covers \FOF40\IP\IPHelper::
19 | */
20 | class IPHelperTest extends FOFTestCase
21 | {
22 | /**
23 | * @group Ip
24 | * @dataProvider \FOF40\Tests\IP\IpDataprovider::getDetectAndCleanIP
25 | */
26 | public function testDetectAndCleanIP($test, $check)
27 | {
28 | $msg = 'Ip::detectIP %s - Case: ' . $check['case'];
29 |
30 | $ip = new IpStub();
31 |
32 | $ip::$fakeIP = $test['fakeIP'];
33 | $ip::setUseFirstIpInChain($test['useFirst']);
34 |
35 | $result = $ip::detectAndCleanIP();
36 |
37 | $this->assertEquals($check['result'], $result, $msg);
38 | }
39 | }
40 |
41 |
--------------------------------------------------------------------------------
/Tests/Layout/LayoutFileTestProvider.php:
--------------------------------------------------------------------------------
1 | ['.fof'],
21 | 'template' => 'system',
22 | 'baseDirs' => [
23 | 'root' => realpath(__DIR__ . '/../_data/layout'),
24 | 'public' => realpath(__DIR__ . '/../_data/layout'),
25 | 'admin' => realpath(__DIR__ . '/../_data/layout/administrator'),
26 | 'tmp' => JoomlaFactory::getConfig()->get('tmp_path'),
27 | 'log' => JoomlaFactory::getConfig()->get('tmp_path'),
28 | ],
29 | ];
30 |
31 | // $layoutId, $platformSetup, $expectedPath, $message
32 | return [
33 | ['test.foo', $platformSetup, $fakeBase . '/test/foo.php', 'Getting a simple layout'],
34 | [
35 | 'test.bar', $platformSetup, $fakeBase . '/test/bar.fof.php',
36 | 'Getting a simple layout with platform extension',
37 | ],
38 | [
39 | 'test.overridden', $platformSetup, $templateBase . '/test/overridden.php',
40 | 'Getting a simple overridden layout without platform extension',
41 | ],
42 | [
43 | 'test.baz', $platformSetup, $templateBase . '/test/baz.fof.php',
44 | 'Getting a simple overridden layout with a platform extension',
45 | ],
46 | [
47 | 'test.bat', $platformSetup, $fakeBase . '/test/bat.fof.php',
48 | 'Platform extension has priority over template override without platform extension',
49 | ],
50 | ];
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/Tests/Layout/LayoutHelperTestProvider.php:
--------------------------------------------------------------------------------
1 | ['.fof'],
24 | 'template' => 'system',
25 | 'baseDirs' => [
26 | 'root' => realpath(__DIR__ . '/../_data/layout'),
27 | 'public' => realpath(__DIR__ . '/../_data/layout'),
28 | 'admin' => realpath(__DIR__ . '/../_data/layout/administrator'),
29 | 'tmp' => JoomlaFactory::getConfig()->get('tmp_path'),
30 | 'log' => JoomlaFactory::getConfig()->get('tmp_path'),
31 | ],
32 | ];
33 |
34 | // $layoutId, $platformSetup, $expectedPath, $message
35 | return [
36 | ['test.foo', $platformSetup, 'FOO', 'Getting a simple layout'],
37 | ['test.bar', $platformSetup, 'BAR.FOF', 'Getting a simple layout with platform extension'],
38 | [
39 | 'test.overridden', $platformSetup, 'OVERRIDDEN',
40 | 'Getting a simple overridden layout without platform extension',
41 | ],
42 | ['test.baz', $platformSetup, 'BAZ.FOF', 'Getting a simple overridden layout with a platform extension'],
43 | [
44 | 'test.bat', $platformSetup, 'BAT.FOF',
45 | 'Platform extension has priority over template override without platform extension',
46 | ],
47 | ];
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/Tests/Model/DataModel/Behaviour/AccessDataprovider.php:
--------------------------------------------------------------------------------
1 | 'foftest_bare_id',
16 | 'table' => '#__foftest_bares',
17 | ],
18 | [
19 | 'access' => false,
20 | ],
21 | ];
22 |
23 | $data[] = [
24 | [
25 | 'tableid' => 'foftest_foobar_id',
26 | 'table' => '#__foftest_foobars',
27 | ],
28 | [
29 | 'access' => true,
30 | ],
31 | ];
32 |
33 | return $data;
34 | }
35 |
36 | public static function getTestOnAfterLoad()
37 | {
38 | // DataModel has not the access field
39 | $data[] = [
40 | [
41 | 'tableid' => 'foftest_bare_id',
42 | 'table' => '#__foftest_bares',
43 | 'mock' => [
44 | 'userAccess' => '',
45 | 'access' => '',
46 | ],
47 | ],
48 | [
49 | 'reset' => false,
50 | ],
51 | ];
52 |
53 | // User has access to the data
54 | $data[] = [
55 | [
56 | 'tableid' => 'foftest_foobar_id',
57 | 'table' => '#__foftest_foobars',
58 | 'mock' => [
59 | 'userAccess' => [10, 5, 1],
60 | 'access' => 10,
61 | ],
62 | ],
63 | [
64 | 'reset' => false,
65 | ],
66 | ];
67 |
68 | // No access
69 | $data[] = [
70 | [
71 | 'tableid' => 'foftest_foobar_id',
72 | 'table' => '#__foftest_foobars',
73 | 'mock' => [
74 | 'userAccess' => [5, 1],
75 | 'access' => 10,
76 | ],
77 | ],
78 | [
79 | 'reset' => true,
80 | ],
81 | ];
82 |
83 | return $data;
84 | }
85 | }
86 |
--------------------------------------------------------------------------------
/Tests/Model/DataModel/Behaviour/ContentHistoryDataprovider.php:
--------------------------------------------------------------------------------
1 | [
15 | 'save_history' => 1,
16 | ],
17 | 'check' => [
18 | 'case' => 'Component enables history saving',
19 | 'store' => 1,
20 | ],
21 | ];
22 |
23 | $data[] = [
24 | 'input' => [
25 | 'save_history' => 0,
26 | ],
27 | 'check' => [
28 | 'case' => 'Component does not enable history saving',
29 | 'store' => 0,
30 | ],
31 | ];
32 |
33 | return $data;
34 | }
35 |
36 | public static function getTestOnBeforeDelete()
37 | {
38 | $data[] = [
39 | 'input' => [
40 | 'save_history' => 1,
41 | ],
42 | 'check' => [
43 | 'case' => 'Component enables history saving',
44 | 'delete' => 1,
45 | ],
46 | ];
47 |
48 | $data[] = [
49 | 'input' => [
50 | 'save_history' => 0,
51 | ],
52 | 'check' => [
53 | 'case' => 'Component does not enable history saving',
54 | 'delete' => 0,
55 | ],
56 | ];
57 |
58 | return $data;
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/Tests/Model/DataModel/Behaviour/EnabledDataprovider.php:
--------------------------------------------------------------------------------
1 | '#__foftest_bares',
16 | 'tableid' => 'foftest_bare_id',
17 | ],
18 | [
19 | 'case' => 'Table without enabled field',
20 | 'count' => 0,
21 | ],
22 | ];
23 |
24 | $data[] = [
25 | [
26 | 'table' => '#__foftest_foobars',
27 | 'tableid' => 'foftest_foobar_id',
28 | ],
29 | [
30 | 'case' => 'Table with enabled field',
31 | 'count' => 1,
32 | ],
33 | ];
34 |
35 | return $data;
36 | }
37 |
38 | public static function getTestOnAfterLoad()
39 | {
40 | // DataModel has not the enabled field
41 | $data[] = [
42 | [
43 | 'tableid' => 'foftest_bare_id',
44 | 'table' => '#__foftest_bares',
45 | 'mock' => [
46 | 'enabled' => 0,
47 | ],
48 | ],
49 | [
50 | 'reset' => false,
51 | ],
52 | ];
53 |
54 | // Enabled
55 | $data[] = [
56 | [
57 | 'tableid' => 'foftest_foobar_id',
58 | 'table' => '#__foftest_foobars',
59 | 'mock' => [
60 | 'enabled' => 1,
61 | ],
62 | ],
63 | [
64 | 'reset' => false,
65 | ],
66 | ];
67 |
68 | // Not enabled
69 | $data[] = [
70 | [
71 | 'tableid' => 'foftest_foobar_id',
72 | 'table' => '#__foftest_foobars',
73 | 'mock' => [
74 | 'enabled' => 0,
75 | ],
76 | ],
77 | [
78 | 'reset' => true,
79 | ],
80 | ];
81 |
82 | return $data;
83 | }
84 | }
85 |
--------------------------------------------------------------------------------
/Tests/Model/DataModel/Behaviour/OwnDataprovider.php:
--------------------------------------------------------------------------------
1 | 'foftest_foobar_id',
16 | 'table' => '#__foftest_foobars',
17 | ],
18 | [
19 | 'case' => 'Table with created_by column',
20 | 'contains' => true,
21 | 'query' => "`created_by` = '99'",
22 | ],
23 | ];
24 |
25 | $data[] = [
26 | [
27 | 'tableid' => 'foftest_bare_id',
28 | 'table' => '#__foftest_bares',
29 | ],
30 | [
31 | 'case' => 'Table without created_by column',
32 | 'contains' => false,
33 | 'query' => "`created_by` = '99'",
34 | ],
35 | ];
36 |
37 | return $data;
38 | }
39 |
40 | public static function getTestOnAfterLoad()
41 | {
42 | // DataModel has not the created_by field
43 | $data[] = [
44 | [
45 | 'tableid' => 'foftest_bare_id',
46 | 'table' => '#__foftest_bares',
47 | 'mock' => [
48 | 'created_by' => '',
49 | ],
50 | ],
51 | [
52 | 'reset' => false,
53 | ],
54 | ];
55 |
56 | // User has access to the data
57 | $data[] = [
58 | [
59 | 'tableid' => 'foftest_foobar_id',
60 | 'table' => '#__foftest_foobars',
61 | 'mock' => [
62 | 'created_by' => 99,
63 | ],
64 | ],
65 | [
66 | 'reset' => false,
67 | ],
68 | ];
69 |
70 | // No access
71 | $data[] = [
72 | [
73 | 'tableid' => 'foftest_foobar_id',
74 | 'table' => '#__foftest_foobars',
75 | 'mock' => [
76 | 'created_by' => 10,
77 | ],
78 | ],
79 | [
80 | 'reset' => true,
81 | ],
82 | ];
83 |
84 | return $data;
85 | }
86 | }
87 |
--------------------------------------------------------------------------------
/Tests/Model/DataModel/Filter/BooleanDataprovider.php:
--------------------------------------------------------------------------------
1 | '',
16 | ],
17 | [
18 | 'case' => 'Empty string',
19 | 'result' => true,
20 | ],
21 | ];
22 |
23 | $data[] = [
24 | [
25 | 'value' => 123,
26 | ],
27 | [
28 | 'case' => 'Integers',
29 | 'result' => false,
30 | ],
31 | ];
32 |
33 | $data[] = [
34 | [
35 | 'value' => [],
36 | ],
37 | [
38 | 'case' => 'Empty array',
39 | 'result' => false,
40 | ],
41 | ];
42 |
43 | $data[] = [
44 | [
45 | 'value' => new stdClass(),
46 | ],
47 | [
48 | 'case' => 'Object',
49 | 'result' => false,
50 | ],
51 | ];
52 |
53 | $data[] = [
54 | [
55 | 'value' => null,
56 | ],
57 | [
58 | 'case' => 'Null value',
59 | 'result' => true,
60 | ],
61 | ];
62 |
63 | return $data;
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/Tests/Model/DataModel/Filter/BooleanTest.php:
--------------------------------------------------------------------------------
1 |
19 | * @covers FOF40\Model\DataModel\Filter\Boolean::
20 | * @package FOF40\Tests\DataModel\Filter\Boolean
21 | */
22 | class BooleanTest extends DatabaseTest
23 | {
24 | /**
25 | * @group BooleanFilter
26 | * @group BooleanFilterIsEmpty
27 | * @covers FOF40\Model\DataModel\Filter\Boolean::isEmpty
28 | * @dataProvider BooleanDataprovider::getTestIsEmpty
29 | */
30 | public function testIsEmpty($test, $check)
31 | {
32 | $msg = 'Boolean::isEmpty %s - Case: ' . $check['case'];
33 | $filter = new Boolean(JoomlaFactory::getDbo(), (object) ['name' => 'test', 'type' => 'tinyint(1)']);
34 |
35 | $result = $filter->isEmpty($test['value']);
36 |
37 | $this->assertEquals($check['result'], $result, sprintf($msg, 'Failed to detect if a variable is empty'));
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/Tests/Model/DataModel/Filter/TextDataprovider.php:
--------------------------------------------------------------------------------
1 | '',
16 | ],
17 | [
18 | 'case' => 'Empty value',
19 | 'result' => '',
20 | ],
21 | ];
22 |
23 | $data[] = [
24 | [
25 | 'value' => 'foobar',
26 | ],
27 | [
28 | 'case' => 'Valid value',
29 | 'result' => "(`test` LIKE '%foobar%')",
30 | ],
31 | ];
32 |
33 | return $data;
34 | }
35 |
36 | public static function getTestExact()
37 | {
38 | $data[] = [
39 | [
40 | 'value' => '',
41 | ],
42 | [
43 | 'case' => 'Empty value',
44 | 'result' => '',
45 | ],
46 | ];
47 |
48 | $data[] = [
49 | [
50 | 'value' => 'foobar',
51 | ],
52 | [
53 | 'case' => 'Valid value',
54 | 'result' => "(`test` LIKE 'foobar')",
55 | ],
56 | ];
57 |
58 | return $data;
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/Tests/Model/DataModel/Relation/BelongsToDataprovider.php:
--------------------------------------------------------------------------------
1 | null,
16 | 'foreign' => null,
17 | ],
18 | [
19 | 'case' => 'Local and foreign keys not passed',
20 | 'local' => 'fakeapp_parent_id',
21 | 'foreign' => 'fakeapp_parent_id',
22 | ],
23 | ];
24 |
25 | $data[] = [
26 | [
27 | 'local' => 'local',
28 | 'foreign' => 'foreign',
29 | ],
30 | [
31 | 'case' => 'Local and foreign keys passed',
32 | 'local' => 'local',
33 | 'foreign' => 'foreign',
34 | ],
35 | ];
36 |
37 | $data[] = [
38 | [
39 | 'local' => 'local',
40 | 'foreign' => null,
41 | ],
42 | [
43 | 'case' => 'Local key passed, foreign key not passed',
44 | 'local' => 'local',
45 | 'foreign' => 'fakeapp_parent_id',
46 | ],
47 | ];
48 |
49 | $data[] = [
50 | [
51 | 'local' => null,
52 | 'foreign' => 'foreign',
53 | ],
54 | [
55 | 'case' => 'Local key not passed, foreign key passed',
56 | 'local' => 'fakeapp_parent_id',
57 | 'foreign' => 'foreign',
58 | ],
59 | ];
60 |
61 | return $data;
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/Tests/Model/DataModel/Relation/HasManyDataprovider.php:
--------------------------------------------------------------------------------
1 | null,
16 | 'foreign' => null,
17 | ],
18 | [
19 | 'case' => 'Local and foreign keys not supplied',
20 | 'local' => 'fakeapp_parent_id',
21 | 'foreign' => 'fakeapp_parent_id',
22 | ],
23 | ];
24 |
25 | $data[] = [
26 | [
27 | 'local' => 'local',
28 | 'foreign' => null,
29 | ],
30 | [
31 | 'case' => 'Local key supplied',
32 | 'local' => 'local',
33 | 'foreign' => 'local',
34 | ],
35 | ];
36 |
37 | $data[] = [
38 | [
39 | 'local' => null,
40 | 'foreign' => 'foreign',
41 | ],
42 | [
43 | 'case' => 'Foreign key supplied',
44 | 'local' => 'fakeapp_parent_id',
45 | 'foreign' => 'foreign',
46 | ],
47 | ];
48 |
49 | $data[] = [
50 | [
51 | 'local' => 'local',
52 | 'foreign' => 'foreign',
53 | ],
54 | [
55 | 'case' => 'Local and foreign keys supplied',
56 | 'local' => 'local',
57 | 'foreign' => 'foreign',
58 | ],
59 | ];
60 |
61 | return $data;
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/Tests/Model/DataModel/Relation/RelationDataprovider.php:
--------------------------------------------------------------------------------
1 | [
16 | 'filter' => true,
17 | 'data' => null,
18 | ],
19 | ],
20 | [
21 | 'case' => 'Data is filtered',
22 | 'applyCallback' => true,
23 | 'count' => 3,
24 | ],
25 | ];
26 |
27 | $data[] = [
28 | [
29 | 'mock' => [
30 | 'filter' => false,
31 | 'data' => null,
32 | ],
33 | ],
34 | [
35 | 'case' => 'Data is not filtered',
36 | 'applyCallback' => false,
37 | 'count' => 0,
38 | ],
39 | ];
40 |
41 | $data[] = [
42 | [
43 | 'mock' => [
44 | 'filter' => true,
45 | 'data' => new \FOF40\Model\DataModel\Collection([1]),
46 | ],
47 | ],
48 | [
49 | 'case' => 'Data fetched from the internal cache',
50 | 'applyCallback' => false,
51 | 'count' => 1,
52 | ],
53 | ];
54 |
55 | return $data;
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/Tests/README.md:
--------------------------------------------------------------------------------
1 | # Running tests
2 | In order to run the tests, you have to configure your environment:
3 |
4 | 1. Create a database for the tests
5 | 2. Install required libraries with Composer
6 |
7 | ### Create a database for the tests
8 |
9 | We need a database where we will create all the tables required by the tests.
10 | The best thing is to provide an empty database, the test suite will create all the needed tables.
11 |
12 | Once created, you have to copy the file `Tests/config.dist.php`, rename it to `Tests/config.php` and update its contents to point to the created database.
13 |
14 | For local testing (not using Travis CI) you need to put the latest Joomla! staging files somewhere and update the `site_root` line in your `Tests/config.php` file to point there. You do not need to install Joomla on that folder, this is automatically detected and done as part of the tests.
15 |
16 | ### Install required libraries with Composer
17 |
18 | You simply have to run `composer install` in order to install all the required libraries. If you want to update the composer dependencies, run `composer update`. Composer is not bundled in the repo.
19 |
20 | ### How to run tests
21 |
22 | From the `Tests` folder run
23 | ```bash
24 | ../vendor/bin/phpunit -c ../phpunit.xml
25 | ```
26 |
--------------------------------------------------------------------------------
/Tests/Stubs/Controller/DataControllerStub.php:
--------------------------------------------------------------------------------
1 | function(){ return 'Foobar'; }
25 | * )
26 | *
27 | * @param $container
28 | * @param array $config
29 | * @param array $methods
30 | */
31 | public function __construct(Container $container, array $config = [], array $methods = [])
32 | {
33 | foreach ($methods as $method => $function)
34 | {
35 | $this->mockedMethods[$method] = $function;
36 | }
37 |
38 | parent::__construct($container, $config);
39 | }
40 |
41 | public function __call($method, $args)
42 | {
43 | if (isset($this->mockedMethods[$method]))
44 | {
45 | $func = $this->mockedMethods[$method];
46 |
47 | // Let's pass an instance of ourself, so we can manipulate other closures
48 | array_unshift($args, $this);
49 |
50 | return call_user_func_array($func, $args);
51 | }
52 | }
53 |
54 | /**
55 | * A mocked object will have a random name, that won't match the regex expression in the parent.
56 | * To prevent exceptions, we have to manually set the name
57 | *
58 | * @return string
59 | */
60 | public function getName(): string
61 | {
62 | if (isset($this->mockedMethods['getName']))
63 | {
64 | $func = $this->mockedMethods['getName'];
65 |
66 | return call_user_func_array($func, []);
67 | }
68 |
69 | return parent::getName();
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/Tests/Stubs/Dummyapp/Admin/fof.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 |
11 |
12 | read
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/Tests/Stubs/Event/FirstObserver.php:
--------------------------------------------------------------------------------
1 | myId);
20 | }
21 |
22 | public function identifyYourself()
23 | {
24 | return $this->myId;
25 | }
26 |
27 | public function chain($stuff)
28 | {
29 | if ($stuff == $this->myId)
30 | {
31 | return $this->myId;
32 | }
33 |
34 | return null;
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/Tests/Stubs/Event/SecondObserver.php:
--------------------------------------------------------------------------------
1 | myId = 'two';
20 | }
21 |
22 | public function onlySecond()
23 | {
24 | return 'only second';
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/Tests/Stubs/Fakeapp/Admin/Controller/Bare.php:
--------------------------------------------------------------------------------
1 |
6 |
7 |
--------------------------------------------------------------------------------
/Tests/Stubs/Fakeapp/Site/Controller/DefaultDataController.php:
--------------------------------------------------------------------------------
1 | 'First item',
36 | 'second' => 'Second item',
37 | '1' => 'JYES',
38 | '0' => 'JNO',
39 | ];
40 |
41 | return $options;
42 | }
43 |
44 | /**
45 | * This method is used in {@link GenericListTest::testGetOptions} to test fetching the options
46 | * from a class method
47 | */
48 | public static function getOptionsWithKeys()
49 | {
50 | $options = [
51 | ['value' => 'first', 'text' => 'First item'],
52 | ['value' => 'second', 'text' => 'Second item'],
53 | ];
54 |
55 | return $options;
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/Tests/Stubs/Fakeapp/Site/Model/Groups.php:
--------------------------------------------------------------------------------
1 | 'First item',
35 | 'second' => 'Second item',
36 | ];
37 |
38 | return $options;
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/Tests/Stubs/Joomla/JToolbarHelper.php:
--------------------------------------------------------------------------------
1 | value = $value;
40 |
41 | return $service;
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/Tests/Stubs/Pimple/NonInvokable.php:
--------------------------------------------------------------------------------
1 |
36 | */
37 | class Service
38 | {
39 | public $value;
40 | }
41 |
--------------------------------------------------------------------------------
/Tests/Stubs/Session/FakeSession.php:
--------------------------------------------------------------------------------
1 | id;
28 | }
29 |
30 | public function setId($id)
31 | {
32 | $this->id = $id;
33 | }
34 |
35 | public function getName()
36 | {
37 | return $this->name;
38 | }
39 |
40 | public function setName($name)
41 | {
42 | return $this->name;
43 | }
44 |
45 | public function regenerate($destroy = false, $lifetime = null)
46 | {
47 | return true;
48 | }
49 |
50 | public function save()
51 | {
52 | }
53 |
54 | public function clear()
55 | {
56 | }
57 | }
--------------------------------------------------------------------------------
/Tests/Stubs/Toolbar/ToolbarStub.php:
--------------------------------------------------------------------------------
1 | methodCounter['onFoobarsDummy']))
21 | {
22 | $this->methodCounter['onFoobarsDummy']++;
23 | }
24 | else
25 | {
26 | $this->methodCounter['onFoobarsDummy'] = 1;
27 | }
28 | }
29 |
30 | public function onViews()
31 | {
32 | if (isset($this->methodCounter['onViews']))
33 | {
34 | $this->methodCounter['onViews']++;
35 | }
36 | else
37 | {
38 | $this->methodCounter['onViews'] = 1;
39 | }
40 | }
41 |
42 | public function onTask()
43 | {
44 | if (isset($this->methodCounter['onTask']))
45 | {
46 | $this->methodCounter['onTask']++;
47 | }
48 | else
49 | {
50 | $this->methodCounter['onTask'] = 1;
51 | }
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/Tests/Stubs/Utils/IpStub.php:
--------------------------------------------------------------------------------
1 | function(){ return 'Foobar'; }
24 | * )
25 | *
26 | * @param $container
27 | * @param array $config
28 | * @param array $methods
29 | */
30 | public function __construct(Container $container, array $config = [], array $methods = [])
31 | {
32 | foreach ($methods as $method => $function)
33 | {
34 | $this->methods[$method] = $function;
35 | }
36 |
37 | parent::__construct($container, $config);
38 | }
39 |
40 | public function __call($method, $args)
41 | {
42 | if (isset($this->methods[$method]))
43 | {
44 | $func = $this->methods[$method];
45 |
46 | // Let's pass an instance of ourself, so we can manipulate other closures
47 | array_unshift($args, $this);
48 |
49 | return call_user_func_array($func, $args);
50 | }
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/Tests/View/DataView/RawDataprovider.php:
--------------------------------------------------------------------------------
1 | [
16 | 'isCli' => false,
17 | ],
18 | ],
19 | [
20 | 'case' => 'We are not in CLI',
21 | 'permissions' => (object) [
22 | 'create' => false,
23 | 'edit' => false,
24 | 'editown' => false,
25 | 'editstate' => false,
26 | 'delete' => false,
27 | ],
28 | ],
29 | ];
30 |
31 | $data[] = [
32 | [
33 | 'mock' => [
34 | 'isCli' => true,
35 | ],
36 | ],
37 | [
38 | 'case' => 'We are in CLI',
39 | 'permissions' => (object) [
40 | 'create' => true,
41 | 'edit' => true,
42 | 'editown' => true,
43 | 'editstate' => true,
44 | 'delete' => true,
45 | ],
46 | ],
47 | ];
48 |
49 | return $data;
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/Tests/_data/configuration/authentication.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 | thing
11 | bar
12 | NOPE
13 |
14 |
15 |
--------------------------------------------------------------------------------
/Tests/_data/configuration/container.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 | thing
11 | bar
12 | NOPE
13 |
14 |
15 |
--------------------------------------------------------------------------------
/Tests/_data/configuration/dispatcher.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 | thing
11 | bar
12 | NOPE
13 |
14 |
15 |
--------------------------------------------------------------------------------
/Tests/_data/configuration/models.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 |
11 | checked_out
12 | checked_out_time
13 | ping,pong
14 |
15 |
16 |
17 | published
18 |
19 |
27 |
28 | foo,bar,baz
29 |
30 |
31 | folks
32 | locked
33 | locked_on
34 | foo,bar,baz
35 |
36 |
--------------------------------------------------------------------------------
/Tests/_data/configuration/views.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 |
11 | browse
12 |
13 |
14 | foobar.something
15 |
16 |
17 |
18 |
19 |
20 |
21 | filter,access
22 |
23 |
24 |
25 |
26 | browse
27 |
28 |
29 |
30 | core.manage
31 |
32 |
33 | 3
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 | show
45 | read
46 |
47 |
48 | kot
49 | foo.bar
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 | read
61 |
62 |
63 |
--------------------------------------------------------------------------------
/Tests/_data/fake_test_template/html/com_foobar/css/test.css:
--------------------------------------------------------------------------------
1 | /**
2 | * @package FOF
3 | * @copyright Copyright (c)2010-2023 Nicholas K. Dionysopoulos / Akeeba Ltd
4 | * @license GNU General Public License version 3, or later
5 | */
6 |
7 | /* Only used for testing */
--------------------------------------------------------------------------------
/Tests/_data/fake_test_template/index.php:
--------------------------------------------------------------------------------
1 |
13 |
--------------------------------------------------------------------------------
/Tests/_data/fake_test_template/media/com_foobar/css/test.css:
--------------------------------------------------------------------------------
1 | /**
2 | * @package FOF
3 | * @copyright Copyright (c)2010-2023 Nicholas K. Dionysopoulos / Akeeba Ltd
4 | * @license GNU General Public License version 3, or later
5 | */
6 |
7 | /* Only used for testing */
--------------------------------------------------------------------------------
/Tests/_data/fake_test_template/media/com_foobar/js/test.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @package FOF
3 | * @copyright Copyright (c)2010-2023 Nicholas K. Dionysopoulos / Akeeba Ltd
4 | * @license GNU General Public License version 3, or later
5 | */
6 |
7 | /* Only used for testing */
--------------------------------------------------------------------------------
/Tests/_data/installer/pick_right/foobar.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 |
11 |
12 |
13 | foobar
14 |
15 |
16 |
17 |
18 |
19 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/Tests/_data/installer/pick_right/mysql.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 |
11 |
12 |
13 | mysql
14 | mysqli
15 | pdomysql
16 |
17 |
18 |
19 |
20 |
21 |
29 |
30 |
31 |
32 |
33 |
36 |
39 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/Tests/_data/installer/test_canfail.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 |
11 | mysql
12 | mysqli
13 | pdomysql
14 |
15 |
16 |
17 |
18 |
19 |
22 |
23 |
24 |
25 |
28 |
29 |
30 |
31 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/Tests/_data/installer/test_fail.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 |
11 | mysql
12 | mysqli
13 | pdomysql
14 |
15 |
16 |
17 |
18 |
19 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/Tests/_data/installer/test_type.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 |
11 | mysql
12 | mysqli
13 | pdomysql
14 |
15 |
16 |
17 |
18 |
19 |
20 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/Tests/_data/layout/layouts/test/bar.fof.php:
--------------------------------------------------------------------------------
1 | BAR.FOF
--------------------------------------------------------------------------------
/Tests/_data/layout/layouts/test/bat.fof.php:
--------------------------------------------------------------------------------
1 | BAT.FOF
--------------------------------------------------------------------------------
/Tests/_data/layout/layouts/test/foo.php:
--------------------------------------------------------------------------------
1 | FOO
--------------------------------------------------------------------------------
/Tests/_data/layout/layouts/test/overridden.php:
--------------------------------------------------------------------------------
1 | BORKED!
--------------------------------------------------------------------------------
/Tests/_data/layout/templates/system/html/layouts/test/bat.php:
--------------------------------------------------------------------------------
1 | LOL! NO, MAN!
--------------------------------------------------------------------------------
/Tests/_data/layout/templates/system/html/layouts/test/baz.fof.php:
--------------------------------------------------------------------------------
1 | BAZ.FOF
--------------------------------------------------------------------------------
/Tests/_data/layout/templates/system/html/layouts/test/overridden.php:
--------------------------------------------------------------------------------
1 | OVERRIDDEN
--------------------------------------------------------------------------------
/Tests/config.dist.php:
--------------------------------------------------------------------------------
1 | 'localhost',
12 | 'user' => 'root',
13 | 'password' => 'root',
14 | 'db' => 'unittesting3',
15 | 'site_root' => realpath(__DIR__ . '/environments/staging'),
16 | ];
17 |
--------------------------------------------------------------------------------
/Tests/config_travis.php:
--------------------------------------------------------------------------------
1 | '127.0.0.1',
12 | 'user' => 'fof_db',
13 | 'password' => 'fof',
14 | 'db' => 'fof_test',
15 | ];
16 |
--------------------------------------------------------------------------------
/Tests/environments.php:
--------------------------------------------------------------------------------
1 | realpath(__DIR__ . '/environments/staging'),
12 | ];
13 |
--------------------------------------------------------------------------------
/Tests/environments/.gitinclude:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/akeeba/fof/fccf97e3990aab96bcc8a9ac9ccbe476375f735e/Tests/environments/.gitinclude
--------------------------------------------------------------------------------
/Tests/tmp/index.html:
--------------------------------------------------------------------------------
1 |
6 |
7 |
--------------------------------------------------------------------------------
/assets/logo-100.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/akeeba/fof/fccf97e3990aab96bcc8a9ac9ccbe476375f735e/assets/logo-100.png
--------------------------------------------------------------------------------
/assets/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/akeeba/fof/fccf97e3990aab96bcc8a9ac9ccbe476375f735e/assets/logo.png
--------------------------------------------------------------------------------
/build/build.properties:
--------------------------------------------------------------------------------
1 | ;; =============================================================================
2 | ;; Non-privileged Phing properties for this project
3 | ;; =============================================================================
4 |
5 | ; ------------------------------------------------------------------------------
6 | ; Release setup
7 | ; ------------------------------------------------------------------------------
8 | ; Use the Akeeba Release Maker 2.0 YAML configuration file.
9 | release.method=yaml
10 |
11 | ; ------------------------------------------------------------------------------
12 | ; FTP deploy for dev releases
13 | ; ------------------------------------------------------------------------------
14 | ; FTP Deploy patterns
15 | ftpdeploy.pattern.core=lib*.zip
16 | ftpdeploy.pattern.pro=NOTHING
17 |
18 | ; FTP Deploy paths
19 | ftpdeploy.path.core=files/dev/fof4
20 | ftpdeploy.path.pro=files/dev/fof4
21 |
22 | ; ------------------------------------------------------------------------------
23 | ; FOF 3 compatible package building
24 | ; ------------------------------------------------------------------------------
25 | ; The name of the component, must be in the form something, NOT com_something!
26 | build.component=fof4
27 | ; Should I include a Self Check .php manifest in each component package?
28 | build.selfcheck=0
29 | ; Do you have a Core / Pro version? If this is 0 only the Core release will be built
30 | build.has_pro=0
31 | ; Do you have CLI script? If yes, a file_example package will be built for you
32 | build.has_cli=0
33 | ; Do not include Akeeba Strapper
34 | build.strapper=0
35 |
--------------------------------------------------------------------------------
/build/fakes/MasterFakeClass.php:
--------------------------------------------------------------------------------
1 | load('lib_fof40', JPATH_SITE, 'en-GB', true);
27 | JoomlaFactory::getLanguage()->load('lib_fof40', JPATH_SITE, null, true);
28 |
29 | // Register a debug log
30 | if (defined('JDEBUG') && JDEBUG && class_exists('\Joomla\CMS\Log\Log'))
31 | {
32 | Log::addLogger(array('text_file' => 'fof.log.php'), Log::ALL, array('fof'));
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/build/templates/link.php:
--------------------------------------------------------------------------------
1 | 'fof/language/en-GB',
14 | ];
--------------------------------------------------------------------------------
/build/templates/release.yaml:
--------------------------------------------------------------------------------
1 | # Basic release information
2 | release:
3 | version: '%%VERSION%%'
4 | date: '%%DATE%%'
5 | category: 62
6 | access: 1
7 | release_notes: '%%DEFAULT_RELEASE_NOTES%%'
8 | changelog: '%%DEFAULT_CHANGELOG%%'
9 |
10 | # Akeeba Release System API connection
11 | api:
12 | type: 'joomla'
13 | endpoint: '%%API.ENDPOINT%%'
14 | connector: '%%API.CONNECTOR%%'
15 | token: '%%API.TOKEN%%'
16 | cacert: '%%CUSTOMCACERT%%'
17 |
18 | steps: [%%RELEASESTEPS%%]
19 |
20 | # File upload connections
21 | connections:
22 | s3:
23 | type: 's3'
24 | access: '%%S3.ACCESS%%'
25 | secret: '%%S3.SECRET%%'
26 | bucket: '%%S3.BUCKET%%'
27 | tls: true
28 | signature: '%%S3.SIGNATURE%%'
29 | region: '%%S3.REGION%%'
30 | directory: 'downloads/fof4'
31 | cdnhostname: '%%S3.CDNHOSTNAME%%'
32 | acl: 'public-read'
33 | storage_class: 'STANDARD'
34 | maximum_age: 600
35 | sftp:
36 | type: '%%PRO.METHOD%%'
37 | directory: '%%SFTP.DIR%%'
38 | hostname: '%%SFTP.HOST%%'
39 | port: '%%SFTP.PORT%%'
40 | username: '%%SFTP.USERNAME%%'
41 | password: '%%SFTP.PASSWORD%%'
42 | public_key: '%%SFTP.PUBKEYFILE%%'
43 | private_key: '%%SFTP.PRIVKEYFILE%%'
44 | private_key_password: '%%SFTP.PRIVKEYFILE.PASS%%'
45 | timeout: 900
46 |
47 | # Release source files configuration.
48 | files:
49 | -
50 | title: 'FOF 4.x Package'
51 | connection: s3
52 | source: '%%RELEASEDIR%%/lib_*.zip'
53 | access: 1
54 |
55 | # Update sources
56 | updates:
57 | -
58 | title: 'FOF 4.x Updates'
59 | connection: s3
60 | directory: 'updates'
61 | stream: 44
62 | base_name: 'fof4_file'
63 | formats:
64 | - 'xml'
65 |
--------------------------------------------------------------------------------
/build/templates/version.txt:
--------------------------------------------------------------------------------
1 | ##VERSION##
2 | ##DATE##
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "akeeba/fof",
3 | "type": "library",
4 | "description": "FOF (Framework on Framework) is a Rapid Application Development framework for Joomla!",
5 | "require": {
6 | "php": "^7.2.0|^8.0.0",
7 | "ext-curl": "*",
8 | "ext-simplexml": "*",
9 | "ext-json": "*",
10 | "ext-openssl": "*",
11 | "ext-mbstring": "*",
12 | "ext-libxml": "*"
13 | },
14 | "keywords": [
15 | "framework",
16 | "joomla",
17 | "mvc",
18 | "rad"
19 | ],
20 | "homepage": "https://github.com/akeeba/fof",
21 | "license": "GPL-3.0+",
22 | "authors": [
23 | {
24 | "name": "Nicholas K. Dionysopoulos",
25 | "email": "nicholas_NO_SPAM_PLEASE@akeeba.com",
26 | "homepage": "http://www.dionysopoulos.me",
27 | "role": "Lead Developer"
28 | }
29 | ],
30 | "require-dev": {
31 | "mikey179/vfsstream": "2.0.x-dev",
32 | "mockery/mockery": "~0.9.5",
33 | "rector/rector": "^0.8"
34 | },
35 | "autoload": {
36 | "psr-4": {
37 | "FOF40\\": "fof"
38 | }
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/fof/.htaccess:
--------------------------------------------------------------------------------
1 |
2 | Order deny,allow
3 | Deny from all
4 |
5 |
6 |
7 | Require all denied
8 |
9 |
10 |
--------------------------------------------------------------------------------
/fof/Cli/Traits/CGIModeAware.php:
--------------------------------------------------------------------------------
1 | $v)
50 | {
51 | $query .= " $k";
52 | if ($v != "")
53 | {
54 | $query .= "=$v";
55 | }
56 | }
57 | }
58 |
59 | $query = ltrim($query);
60 |
61 | global $argv, $argc;
62 |
63 | $argv = explode(' ', $query);
64 | $argc = count($argv);
65 |
66 | $_SERVER['argv'] = $argv;
67 | }
68 |
69 | }
--------------------------------------------------------------------------------
/fof/Cli/Traits/JoomlaConfigAware.php:
--------------------------------------------------------------------------------
1 | formatByteSize($size);
48 | }
49 | else
50 | {
51 | return "(unknown)";
52 | }
53 | }
54 |
55 | /**
56 | * Returns the peak memory usage, formatted
57 | *
58 | * @return string
59 | */
60 | protected function peakMemUsage()
61 | {
62 | if (function_exists('memory_get_peak_usage'))
63 | {
64 | $size = memory_get_peak_usage();
65 |
66 | return $this->formatByteSize($size);
67 | }
68 | else
69 | {
70 | return "(unknown)";
71 | }
72 | }
73 | }
--------------------------------------------------------------------------------
/fof/Cli/Traits/MessageAware.php:
--------------------------------------------------------------------------------
1 | $msg, 'type' => strtolower($type)];
38 |
39 | if (!in_array($message, $this->messageQueue))
40 | {
41 | // Enqueue the message.
42 | $this->messageQueue[] = $message;
43 | }
44 | }
45 |
46 | /**
47 | * Loosely based on Joomla getMessageQueue
48 | *
49 | * @param bool $clear
50 | *
51 | * @return array
52 | */
53 | public function getMessageQueue($clear = false)
54 | {
55 | $messageQueue = $this->messageQueue;
56 |
57 | if ($clear)
58 | {
59 | $this->messageQueue = [];
60 | }
61 |
62 | return $messageQueue;
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/fof/Configuration/Domain/Authentication.php:
--------------------------------------------------------------------------------
1 | authentication;
36 |
37 | // Sanity check
38 |
39 | if (empty($authenticationData))
40 | {
41 | return;
42 | }
43 |
44 | $options = $xml->xpath('authentication/option');
45 |
46 | foreach ($options as $option)
47 | {
48 | $key = (string) $option['name'];
49 | $ret['authentication'][$key] = (string) $option;
50 | }
51 | }
52 |
53 | /**
54 | * Return a configuration variable
55 | *
56 | * @param string &$configuration Configuration variables (hashed array)
57 | * @param string $var The variable we want to fetch
58 | * @param mixed $default Default value
59 | *
60 | * @return mixed The variable's value
61 | */
62 | public function get(array &$configuration, string $var, $default = null)
63 | {
64 | if ($var == '*')
65 | {
66 | return $configuration['authentication'];
67 | }
68 |
69 | if (isset($configuration['authentication'][$var]))
70 | {
71 | return $configuration['authentication'][$var];
72 | }
73 | else
74 | {
75 | return $default;
76 | }
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/fof/Configuration/Domain/Container.php:
--------------------------------------------------------------------------------
1 | container;
36 |
37 | // Sanity check
38 |
39 | if (empty($containerData))
40 | {
41 | return;
42 | }
43 |
44 | $options = $xml->xpath('container/option');
45 |
46 | foreach ($options as $option)
47 | {
48 | $key = (string) $option['name'];
49 | $ret['container'][$key] = (string) $option;
50 | }
51 | }
52 |
53 | /**
54 | * Return a configuration variable
55 | *
56 | * @param string &$configuration Configuration variables (hashed array)
57 | * @param string $var The variable we want to fetch
58 | * @param mixed $default Default value
59 | *
60 | * @return mixed The variable's value
61 | */
62 | public function get(array &$configuration, string $var, $default = null)
63 | {
64 | if ($var == '*')
65 | {
66 | return $configuration['container'];
67 | }
68 |
69 | if (isset($configuration['container'][$var]))
70 | {
71 | return $configuration['container'][$var];
72 | }
73 | else
74 | {
75 | return $default;
76 | }
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/fof/Configuration/Domain/Dispatcher.php:
--------------------------------------------------------------------------------
1 | dispatcher;
36 |
37 | // Sanity check
38 |
39 | if (empty($dispatcherData))
40 | {
41 | return;
42 | }
43 |
44 | $options = $xml->xpath('dispatcher/option');
45 |
46 | foreach ($options as $option)
47 | {
48 | $key = (string) $option['name'];
49 | $ret['dispatcher'][$key] = (string) $option;
50 | }
51 | }
52 |
53 | /**
54 | * Return a configuration variable
55 | *
56 | * @param string &$configuration Configuration variables (hashed array)
57 | * @param string $var The variable we want to fetch
58 | * @param mixed $default Default value
59 | *
60 | * @return mixed The variable's value
61 | */
62 | public function get(array &$configuration, string $var, $default = null)
63 | {
64 | if ($var == '*')
65 | {
66 | return $configuration['dispatcher'];
67 | }
68 |
69 | if (isset($configuration['dispatcher'][$var]))
70 | {
71 | return $configuration['dispatcher'][$var];
72 | }
73 | else
74 | {
75 | return $default;
76 | }
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/fof/Configuration/Domain/DomainInterface.php:
--------------------------------------------------------------------------------
1 | foo instead of $container['foo']
18 | *
19 | * @param string $name
20 | *
21 | * @return mixed
22 | *
23 | * @throws \InvalidArgumentException if the identifier is not defined
24 | */
25 | function __get(string $name)
26 | {
27 | return $this->offsetGet($name);
28 | }
29 |
30 | /**
31 | * Magic setter for alternative syntax, e.g. $container->foo instead of $container['foo']
32 | *
33 | * @param string $name The unique identifier for the parameter or object
34 | * @param mixed $value The value of the parameter or a closure for a service
35 | *
36 | * @throws \RuntimeException Prevent override of a frozen service
37 | */
38 | function __set(string $name, $value)
39 | {
40 | // Special backwards compatible handling for the mediaVersion service
41 | if ($name == 'mediaVersion')
42 | {
43 | $this[$name]->setMediaVersion($value);
44 |
45 | return;
46 | }
47 |
48 | $this->offsetSet($name, $value);
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/fof/Container/Exception/NoComponent.php:
--------------------------------------------------------------------------------
1 | attach($this);
31 |
32 | // Store a reference to the subject object
33 | $this->subject = $subject;
34 | }
35 |
36 | /**
37 | * Returns the list of events observable by this observer. Set the $this->events array manually for faster
38 | * processing, or let this method use reflection to return a list of all public methods.
39 | *
40 | * @return array
41 | */
42 | public function getObservableEvents()
43 | {
44 | if (is_null($this->events))
45 | {
46 | // Assign an empty array to protect us from behaviours without any valid method
47 | $this->events = [];
48 |
49 | $reflection = new ReflectionObject($this);
50 | $methods = $reflection->getMethods(ReflectionMethod::IS_PUBLIC);
51 |
52 | foreach ($methods as $m)
53 | {
54 | if ($m->name == 'getObservableEvents')
55 | {
56 | continue;
57 | }
58 |
59 | if ($m->name == '__construct')
60 | {
61 | continue;
62 | }
63 |
64 | $this->events[] = $m->name;
65 | }
66 | }
67 |
68 | return $this->events;
69 | }
70 | }
71 |
--------------------------------------------------------------------------------
/fof/Factory/Exception/ControllerNotFound.php:
--------------------------------------------------------------------------------
1 | container = $container;
38 | }
39 |
40 | /**
41 | * @return string
42 | */
43 | public function getSection(): string
44 | {
45 | return $this->section;
46 | }
47 |
48 | /**
49 | * @param string $section
50 | */
51 | public function setSection(string $section): void
52 | {
53 | $this->section = $section;
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/fof/Factory/Magic/DispatcherFactory.php:
--------------------------------------------------------------------------------
1 | container->appConfig;
29 | $defaultConfig = $appConfig->get('dispatcher.*');
30 | $config = array_merge($defaultConfig, $config);
31 |
32 | $className = $this->container->getNamespacePrefix($this->getSection()) . 'Dispatcher\\DefaultDispatcher';
33 |
34 | if (!class_exists($className, true))
35 | {
36 | $className = '\\FOF40\\Dispatcher\\Dispatcher';
37 | }
38 |
39 | return new $className($this->container, $config);
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/fof/Factory/Magic/TransparentAuthenticationFactory.php:
--------------------------------------------------------------------------------
1 | container->appConfig;
30 | $defaultConfig = $appConfig->get('authentication.*');
31 | $config = array_merge($defaultConfig, $config);
32 |
33 | $className = $this->container->getNamespacePrefix($this->getSection()) . 'TransparentAuthentication\\DefaultTransparentAuthentication';
34 |
35 | if (!class_exists($className, true))
36 | {
37 | $className = '\\FOF40\\TransparentAuthentication\\TransparentAuthentication';
38 | }
39 |
40 | return new $className($this->container, $config);
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/fof/Html/FEFHelper/edit.php:
--------------------------------------------------------------------------------
1 | null,
25 | 'editor' => null,
26 | 'width' => '100%',
27 | 'height' => 500,
28 | 'columns' => 50,
29 | 'rows' => 20,
30 | 'created_by' => null,
31 | 'asset_id' => null,
32 | 'buttons' => true,
33 | 'hide' => false,
34 | ], $params);
35 |
36 | $editorType = $params['editor'];
37 |
38 | if (is_null($editorType))
39 | {
40 | $editorType = JoomlaFactory::getConfig()->get('editor');
41 | $user = JoomlaFactory::getUser();
42 |
43 | if (!$user->guest)
44 | {
45 | $editorType = $user->getParam('editor', $editorType);
46 | }
47 | }
48 |
49 | if (is_null($params['id']))
50 | {
51 | $params['id'] = $fieldName;
52 | }
53 |
54 | $editor = Editor::getInstance($editorType);
55 |
56 | return $editor->display($fieldName, $value, $params['width'], $params['height'],
57 | $params['columns'], $params['rows'], $params['buttons'], $params['id'],
58 | $params['asset_id'], $params['created_by'], $params);
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/fof/Html/Fields/fancyradio.php:
--------------------------------------------------------------------------------
1 | layout = 'joomla.form.field.radio.switcher';
47 | }
48 | else
49 | {
50 | // Joomla 3.x. Yes, 3.10 does have the layout but I am playing it safe.
51 | $this->layout = 'joomla.form.field.radio';
52 | }
53 |
54 | parent::__construct($form);
55 | }
56 | }
--------------------------------------------------------------------------------
/fof/Layout/LayoutHelper.php:
--------------------------------------------------------------------------------
1 | container = $container;
42 |
43 | return $layout->render($displayData);
44 | }
45 |
46 | }
47 |
--------------------------------------------------------------------------------
/fof/Model/DataModel/Behaviour/EmptyNonZero.php:
--------------------------------------------------------------------------------
1 | setBehaviorParam('filterZero', 1);
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/fof/Model/DataModel/Behaviour/Enabled.php:
--------------------------------------------------------------------------------
1 | hasField('enabled'))
36 | {
37 | return;
38 | }
39 |
40 | $fieldName = $model->getFieldAlias('enabled');
41 | $db = $model->getDbo();
42 |
43 | $model->whereRaw($db->qn($fieldName) . ' = ' . $db->q(1));
44 | }
45 |
46 | /**
47 | * The event runs after DataModel has retrieved a single item from the database. It is used to apply automatic
48 | * filters.
49 | *
50 | * @param DataModel &$model The model which was called
51 | * @param mixed &$keys The keys used to locate the record which was loaded
52 | *
53 | * @return void
54 | */
55 | public function onAfterLoad(DataModel &$model, &$keys)
56 | {
57 | // Make sure we have a DataModel
58 | if (!($model instanceof DataModel))
59 | {
60 | return;
61 | }
62 |
63 | // Make sure the field actually exists
64 | if (!$model->hasField('enabled'))
65 | {
66 | return;
67 | }
68 |
69 | // Filter by enabled status
70 | if (!$model->getFieldValue('enabled', 0))
71 | {
72 | $model->reset(true);
73 | }
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/fof/Model/DataModel/Exception/BaseException.php:
--------------------------------------------------------------------------------
1 | $relationName,
21 | 'type' => 'relation',
22 | );
23 |
24 | parent::__construct($db, $field);
25 |
26 | $this->subQuery = $subQuery;
27 | }
28 |
29 | public function callback($value)
30 | {
31 | return call_user_func($value, $this->subQuery);
32 | }
33 |
34 | public function getFieldName()
35 | {
36 | return '(' . $this->subQuery . ')';
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/fof/Model/DataModel/Relation/Exception/ForeignModelNotFound.php:
--------------------------------------------------------------------------------
1 | setState('foo', 'bar')
29 | *
30 | * @param callable $callback The callback to run on the remote model.
31 | * @param Collection $dataCollection
32 | *
33 | * @return Collection|DataModel
34 | */
35 | public function getData($callback = null, Collection $dataCollection = null)
36 | {
37 | if (is_null($dataCollection))
38 | {
39 | return parent::getData($callback, $dataCollection)->first();
40 | }
41 | else
42 | {
43 | return parent::getData($callback, $dataCollection);
44 | }
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/fof/Model/Exception/CannotGetName.php:
--------------------------------------------------------------------------------
1 | priority = 55;
31 | $this->enabled = version_compare(JVERSION, '3.9.999', 'le');
32 |
33 | parent::__construct($container);
34 | }
35 |
36 | /**
37 | * Opens the FEF styling wrapper element. Our component's output will be inside this wrapper.
38 | *
39 | * @param array $classes An array of additional CSS classes to add to the outer page wrapper element.
40 | *
41 | * @return void
42 | */
43 | protected function openPageWrapper(array $classes): void
44 | {
45 | $classes[] = 'akeeba-renderer-joomla3';
46 |
47 | parent::openPageWrapper($classes);
48 | }
49 |
50 | }
51 |
--------------------------------------------------------------------------------
/fof/Render/Joomla4.php:
--------------------------------------------------------------------------------
1 | priority = 40;
31 | $this->enabled = version_compare(JVERSION, '3.9.999', 'gt');
32 |
33 | parent::__construct($container);
34 | }
35 |
36 | /**
37 | * Opens the FEF styling wrapper element. Our component's output will be inside this wrapper.
38 | *
39 | * @param array $classes An array of additional CSS classes to add to the outer page wrapper element.
40 | *
41 | * @return void
42 | */
43 | protected function openPageWrapper(array $classes): void
44 | {
45 | $classes[] = 'akeeba-renderer-joomla4';
46 |
47 | parent::openPageWrapper($classes);
48 | }
49 |
50 | }
51 |
--------------------------------------------------------------------------------
/fof/Toolbar/Exception/MissingAttribute.php:
--------------------------------------------------------------------------------
1 | view = $view;
27 | }
28 |
29 | /**
30 | * Get the include path for a parsed view template
31 | *
32 | * @param string $path The path to the view template
33 | * @param array $forceParams Any additional information to pass to the view template engine
34 | *
35 | * @return array Content 3ναlυα+ιοη information (I use leetspeak here because of bad quality hosts with broken
36 | * scanners)
37 | */
38 | public function get($path, array $forceParams = [])
39 | {
40 | return [
41 | 'type' => 'raw',
42 | 'content' => '',
43 | ];
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/fof/View/Engine/BladeEngine.php:
--------------------------------------------------------------------------------
1 | compiler = $view->getContainer()->blade;
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/fof/View/Engine/EngineInterface.php:
--------------------------------------------------------------------------------
1 | 'raw|path', 'content' => 'path or raw content'] (I use leetspeak here because of bad quality hosts with broken scanners)
30 | */
31 | public function get($path, array $forceParams = array());
32 | }
33 |
--------------------------------------------------------------------------------
/fof/View/Engine/PhpEngine.php:
--------------------------------------------------------------------------------
1 | 'path',
29 | 'content' => $path
30 | );
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/fof/View/Exception/AccessForbidden.php:
--------------------------------------------------------------------------------
1 |
6 |
7 |
--------------------------------------------------------------------------------
/fof/sql/mysql.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 |
11 | mysql
12 | mysqli
13 | pdomysql
14 |
15 |
17 | false
18 |
19 |
20 |
21 |
22 |
23 |
30 |
31 |
32 |
33 |
34 |
37 |
38 |
39 |
40 |
41 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/fof/sql/postgresql.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 |
11 | postgres
12 | postgresql
13 |
14 |
15 |
16 |
17 |
18 |
19 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/fof/sql/sqlsrv.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 |
11 | sqlsrv
12 | sqlazure
13 |
14 |
15 |
16 |
17 |
18 |
19 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/fof/web.config:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/akeeba/fof/fccf97e3990aab96bcc8a9ac9ccbe476375f735e/icon.png
--------------------------------------------------------------------------------
/phpunit-5.phar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/akeeba/fof/fccf97e3990aab96bcc8a9ac9ccbe476375f735e/phpunit-5.phar
--------------------------------------------------------------------------------
/plugins/user/foftoken/.htaccess:
--------------------------------------------------------------------------------
1 |
2 | Order deny,allow
3 | Deny from all
4 |
5 |
6 |
7 | Require all denied
8 |
9 |
10 |
--------------------------------------------------------------------------------
/plugins/user/foftoken/fields/fancyradio.php:
--------------------------------------------------------------------------------
1 | form->getData()->get('id');
25 |
26 | if ($userId != Factory::getUser()->id)
27 | {
28 | $this->hidden = true;
29 | }
30 |
31 | return $ret;
32 | }
33 |
34 |
35 | protected function getInput()
36 | {
37 | // Do not display the token field when the user being edited is not the same as the logged in user
38 | if ($this->hidden)
39 | {
40 | return '';
41 | }
42 |
43 | $this->value = $this->getTokenForDisplay($this->value);
44 |
45 | return parent::getInput();
46 | }
47 |
48 | private function getTokenForDisplay($token)
49 | {
50 | $algo = $this->getAttribute('algo', 'sha256');
51 |
52 | try
53 | {
54 | $siteSecret = Factory::getApplication()->get('secret');
55 | }
56 | catch (Exception $e)
57 | {
58 | $jConfig = Factory::getConfig();
59 | $siteSecret = $jConfig->get('secret');
60 | }
61 |
62 | $rawToken = base64_decode($token);
63 | $tokenHash = hash_hmac($algo, $rawToken, $siteSecret);
64 | $userId = $this->form->getData()->get('id');
65 | $message = base64_encode("$algo:$userId:$tokenHash");
66 |
67 | if ($userId != Factory::getUser()->id)
68 | {
69 | $message = '';
70 | }
71 |
72 | return $message;
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/plugins/user/foftoken/foftoken.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 | plg_user_foftoken
10 | Nicholas K. Dionysopoulos / Akeeba Ltd
11 | 2019-11-04
12 | Copyright (c)2010-2023 Nicholas K. Dionysopoulos / Akeeba Ltd
13 | GNU GPL version 2 or later; see LICENSE.txt
14 | nicholas@akeeba.com
15 | www.akeeba.com
16 | 1.0.0
17 | PLG_USER_FOFTOKEN_XML_DESCRIPTION
18 |
19 |
20 | foftoken.php
21 | .htaccess
22 | web.config
23 | fields
24 | foftoken
25 |
26 |
27 |
28 | en-GB/en-GB.plg_user_foftoken.ini
29 | en-GB/en-GB.plg_user_foftoken.sys.ini
30 |
31 |
32 |
33 |
34 |
35 |
42 |
43 |
44 |
45 |
46 |
47 |
48 | script.php
49 |
50 |
51 | http://cdn.akeeba.com/updates/plg_user_foftoken.xml
52 |
53 |
54 |
--------------------------------------------------------------------------------
/plugins/user/foftoken/foftoken/foftoken.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
--------------------------------------------------------------------------------
/plugins/user/foftoken/language/.gitinclude:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/akeeba/fof/fccf97e3990aab96bcc8a9ac9ccbe476375f735e/plugins/user/foftoken/language/.gitinclude
--------------------------------------------------------------------------------
/plugins/user/foftoken/script.php:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/translations/plugins/user/foftoken/en-GB/en-GB.plg_user_foftoken.ini:
--------------------------------------------------------------------------------
1 | ;;
2 | ;; @package FOF
3 | ;; @copyright Copyright (c)2010-2023 Nicholas K. Dionysopoulos / Akeeba Ltd
4 | ;; @license GNU GPL version 2 or later
5 | ;;
6 | PLG_USER_FOFTOKEN="User - FOF Token Management"
7 | PLG_USER_FOFTOKEN_XML_DESCRIPTION="Allows the management of security tokens used for API authentication in FOF applications. IMPORTANT : FOF is a framework which may be used by third party software, unaffiliated with Akeeba Ltd. Do not disable or uninstall this plugin unless you are certain it's not used by other software."
8 |
9 | PLG_USER_FOFTOKEN_ERR_INVALIDTOKEN="Invalid token"
10 |
11 | PLG_USER_FOFTOKEN_GROUP_LABEL="FOF Token"
12 | PLG_USER_FOFTOKEN_GROUP_DESC="Manage the security tokens used for API authentication in extensions powered by the Akeeba FOF framework."
13 |
14 | PLG_USER_FOFTOKEN_TOKEN_LABEL="Token"
15 | PLG_USER_FOFTOKEN_TOKEN_DESC="This is your token. Use it in third party applications. IMPORTANT! If you do not see a token yet click on Save and revisit this page. A new token will be generated for you."
16 |
17 | PLG_USER_FOFTOKEN_ENABLED_LABEL="Active"
18 | PLG_USER_FOFTOKEN_ENABLED_DESC="Controls whether the token is active or not."
19 |
20 | PLG_USER_FOFTOKEN_RESET_LABEL="Reset"
21 | PLG_USER_FOFTOKEN_RESET_DESC="Set to Yes and save your user profile to create a new token, invalidating the old one."
22 |
--------------------------------------------------------------------------------
/translations/plugins/user/foftoken/en-GB/en-GB.plg_user_foftoken.sys.ini:
--------------------------------------------------------------------------------
1 | ;;
2 | ;; @package FOF
3 | ;; @copyright Copyright (c)2010-2023 Nicholas K. Dionysopoulos / Akeeba Ltd
4 | ;; @license GNU GPL version 2 or later
5 | ;;
6 | PLG_USER_FOFTOKEN="User - FOF Token Management"
7 | PLG_USER_FOFTOKEN_XML_DESCRIPTION="Allows the management of security tokens used for API authentication in FOF applications. IMPORTANT : FOF is a framework which may be used by third party software, unaffiliated with Akeeba Ltd. Do not disable or uninstall this plugin unless you are certain it's not used by other software."
8 |
9 | PLG_USER_FOFTOKEN_ALLOWEDUSERGROUPS_LABEL="Allowed User Groups"
10 | PLG_USER_FOFTOKEN_ALLOWEDUSERGROUPS_DESC="Which Joomla User Groups are allowed to use FOF Tokens for transparent authentication. Also controls which user groups see the FOF Token interface. Remove all selected entries to allow all groups to access FOF Tokens. Default: Joomla's built-in Super Users group (User Group ID 8)."
--------------------------------------------------------------------------------