├── .env ├── bin └── .gitkeep ├── cli └── .gitkeep ├── language └── .gitkeep ├── layouts ├── .gitkeep └── html │ ├── headline.php │ ├── attribution.php │ └── paragraph.php ├── media └── .gitkeep ├── modules └── .gitkeep ├── plugins └── .gitkeep ├── templates └── .gitkeep ├── administrator └── .gitkeep ├── components └── .gitkeep ├── installation └── .gitkeep ├── tests ├── _output │ └── .gitignore ├── unit │ ├── Http │ │ ├── data │ │ │ └── .env │ │ ├── RequestCest.php │ │ ├── RendererCest.php │ │ └── AcceptLanguageHeaderTest.php │ ├── Cms │ │ └── ServiceProvider │ │ │ ├── data │ │ │ └── env.txt │ │ │ ├── RequestServiceProviderTest.php │ │ │ ├── ExtensionFactoryServiceProviderTest.php │ │ │ ├── EventDispatcherServiceProviderTest.php │ │ │ └── SessionServiceProviderTest.php │ ├── DI │ │ ├── data │ │ │ ├── services.ini │ │ │ └── services.yml │ │ ├── Stubs │ │ │ ├── SimpleServiceProvider.php │ │ │ ├── ArbitraryInteropContainer.php │ │ │ └── stubs.php │ │ ├── ServiceProviderTest.php │ │ ├── AliasingTest.php │ │ ├── ContainerAwareTraitTest.php │ │ └── Loader │ │ │ └── IniLoaderTest.php │ ├── _bootstrap.php │ ├── Service │ │ ├── Stubs │ │ │ ├── Logger.php │ │ │ ├── MockEventDispatcher.php │ │ │ ├── SimpleCommandHandler.php │ │ │ ├── SimpleQueryHandler.php │ │ │ ├── ImmutableClass.php │ │ │ ├── SimpleQuery.php │ │ │ ├── SimpleCommand.php │ │ │ ├── ComplexQuery.php │ │ │ ├── LoggingMiddleware.php │ │ │ └── ComplexCommand.php │ │ ├── Mock │ │ │ └── Value.php │ │ ├── CommandBusTest.php │ │ └── ImmutableTest.php │ ├── Extension │ │ ├── Stubs │ │ │ └── SimpleEventListener.php │ │ ├── ExtensionTest.php │ │ └── ExtensionDispatcherTest.php │ ├── Event │ │ ├── Stubs │ │ │ ├── EmptyListener.php │ │ │ ├── ThirdListener.php │ │ │ ├── SecondListener.php │ │ │ ├── FirstListener.php │ │ │ └── SomethingListener.php │ │ └── DelegatingDispatcherTest.php │ ├── Session │ │ └── SessionTest.php │ ├── ORM │ │ ├── data │ │ │ ├── articles.csv │ │ │ ├── JsonEntity.json │ │ │ └── XmlEntity.xml │ │ ├── Storage │ │ │ └── Doctrine │ │ │ │ ├── data │ │ │ │ └── Test.xml │ │ │ │ ├── BasicDoctrineTestCase.php │ │ │ │ ├── DoctrineProviderTest.php │ │ │ │ └── DoctrineEntityFinderTest.php │ │ └── EntityBuilderCestX.php │ ├── Content │ │ └── AbstractContentTypeTest.php │ ├── Renderer │ │ └── Mock │ │ │ ├── Content.php │ │ │ └── Renderer.php │ └── Extensions │ │ └── Uppercase │ │ └── Listener │ │ └── UpperCaseListenerTest.php ├── .gitignore ├── _data │ └── dump.sql ├── api.suite.yml ├── cli.suite.yml ├── api │ └── _bootstrap.php ├── cli │ └── _bootstrap.php ├── acceptance │ ├── _bootstrap.php │ └── Page │ │ └── Joomla3 │ │ └── Hathor │ │ └── CPanelPage.php ├── functional │ ├── _bootstrap.php │ └── ORM │ │ └── Storage │ │ └── Doctrine │ │ ├── data │ │ └── Test.xml │ │ ├── BasicDoctrineTestCase.php │ │ └── DoctrineEntityFinderTest.php ├── _bootstrap.php ├── unit.suite.yml ├── _support │ ├── Helper │ │ ├── Api.php │ │ ├── Cli.php │ │ ├── Unit.php │ │ ├── Acceptance.php │ │ └── Functional.php │ ├── ApiTester.php │ ├── CliTester.php │ ├── UnitTester.php │ ├── AcceptanceTester.php │ ├── FunctionalTester.php │ └── Page │ │ ├── PageFactory.php │ │ └── Page.php ├── functional.suite.yml └── acceptance.suite.yml ├── docs ├── .gitignore ├── j4cdhms.png └── j4cdhms.md ├── config ├── database.ini ├── services.ini └── renderer.ini ├── .gitignore ├── extensions ├── UpperCase │ ├── config │ │ └── extension.yml │ └── Listener │ │ └── UpperCaseListener.php ├── Category │ ├── config │ │ └── extension.yml │ ├── Command │ │ └── AddCategoryContentTypesHandler.php │ ├── Entity │ │ └── Category.xml │ └── Listener │ │ └── AddRelationListener.php └── Article │ ├── data │ └── articles.csv │ └── Command │ ├── DisplayCommand.php │ └── DisplayCommandHandler.php ├── libraries └── incubator │ ├── Content │ ├── README.md │ ├── ContentTypeInterface.php │ ├── Type │ │ ├── AbstractContentType.php │ │ ├── Headline.php │ │ ├── Attribution.php │ │ ├── Paragraph.php │ │ └── Compound.php │ └── ContentTypeVisitorInterface.php │ ├── ORM │ ├── README.md │ ├── Definition │ │ ├── Parser │ │ │ ├── HasMany.php │ │ │ ├── BelongsTo.php │ │ │ ├── HasOne.php │ │ │ ├── HasManyThrough.php │ │ │ ├── Option.php │ │ │ ├── Relation.php │ │ │ ├── Fieldset.php │ │ │ ├── Element.php │ │ │ ├── Fields.php │ │ │ ├── ParserInterface.php │ │ │ ├── Entity.php │ │ │ ├── YamlParser.php │ │ │ └── Field.php │ │ └── Locator │ │ │ ├── LocatorInterface.php │ │ │ ├── Strategy │ │ │ ├── StrategyInterface.php │ │ │ ├── MapStrategy.php │ │ │ └── RecursiveDirectoryStrategy.php │ │ │ └── Locator.php │ ├── Exception │ │ ├── FileNotFoundException.php │ │ ├── EntityNotFoundException.php │ │ ├── InvalidElementException.php │ │ ├── PropertyNotFoundException.php │ │ └── WriteOnImmutableException.php │ ├── Collection │ │ ├── AbstractCollection.php │ │ └── CollectionInterface.php │ ├── Repository │ │ ├── RepositoryQuery.php │ │ ├── RepositoryQueryHandler.php │ │ └── RepositoryInterface.php │ ├── Status.php │ ├── Persistor │ │ └── PersistorInterface.php │ ├── Validator │ │ └── ValidatorInterface.php │ ├── Storage │ │ ├── DefaultProvider.php │ │ ├── Doctrine │ │ │ └── DoctrineEntityFinder.php │ │ ├── StorageProviderInterface.php │ │ └── CsvProvider.php │ ├── Event │ │ └── AfterCreateDefinitionEvent.php │ └── Finder │ │ ├── Operator.php │ │ ├── EntityFinderInterface.php │ │ └── CollectionFinderInterface.php │ ├── Service │ ├── README.md │ ├── Query.php │ ├── Command.php │ ├── CommandLockingMiddleware.php │ ├── Service.php │ ├── QueryHandler.php │ ├── DomainEvent.php │ ├── CommandBus.php │ └── Message.php │ ├── Renderer │ ├── README.md │ ├── ScriptStrategyInterface.php │ ├── Exception │ │ └── NotFoundException.php │ ├── RendererInterface.php │ ├── Event │ │ ├── RegisterContentTypeEvent.php │ │ ├── RenderContentTypeFailureEvent.php │ │ ├── RegisterContentTypeSuccessEvent.php │ │ ├── RegisterContentTypeFailureEvent.php │ │ ├── RenderContentTypeEvent.php │ │ └── RenderContentTypeSuccessEvent.php │ └── Factory.php │ ├── J3Compatibility │ ├── README.md │ └── Http │ │ └── Middleware │ │ └── RouterMiddleware.php │ ├── Http │ ├── README.md │ ├── Response.php │ ├── ServerRequestFactory.php │ ├── Exception │ │ └── UnsupportedMiddlewareException.php │ ├── Header │ │ ├── AcceptHeader.php │ │ └── AcceptLanguageHeader.php │ ├── MiddlewareInterface.php │ └── Middleware │ │ └── CommandBusMiddleware.php │ ├── Event │ ├── README.md │ ├── DispatcherAwareInterface.php │ ├── Priority.php │ ├── SubscriberInterface.php │ ├── EventInterface.php │ ├── DispatcherAwareTrait.php │ └── DispatcherInterface.php │ ├── DI │ ├── README.md │ ├── Exception │ │ ├── ContainerNotFoundException.php │ │ ├── KeyNotFoundException.php │ │ ├── DependencyResolutionException.php │ │ └── ProtectedKeyException.php │ ├── Loader │ │ ├── LoaderInterface.php │ │ └── IniLoader.php │ ├── ServiceProviderInterface.php │ ├── ContainerAwareInterface.php │ └── ContainerAwareTrait.php │ ├── Extension │ ├── ExtensionFactoryInterface.php │ └── ExtensionInterface.php │ ├── Cms │ ├── Service │ │ ├── ContentTypeQueryHandler.php │ │ ├── ContentTypeQuery.php │ │ ├── BasicDisplayCommand.php │ │ └── ExtensionQueryMiddleware.php │ └── ServiceProvider │ │ ├── ConfigServiceProvider.php │ │ ├── SessionServiceProvider.php │ │ ├── RequestServiceProvider.php │ │ ├── EventDispatcherServiceProvider.php │ │ └── ExtensionFactoryServiceProvider.php │ └── Session │ ├── SessionInterface.php │ └── Session.php ├── docker-compose.yml ├── travisci-codeception.yml ├── init.php ├── index.php ├── .travis.yml ├── TODO.md └── README.md /.env: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /bin/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /cli/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /language/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /layouts/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /media/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /modules/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /plugins/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /templates/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /administrator/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /components/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /installation/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/_output/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore -------------------------------------------------------------------------------- /tests/unit/Http/data/.env: -------------------------------------------------------------------------------- 1 | TEST_VARIABLE="value" 2 | -------------------------------------------------------------------------------- /docs/.gitignore: -------------------------------------------------------------------------------- 1 | /.gitignore 2 | /discussion 3 | *.pdf 4 | -------------------------------------------------------------------------------- /tests/.gitignore: -------------------------------------------------------------------------------- 1 | /_support/_generated 2 | /_output/* 3 | -------------------------------------------------------------------------------- /tests/unit/Cms/ServiceProvider/data/env.txt: -------------------------------------------------------------------------------- 1 | foo=bar 2 | -------------------------------------------------------------------------------- /config/database.ini: -------------------------------------------------------------------------------- 1 | sqlite : ///installation/demo.sqlite 2 | -------------------------------------------------------------------------------- /tests/_data/dump.sql: -------------------------------------------------------------------------------- 1 | /* Replace this file with actual dump of your database */ -------------------------------------------------------------------------------- /tests/unit/DI/data/services.ini: -------------------------------------------------------------------------------- 1 | [providers] 2 | foo = "\\SimpleServiceProvider" 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /cache/* 2 | /installation/demo.sqlite 3 | /libraries/vendor 4 | /logs/* 5 | /tmp/* 6 | -------------------------------------------------------------------------------- /docs/j4cdhms.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fastslack/joomla-pythagoras/master/docs/j4cdhms.png -------------------------------------------------------------------------------- /tests/api.suite.yml: -------------------------------------------------------------------------------- 1 | class_name: ApiTester 2 | modules: 3 | enabled: 4 | - \Helper\Api -------------------------------------------------------------------------------- /tests/cli.suite.yml: -------------------------------------------------------------------------------- 1 | class_name: CliTester 2 | modules: 3 | enabled: 4 | - \Helper\Cli -------------------------------------------------------------------------------- /tests/unit/DI/data/services.yml: -------------------------------------------------------------------------------- 1 | providers: 2 | foo: 3 | class: \SimpleServiceProvider 4 | -------------------------------------------------------------------------------- /tests/api/_bootstrap.php: -------------------------------------------------------------------------------- 1 | getTest() . 'Y'; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /tests/unit/Extension/Stubs/SimpleEventListener.php: -------------------------------------------------------------------------------- 1 | 12 | level; ?>>text; ?>level; ?>> 13 | -------------------------------------------------------------------------------- /tests/unit/Session/SessionTest.php: -------------------------------------------------------------------------------- 1 | assertNull($session->get('unit')); 14 | 15 | $session->set('unit', 'test'); 16 | $this->assertEquals('test', $session->get('unit')); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /tests/unit/ORM/data/articles.csv: -------------------------------------------------------------------------------- 1 | id,title,teaser,body,author,license,parent_id 2 | 1,"First Article","Look at the first example","This first example is cool","John Doe","CC",0 3 | 2,"Second Article","Look at another example","This provides child elements","Doctor","CC",0 4 | 3,"Part One","No. 1 of 2. article's children","This is the first child element","Rose Tyler","CC",2 5 | 4,"Part Two","No. 2 of 2. article's children","This is the second child element","Doctor","CC",2 6 | -------------------------------------------------------------------------------- /extensions/Article/data/articles.csv: -------------------------------------------------------------------------------- 1 | id,title,teaser,body,author,license,parent_id 2 | 1,"First Article","Look at the first example","This first example is cool","John Doe","CC",0 3 | 2,"Second Article","Look at another example","This provides child elements","Doctor","CC",0 4 | 3,"Part One","No. 1 of 2. article's children","This is the first child element","Rose Tyler","CC",2 5 | 4,"Part Two","No. 2 of 2. article's children","This is the second child element","Doctor","CC",2 6 | -------------------------------------------------------------------------------- /layouts/html/attribution.php: -------------------------------------------------------------------------------- 1 | 12 |

13 | label; ?> name; ?> 14 |

15 | -------------------------------------------------------------------------------- /tests/unit/Service/Stubs/ImmutableClass.php: -------------------------------------------------------------------------------- 1 | test = $test; 18 | 19 | parent::__construct(); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /config/services.ini: -------------------------------------------------------------------------------- 1 | [providers] 2 | config = "\\Joomla\\Cms\\ServiceProvider\\ConfigServiceProvider" 3 | request = "\\Joomla\\Cms\\ServiceProvider\\RequestServiceProvider" 4 | session = "\\Joomla\\Cms\\ServiceProvider\\SessionServiceProvider" 5 | extension_factory = "\\Joomla\\Cms\\ServiceProvider\\ExtensionFactoryServiceProvider" 6 | dispatcher = "\\Joomla\\Cms\\ServiceProvider\\EventDispatcherServiceProvider" 7 | command_bus = "\\Joomla\\Cms\\ServiceProvider\\CommandBusServiceProvider" 8 | -------------------------------------------------------------------------------- /tests/unit/DI/Stubs/SimpleServiceProvider.php: -------------------------------------------------------------------------------- 1 | value = $value; 14 | } 15 | 16 | public function register(Container $container, $alias = null) 17 | { 18 | $container->set($alias, $this->value); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /tests/unit/Service/Stubs/SimpleQuery.php: -------------------------------------------------------------------------------- 1 | test = $test; 19 | 20 | parent::__construct(); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /libraries/incubator/Http/Response.php: -------------------------------------------------------------------------------- 1 | test = $test; 19 | 20 | parent::__construct(); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /libraries/incubator/ORM/Definition/Parser/HasMany.php: -------------------------------------------------------------------------------- 1 | 12 | variant == Joomla\Content\Type\Paragraph::EMPHASISED) : ?> 13 |

text; ?>

14 | 15 |

text; ?>

16 | 17 | -------------------------------------------------------------------------------- /travisci-codeception.yml: -------------------------------------------------------------------------------- 1 | actor: Tester 2 | paths: 3 | tests: tests 4 | log: build/reports 5 | data: tests/_data 6 | support: tests/_support 7 | envs: tests/_envs 8 | settings: 9 | bootstrap: _bootstrap.php 10 | colors: true 11 | memory_limit: 1024M 12 | extensions: 13 | enabled: 14 | - Codeception\Extension\RunFailed 15 | modules: 16 | config: 17 | Db: 18 | dsn: '' 19 | user: '' 20 | password: '' 21 | dump: tests/_data/dump.sql 22 | reporters: 23 | report: PHPUnit_TextUI_ResultPrinter 24 | -------------------------------------------------------------------------------- /extensions/Article/Command/DisplayCommand.php: -------------------------------------------------------------------------------- 1 | $value) 16 | { 17 | $this->{$key} = $value; 18 | } 19 | 20 | parent::__construct(); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /libraries/incubator/DI/Exception/ContainerNotFoundException.php: -------------------------------------------------------------------------------- 1 | validate($arg1, $arg2); 16 | 17 | $this->arg1 = $arg1; 18 | $this->arg2 = $arg2; 19 | } 20 | 21 | private function validate($arg1, $arg2) 22 | { 23 | if (is_null($arg1)) 24 | { 25 | throw new \RuntimeException('Argument 1 cannot be null'); 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /tests/unit/Service/Stubs/LoggingMiddleware.php: -------------------------------------------------------------------------------- 1 | logger = $logger; 13 | } 14 | 15 | public function execute($message, callable $next) 16 | { 17 | $commandClass = get_class($message); 18 | 19 | $this->logger->log('Starting ' . $commandClass); 20 | $returnValue = $next($message); 21 | $this->logger->log('Ending ' . $commandClass); 22 | 23 | return $returnValue; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /libraries/incubator/DI/Exception/ProtectedKeyException.php: -------------------------------------------------------------------------------- 1 | validate($arg1, $arg2); 16 | 17 | $this->arg1 = $arg1; 18 | $this->arg2 = $arg2; 19 | } 20 | 21 | private function validate($arg1, $arg2) 22 | { 23 | if (is_null($arg1)) 24 | { 25 | throw new \RuntimeException('Argument 1 cannot be null'); 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /libraries/incubator/Http/Exception/UnsupportedMiddlewareException.php: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 15 | 16 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /tests/functional/ORM/Storage/Doctrine/data/Test.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 15 | 16 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /libraries/incubator/ORM/Definition/Locator/LocatorInterface.php: -------------------------------------------------------------------------------- 1 | tester->canSeeCurrentUrlEquals('/'); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /libraries/incubator/DI/ServiceProviderInterface.php: -------------------------------------------------------------------------------- 1 | assertTrue(ServerRequestFactory::fromGlobals() instanceof \Psr\Http\Message\RequestInterface, 'Request does not follow PSR-7'); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /libraries/incubator/ORM/Repository/RepositoryQuery.php: -------------------------------------------------------------------------------- 1 | entityName = $entityName; 30 | 31 | parent::__construct(); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /init.php: -------------------------------------------------------------------------------- 1 | set('ConfigDirectory', __DIR__); 22 | 23 | (new IniLoader($container))->loadFromFile(__DIR__ . '/config/services.ini'); 24 | 25 | if (!defined('JPATH_ROOT')) 26 | { 27 | define('JPATH_ROOT', $container->get('config')->get('JPATH_ROOT', __DIR__)); 28 | } 29 | 30 | return $container; 31 | } 32 | -------------------------------------------------------------------------------- /libraries/incubator/Event/DispatcherAwareInterface.php: -------------------------------------------------------------------------------- 1 | $field) 33 | { 34 | $this->fields[$name] = $field; 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /tests/unit/Extension/ExtensionTest.php: -------------------------------------------------------------------------------- 1 | assertInstanceOf(ExtensionInterface::class, $plugin); 16 | $this->assertEmpty($plugin->getListeners('unit')); 17 | } 18 | 19 | public function testAddExtensionListener() 20 | { 21 | $plugin = new Extension(); 22 | $plugin->addListener('unit', new SimpleEventListener()); 23 | 24 | $this->assertCount(1, $plugin->getListeners('unit')); 25 | $this->assertInstanceOf(SimpleEventListener::class, $plugin->getListeners('unit')[0]); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /libraries/incubator/ORM/Collection/CollectionInterface.php: -------------------------------------------------------------------------------- 1 | getArgument('listeners'); 31 | 32 | $listeners[] = 'third'; 33 | 34 | $event->setArgument('listeners', $listeners); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /tests/unit/Event/Stubs/SecondListener.php: -------------------------------------------------------------------------------- 1 | getArgument('listeners'); 31 | 32 | $listeners[] = 'second'; 33 | 34 | $event->setArgument('listeners', $listeners); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /libraries/incubator/Renderer/RendererInterface.php: -------------------------------------------------------------------------------- 1 | entity; 32 | $elements = $query->elements; 33 | 34 | return [ 35 | $elements 36 | ]; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /libraries/incubator/Service/Query.php: -------------------------------------------------------------------------------- 1 | $var)) 31 | { 32 | return $this->$var; 33 | } 34 | 35 | throw new \UnexpectedValueException("Unknown property $var"); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /tests/unit/DI/ServiceProviderTest.php: -------------------------------------------------------------------------------- 1 | getMock('Joomla\\DI\\ServiceProviderInterface'); 24 | $mock 25 | ->expects($this->once()) 26 | ->method('register') 27 | ->with($container); 28 | 29 | /** @noinspection PhpParamsInspection */ 30 | $container->registerServiceProvider($mock); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /libraries/incubator/Session/SessionInterface.php: -------------------------------------------------------------------------------- 1 | entity = $entity; 32 | $this->elements = $elements; 33 | 34 | parent::__construct(); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /libraries/incubator/ORM/Validator/ValidatorInterface.php: -------------------------------------------------------------------------------- 1 | $type, 34 | 'handler' => $handler 35 | ] 36 | ); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /tests/unit/ORM/Storage/Doctrine/BasicDoctrineTestCase.php: -------------------------------------------------------------------------------- 1 | getMockBuilder(Statement::class)->getMock(); 19 | $statement->method('fetchAll')->willReturn($data); 20 | $builder = $this->getMockBuilder(QueryBuilder::class) 21 | ->disableOriginalConstructor() 22 | ->getMock(); 23 | $builder->method('execute')->willReturn($statement); 24 | $connection = $this->getMockBuilder(Connection::class) 25 | ->disableOriginalConstructor() 26 | ->getMock(); 27 | $connection->method('createQueryBuilder')->willReturn($builder); 28 | 29 | return $connection; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /tests/unit/ORM/Storage/Doctrine/DoctrineProviderTest.php: -------------------------------------------------------------------------------- 1 | getMockBuilder(EntityBuilder::class) 16 | ->disableOriginalConstructor() 17 | ->getMock(); 18 | $persistor = new DoctrineProvider('sqlite::memory:', $builder, 'test'); 19 | 20 | $this->assertInstanceOf(EntityFinderInterface::class, $persistor->getEntityFinder('Test')); 21 | $this->assertInstanceOf(CollectionFinderInterface::class, $persistor->getCollectionFinder('Test')); 22 | $this->assertInstanceOf(PersistorInterface::class, $persistor->getPersistor('Test')); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /libraries/incubator/DI/ContainerAwareInterface.php: -------------------------------------------------------------------------------- 1 | $type, 34 | 'exception' => $exception 35 | ] 36 | ); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /tests/unit/Event/Stubs/FirstListener.php: -------------------------------------------------------------------------------- 1 | setArgument('listeners', array('first')); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /libraries/incubator/Renderer/Event/RegisterContentTypeSuccessEvent.php: -------------------------------------------------------------------------------- 1 | $type, 34 | 'handler' => $handler 35 | ] 36 | ); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /libraries/incubator/Renderer/Event/RegisterContentTypeFailureEvent.php: -------------------------------------------------------------------------------- 1 | $type, 34 | 'exception' => $exception 35 | ] 36 | ); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /libraries/incubator/Renderer/Event/RenderContentTypeEvent.php: -------------------------------------------------------------------------------- 1 | $type, 35 | 'content' => $content 36 | ] 37 | ); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /index.php: -------------------------------------------------------------------------------- 1 | get('dispatcher')), 25 | new RouterMiddleware, 26 | new LegacyRouterMiddleware, 27 | new CommandBusMiddleware($container->get('command_bus')), 28 | ] 29 | ); 30 | 31 | $response = $app->run($container->get('Request')); 32 | -------------------------------------------------------------------------------- /libraries/incubator/Event/SubscriberInterface.php: -------------------------------------------------------------------------------- 1 | 'methodName') 29 | * * array('eventName' => array('methodName', $priority)) 30 | * 31 | * @return array 32 | * 33 | * @since __DEPLOY_VERSION__ 34 | */ 35 | public static function getSubscribedEvents(); 36 | } 37 | -------------------------------------------------------------------------------- /extensions/Category/Command/AddCategoryContentTypesHandler.php: -------------------------------------------------------------------------------- 1 | entity->category; 31 | 32 | $elements = $query->elements; 33 | $elements['category_title'] = new Paragraph($category->title); 34 | 35 | return $elements; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /libraries/incubator/Renderer/Event/RenderContentTypeSuccessEvent.php: -------------------------------------------------------------------------------- 1 | $type, 35 | 'stream' => $stream 36 | ] 37 | ); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /libraries/incubator/ORM/Storage/DefaultProvider.php: -------------------------------------------------------------------------------- 1 | getMockForAbstractClass(AbstractContentType::class); 16 | 17 | /** @noinspection PhpUndefinedFieldInspection */ 18 | $mock->test = 'hello'; 19 | 20 | $this->assertEquals('hello', $mock->__get('test')); 21 | } 22 | 23 | /** 24 | * @testdox The AbstractContentType throws exception when no variable is 25 | * set. 26 | */ 27 | public function testAbstractContentTypeMagicGetterInvalidVariable() 28 | { 29 | $this->setExpectedException(\UnexpectedValueException::class); 30 | 31 | /** @var AbstractContentType $mock */ 32 | $mock = $this->getMockForAbstractClass(AbstractContentType::class); 33 | 34 | $mock->__get('test'); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /libraries/incubator/Extension/ExtensionInterface.php: -------------------------------------------------------------------------------- 1 | $value) 28 | { 29 | $method = 'set' . ucfirst($name); 30 | 31 | if (is_callable([$this, $method])) 32 | { 33 | $this->$method($value); 34 | } 35 | else 36 | { 37 | $this->$name = $value; 38 | } 39 | } 40 | } 41 | 42 | /** 43 | * Returns an array of variables assigned to this element. 44 | * 45 | * @return array 46 | */ 47 | public function toArray() 48 | { 49 | return get_object_vars($this); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /libraries/incubator/ORM/Storage/Doctrine/DoctrineEntityFinder.php: -------------------------------------------------------------------------------- 1 | $field) 33 | { 34 | $this->fields[$name] = $field; 35 | } 36 | } 37 | 38 | /** 39 | * Set the fieldsets 40 | * 41 | * @param Fieldset[] $values The fieldsets 42 | * 43 | * @return void 44 | */ 45 | protected function setFieldset($values) 46 | { 47 | foreach ($values as $name => $field) 48 | { 49 | $this->fields[$name] = $field; 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /libraries/incubator/ORM/Event/AfterCreateDefinitionEvent.php: -------------------------------------------------------------------------------- 1 | $entityName, 37 | 'definition' => $definition, 38 | 'builder' => $builder 39 | ] 40 | ); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /libraries/incubator/ORM/Definition/Locator/Strategy/MapStrategy.php: -------------------------------------------------------------------------------- 1 | map = $map; 31 | } 32 | 33 | /** 34 | * Locate a definition file 35 | * 36 | * @param string $filename The name of the XML file 37 | * 38 | * @return string|null The path, if found, null else 39 | */ 40 | public function locate($filename) 41 | { 42 | $basename = basename($filename); 43 | 44 | if (isset($this->map[$basename])) 45 | { 46 | return $this->map[$basename]; 47 | } 48 | 49 | return null; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /tests/_support/Page/PageFactory.php: -------------------------------------------------------------------------------- 1 | tester = $I; 32 | $this->template = $template; 33 | $this->version = $version; 34 | } 35 | 36 | /** 37 | * @param string $pageClass 38 | * 39 | * @return Page 40 | */ 41 | public function create($pageClass) 42 | { 43 | $pageClass = 'Joomla\\Tests\\System\\Page\\' . $this->version . '\\' . $this->template . '\\' . $pageClass; 44 | 45 | return new $pageClass($this->tester); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /libraries/incubator/Content/Type/Headline.php: -------------------------------------------------------------------------------- 1 | text = $text; 33 | $this->level = $level; 34 | } 35 | 36 | /** 37 | * Visits the content type. 38 | * 39 | * @param ContentTypeVisitorInterface $visitor The Visitor 40 | * 41 | * @return mixed 42 | */ 43 | public function accept(ContentTypeVisitorInterface $visitor) 44 | { 45 | return $visitor->visitHeadline($this); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /libraries/incubator/ORM/Definition/Parser/ParserInterface.php: -------------------------------------------------------------------------------- 1 | getMock(Dispatcher::class); 29 | $mockedDispatcher->expects($this->once()) 30 | ->method('dispatch') 31 | ->with(new Event($event)); 32 | 33 | $delegating = new DelegatingDispatcher($mockedDispatcher); 34 | 35 | /** @noinspection PhpDeprecationInspection */ 36 | $delegating->triggerEvent($event); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /libraries/incubator/Content/Type/Attribution.php: -------------------------------------------------------------------------------- 1 | label = $label; 33 | $this->name = $name; 34 | } 35 | 36 | /** 37 | * Visits the content type. 38 | * 39 | * @param ContentTypeVisitorInterface $visitor The Visitor 40 | * 41 | * @return mixed 42 | */ 43 | public function accept(ContentTypeVisitorInterface $visitor) 44 | { 45 | return $visitor->visitAttribution($this); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /libraries/incubator/Service/CommandLockingMiddleware.php: -------------------------------------------------------------------------------- 1 | commandBus = $commandBusBuilder->getCommandBus(); 36 | } 37 | 38 | /** 39 | * Command/query handler. 40 | * 41 | * @param Message $message A Command or a Query. 42 | * 43 | * @return mixed 44 | * 45 | * @since __DEPLOY_VERSION__ 46 | */ 47 | public function handle(Message $message) 48 | { 49 | return $this->commandBus->handle($message); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /libraries/incubator/ORM/Repository/RepositoryQueryHandler.php: -------------------------------------------------------------------------------- 1 | setDispatcher($this->getDispatcher()); 41 | 42 | return new Repository($query->entityName, $builder); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /tests/unit/Http/RendererCest.php: -------------------------------------------------------------------------------- 1 | getBody(); 36 | 37 | #$I->assertTrue($body instanceof PlainRenderer); 38 | 39 | return $next($request, $response); 40 | } 41 | ]); 42 | 43 | $app->run(new ServerRequest()); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /tests/unit/DI/Stubs/ArbitraryInteropContainer.php: -------------------------------------------------------------------------------- 1 | 'aic_foo_content', 7 | ); 8 | 9 | /** 10 | * Finds an entry of the container by its identifier and returns it. 11 | * 12 | * @param string $id Identifier of the entry to look for. 13 | * 14 | * @throws \Interop\Container\Exception\NotFoundException No entry was found for this identifier. 15 | * @throws \Interop\Container\Exception\ContainerException Error while retrieving the entry. 16 | * 17 | * @return mixed Entry. 18 | */ 19 | public function get($id) 20 | { 21 | if (!$this->has($id)) 22 | { 23 | throw new ArbitraryNotFoundException(); 24 | } 25 | 26 | return $this->data[$id]; 27 | } 28 | 29 | /** 30 | * Returns true if the container can return an entry for the given identifier. 31 | * Returns false otherwise. 32 | * 33 | * @param string $id Identifier of the entry to look for. 34 | * 35 | * @return boolean 36 | */ 37 | public function has($id) 38 | { 39 | return isset($this->data[$id]); 40 | } 41 | } 42 | 43 | class ArbitraryNotFoundException extends \RuntimeException implements \Interop\Container\Exception\NotFoundException 44 | { 45 | 46 | } 47 | -------------------------------------------------------------------------------- /libraries/incubator/ORM/Definition/Parser/Entity.php: -------------------------------------------------------------------------------- 1 | fields as $name => $field) 42 | { 43 | $this->fields[$name] = $field; 44 | } 45 | } 46 | 47 | /** 48 | * Set the relations 49 | * 50 | * @param Relation[] $values The relations 51 | * 52 | * @return void 53 | */ 54 | protected function setRelations($values) 55 | { 56 | $this->relations = $values[0]; 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /libraries/incubator/ORM/Finder/Operator.php: -------------------------------------------------------------------------------- 1 | '; 24 | const GT = self::GREATER_THAN; 25 | const GREATER_THAN = '>'; 26 | const GE = self::GREATER_OR_EQUAL; 27 | const GREATER_OR_EQUAL = '>='; 28 | const LT = self::LESS_THAN; 29 | const LESS_THAN = '<'; 30 | const LE = self::LESS_OR_EQUAL; 31 | const LESS_OR_EQUAL = '<='; 32 | const CONTAINS = '%LIKE%'; 33 | const STARTS_WITH = 'LIKE%'; 34 | const ENDS_WITH = '%LIKE'; 35 | const MATCHES = 'RLIKE'; 36 | const IN = 'IN'; 37 | 38 | /** 39 | * @param string $op The operator to be checked 40 | * 41 | * @return boolean true if valid, false else 42 | */ 43 | public static function isValid($op) 44 | { 45 | $reflect = new \ReflectionClass(self::class); 46 | 47 | return in_array($op, $reflect->getConstants()); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /libraries/incubator/Service/QueryHandler.php: -------------------------------------------------------------------------------- 1 | messageBus = $messageBus; 40 | $this->setDispatcher($dispatcher); 41 | } 42 | 43 | /** 44 | * Get the command bus. 45 | * 46 | * @return CommandBus 47 | */ 48 | public function getCommandBus() 49 | { 50 | return $this->messageBus; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /libraries/incubator/Content/Type/Paragraph.php: -------------------------------------------------------------------------------- 1 | text = $text; 36 | $this->variant = $variant; 37 | } 38 | 39 | /** 40 | * Visits the content type. 41 | * 42 | * @param ContentTypeVisitorInterface $visitor The Visitor 43 | * 44 | * @return mixed 45 | */ 46 | public function accept(ContentTypeVisitorInterface $visitor) 47 | { 48 | return $visitor->visitParagraph($this); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /libraries/incubator/ORM/Storage/StorageProviderInterface.php: -------------------------------------------------------------------------------- 1 | entityName = $entityName; 42 | $this->id = $id; 43 | $this->renderer = $renderer; 44 | 45 | parent::__construct(); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /libraries/incubator/Cms/ServiceProvider/ConfigServiceProvider.php: -------------------------------------------------------------------------------- 1 | has('ConfigFileName')) 38 | { 39 | $file = $container->get('ConfigFileName'); 40 | } 41 | 42 | $dotenv = new Dotenv($container->get('ConfigDirectory'), $file); 43 | $dotenv->overload(); 44 | 45 | $container->set($alias, new Registry($_ENV), true); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /libraries/incubator/ORM/Definition/Parser/YamlParser.php: -------------------------------------------------------------------------------- 1 | strategies = $strategies; 33 | } 34 | 35 | /** 36 | * Find the description file for an entity 37 | * 38 | * @param string $filename The name of the file 39 | * 40 | * @return string Path to the XML file 41 | */ 42 | public function findFile($filename) 43 | { 44 | foreach ($this->strategies as $strategy) 45 | { 46 | $path = $strategy->locate($filename); 47 | 48 | if (!is_null($path)) 49 | { 50 | return $path; 51 | } 52 | } 53 | 54 | return null; 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /libraries/incubator/DI/ContainerAwareTrait.php: -------------------------------------------------------------------------------- 1 | container) 39 | { 40 | return $this->container; 41 | } 42 | 43 | throw new ContainerNotFoundException('Container not set in ' . __CLASS__); 44 | } 45 | 46 | /** 47 | * Set the DI container. 48 | * 49 | * @param Container $container The DI container. 50 | * 51 | * @return $this 52 | * 53 | * @since 1.2 54 | */ 55 | public function setContainer(Container $container) 56 | { 57 | $this->container = $container; 58 | 59 | return $this; 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /libraries/incubator/Event/EventInterface.php: -------------------------------------------------------------------------------- 1 | session = (new SessionFactory)->newInstance($cookieParams); 32 | } 33 | 34 | /** 35 | * Get a property from the session bucket 36 | * 37 | * @param string $key The key 38 | * 39 | * @return mixed 40 | */ 41 | public function get($key) 42 | { 43 | return $this->session->getSegment('Joomla')->get($key); 44 | } 45 | 46 | /** 47 | * Set a property in the session bucket 48 | * 49 | * @param string $key The key 50 | * @param mixed $value The value 51 | * 52 | * @return void 53 | */ 54 | public function set($key, $value) 55 | { 56 | $this->session->getSegment('Joomla')->set($key, $value); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /libraries/incubator/Cms/ServiceProvider/SessionServiceProvider.php: -------------------------------------------------------------------------------- 1 | set( 34 | 'Session', 35 | [ 36 | $this, 37 | 'createSession' 38 | ], 39 | true, 40 | true 41 | ); 42 | 43 | if ($alias) 44 | { 45 | $container->alias($alias, 'Session'); 46 | } 47 | } 48 | 49 | /** 50 | * Create a session 51 | * 52 | * @param Container $container The container 53 | * 54 | * @return Session 55 | */ 56 | public function createSession(Container $container) 57 | { 58 | return new Session($container->get('Request')->getCookieParams()); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /libraries/incubator/Event/DispatcherAwareTrait.php: -------------------------------------------------------------------------------- 1 | dispatcher) 37 | { 38 | return $this->dispatcher; 39 | } 40 | 41 | throw new \UnexpectedValueException('Dispatcher not set in ' . __CLASS__); 42 | } 43 | 44 | /** 45 | * Set the dispatcher to use. 46 | * 47 | * @param DispatcherInterface $dispatcher The dispatcher to use. 48 | * 49 | * @return $this 50 | * 51 | * @since __DEPLOY_VERSION__ 52 | */ 53 | public function setDispatcher(DispatcherInterface $dispatcher) 54 | { 55 | $this->dispatcher = $dispatcher; 56 | 57 | return $this; 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /libraries/incubator/Renderer/Factory.php: -------------------------------------------------------------------------------- 1 | mediaTypeMap = $mapping; 34 | } 35 | 36 | /** 37 | * @param string $acceptHeader The 'Accept' header 38 | * 39 | * @return mixed 40 | */ 41 | public function create($acceptHeader = '*/*') 42 | { 43 | $header = new AcceptHeader($acceptHeader); 44 | 45 | $match = $header->getBestMatch(array_keys($this->mediaTypeMap)); 46 | 47 | if (!isset($match['token'])) 48 | { 49 | throw(new NotFoundException("No matching renderer found for\n\t$acceptHeader")); 50 | } 51 | 52 | $classname = $this->mediaTypeMap[$match['token']]; 53 | 54 | return new $classname($match); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /tests/unit/Renderer/Mock/Content.php: -------------------------------------------------------------------------------- 1 | content = $content; 15 | } 16 | 17 | public function getContents() 18 | { 19 | return $this->content; 20 | } 21 | } 22 | 23 | class ContentType extends Content 24 | { 25 | public function accept(ContentTypeVisitorInterface $visitor) 26 | { 27 | $visitor->visitContent($this); 28 | } 29 | } 30 | 31 | class NewContentType extends Content 32 | { 33 | public static function asHtml(NewContentType $content) 34 | { 35 | return 'static: ' . $content->getContents() . "\n"; 36 | } 37 | 38 | public function accept(ContentTypeVisitorInterface $visitor) 39 | { 40 | $visitor->visitNewContent($this); 41 | } 42 | } 43 | 44 | class OtherContentType extends Content 45 | { 46 | public function accept(ContentTypeVisitorInterface $visitor) 47 | { 48 | $visitor->visitOtherContent($this); 49 | } 50 | 51 | public function asHtml() 52 | { 53 | return 'dynamic: ' . $this->getContents() . "\n"; 54 | } 55 | } 56 | 57 | class UnregisteredContentType extends Content 58 | { 59 | public function accept(ContentTypeVisitorInterface $visitor) 60 | { 61 | $visitor->visitUnregisteredContent($this); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /libraries/incubator/ORM/Finder/EntityFinderInterface.php: -------------------------------------------------------------------------------- 1 | tester = $I; 26 | } 27 | 28 | /** 29 | * @return boolean 30 | */ 31 | abstract public function isCurrent(); 32 | 33 | public function isPresent($locator, $timeout = null) 34 | { 35 | try 36 | { 37 | $this->getElement($locator, $timeout); 38 | 39 | return true; 40 | } 41 | catch (\Exception $e) 42 | { 43 | return false; 44 | } 45 | } 46 | 47 | /** 48 | * @param string $locator The locator method:value 49 | * @param int $timeout 50 | * 51 | * @return WebDriverElement 52 | */ 53 | public function getElement($locator, $timeout = null) 54 | { 55 | $nodes = $this->tester->getScenario()->runStep(new \Codeception\Step\Action('_findElement', func_get_args())); 56 | 57 | return array_shift($nodes); 58 | } 59 | 60 | /** 61 | * @return string 62 | */ 63 | public function __toString() 64 | { 65 | return $this->url; 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /tests/unit/Http/AcceptLanguageHeaderTest.php: -------------------------------------------------------------------------------- 1 | [ 17 | 'requested' => 'Accept-Language: en-US', 18 | 'provided' => ['de-DE', 'en-GB', 'en-US'], 19 | 'expected' => ['token' => 'en-US'] 20 | ], 21 | 'wildcard' => [ 22 | 'requested' => 'Accept-Language: en', 23 | 'provided' => ['de-DE', 'en-GB', 'en-US'], 24 | 'expected' => ['token' => 'en-GB'] 25 | ], 26 | 'reallife-1' => [ 27 | 'requested' => 'Accept-Language: en-US,en;q=0.5', 28 | 'provided' => ['de-DE', 'en-GB', 'en-US'], 29 | 'expected' => ['token' => 'en-US'] 30 | ], 31 | ]; 32 | } 33 | 34 | /** 35 | * @dataProvider dataHeaders 36 | * 37 | * @param $requested 38 | * @param $provided 39 | * @param $expected 40 | */ 41 | public function testBestMatchIsNegotiated($requested, $provided, $expected) 42 | { 43 | $header = new \Joomla\Http\Header\AcceptLanguageHeader($requested); 44 | $accepted = $header->getBestMatch($provided); 45 | 46 | $this->assertArraySubset($expected, $accepted); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /libraries/incubator/Service/DomainEvent.php: -------------------------------------------------------------------------------- 1 | requestedon != $other->requestedon) 43 | { 44 | return false; 45 | } 46 | 47 | return parent::equals($other); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /libraries/incubator/Service/CommandBus.php: -------------------------------------------------------------------------------- 1 | commandBus = new \League\Tactician\CommandBus($middleware); 39 | } 40 | 41 | /** 42 | * Handle a command or query. 43 | * 44 | * @param Message $message A command object. 45 | * 46 | * @return mixed 47 | * 48 | * @since __DEPLOY_VERSION__ 49 | */ 50 | public function handle(Message $message) 51 | { 52 | return $this->commandBus->handle($message); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /libraries/incubator/Cms/ServiceProvider/RequestServiceProvider.php: -------------------------------------------------------------------------------- 1 | set( 35 | 'Request', 36 | [ 37 | $this, 38 | 'createRequest' 39 | ], 40 | true, 41 | true 42 | ); 43 | 44 | if ($alias) 45 | { 46 | $container->alias($alias, 'Request'); 47 | } 48 | } 49 | 50 | /** 51 | * Create a request 52 | * 53 | * @param Container $container The container 54 | * 55 | * @return ServerRequest 56 | */ 57 | public function createRequest(Container $container) 58 | { 59 | return ServerRequestFactory::fromGlobals(); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /tests/unit/DI/AliasingTest.php: -------------------------------------------------------------------------------- 1 | set('foo', function () 25 | { 26 | return new \StdClass; 27 | }, true, true); 28 | $container->alias('bar', 'foo'); 29 | 30 | $this->assertSame( 31 | $container->get('foo'), 32 | $container->get('bar'), 33 | 'When retrieving an alias of a class, both the original and the alias should return the same object instance.' 34 | ); 35 | } 36 | 37 | /** 38 | * @testdox has() also resolves the alias if set. 39 | */ 40 | public function testExistsResolvesAlias() 41 | { 42 | $container = new Container(); 43 | $container 44 | ->set('foo', function () 45 | { 46 | return new \stdClass; 47 | }, true, true) 48 | ->alias('bar', 'foo'); 49 | 50 | $this->assertTrue($container->has('foo'), "Original 'foo' was not resolved"); 51 | $this->assertTrue($container->has('bar'), "Alias 'bar' was not resolved"); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /extensions/Category/Entity/Category.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 17 | 18 | 19 | 20 | 21 | 25 | 26 | 27 | 28 | 33 | 34 | 35 | 36 | 37 | 42 | 46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /tests/unit/DI/Stubs/stubs.php: -------------------------------------------------------------------------------- 1 | stub = $stub; 26 | } 27 | } 28 | 29 | class Stub3 30 | { 31 | public $stub1; 32 | public $stub2; 33 | 34 | public function __construct(StubInterface $stub, StubInterface $stub2) 35 | { 36 | $this->stub1 = $stub; 37 | $this->stub2 = $stub2; 38 | } 39 | } 40 | 41 | class Stub4 implements StubInterface 42 | { 43 | } 44 | 45 | class Stub5 46 | { 47 | public $stub; 48 | 49 | public function __construct(Stub4 $stub) 50 | { 51 | $this->stub = $stub; 52 | } 53 | } 54 | 55 | class Stub6 56 | { 57 | public $stub; 58 | 59 | public function __construct($stub = 'foo') 60 | { 61 | $this->stub = $stub; 62 | } 63 | } 64 | 65 | class Stub7 66 | { 67 | public $stub; 68 | 69 | public function __construct($stub) 70 | { 71 | $this->stub = $stub; 72 | } 73 | } 74 | 75 | class Stub8 76 | { 77 | public $stub; 78 | 79 | public function __construct(DoesntExist $stub) 80 | { 81 | $this->stub = $stub; 82 | } 83 | } 84 | 85 | class Stub9 86 | { 87 | } 88 | -------------------------------------------------------------------------------- /tests/unit/Service/CommandBusTest.php: -------------------------------------------------------------------------------- 1 | commandBus = (new CommandBusBuilder($dispatcher))->getCommandBus(); 19 | } 20 | 21 | /** 22 | * @testdox The test command bus has the CommandBus interface 23 | */ 24 | public function testTheTestCommandBusImplementsTheCommandBusInterface() 25 | { 26 | $this->assertInstanceOf('\\Joomla\\Service\\CommandBus', $this->commandBus); 27 | } 28 | 29 | /** 30 | * @testdox The command bus has a handle method that takes a Command as a parameter 31 | */ 32 | public function testTheCommandBusHasAnExecuteMethodThatTakesACommandAsAParameter() 33 | { 34 | $this->assertTrue($this->commandBus->handle((new SimpleCommand))); 35 | } 36 | 37 | /** 38 | * @testdox The command bus has a handle method that takes a Query as a parameter 39 | */ 40 | public function testTheCommandBusHasAnExecuteMethodThatTakesAQueryAsAParameter() 41 | { 42 | $this->assertEquals('XSome contentY', $this->commandBus->handle((new SimpleQuery('Some content')))); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /tests/unit/ORM/EntityBuilderCestX.php: -------------------------------------------------------------------------------- 1 | "article", 36 | "@key" => "id", 37 | "id" => null, 38 | "title" => null, 39 | "teaser" => null, 40 | "body" => null, 41 | "author" => null, 42 | "license" => null, 43 | "parent_id" => null 44 | ]; 45 | 46 | foreach (['XmlEntity', 'JsonEntity', 'YmlEntity', 'YamlEntity'] as $entityName) 47 | { 48 | $entity = $builder->create($entityName); 49 | $I->assertEquals('article', $entity->type()); 50 | $I->assertEquals($expected, $entity->asArray()); 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /extensions/Category/Listener/AddRelationListener.php: -------------------------------------------------------------------------------- 1 | getArgument('builder'); 36 | 37 | // @todo the relation needs to be looked up here trough a relation table */ 38 | $id = 1; 39 | 40 | $relation = new HasOne( 41 | [ 42 | 'id' => 1, 43 | 'name' => 'category_id', 44 | 'type' => 'hasOne', 45 | 'entity' => 'Category', 46 | 'reference' => 'id' 47 | ] 48 | ); 49 | 50 | $builder->handleHasOne($relation, new Locator([new RecursiveDirectoryStrategy(__DIR__ . '/../Entity')])); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /extensions/Article/Command/DisplayCommandHandler.php: -------------------------------------------------------------------------------- 1 | children as $child) 40 | { 41 | $elements[] = new Compound( 42 | 'section', 43 | [ 44 | new Headline($child->title, 2), 45 | new Attribution('Contribution from', $child->author), 46 | new Paragraph($child->body), 47 | ] 48 | ); 49 | } 50 | 51 | return $elements; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /tests/unit/Extensions/Uppercase/Listener/UpperCaseListenerTest.php: -------------------------------------------------------------------------------- 1 | toUpperCase(new RenderContentTypeEvent('onBeforeRenderParagraph', $p)); 19 | 20 | $this->assertEquals('UNIT TEST', $p->text); 21 | } 22 | 23 | public function testUpperCaseListenerHeadline() 24 | { 25 | $listener = new UpperCaseListener(); 26 | 27 | $h = new Headline('unit test'); 28 | $listener->toUpperCase(new RenderContentTypeEvent('onBeforeRenderHeadline', $h)); 29 | 30 | $this->assertEquals('UNIT TEST', $h->text); 31 | } 32 | 33 | public function testUpperCaseListenerCompound() 34 | { 35 | $listener = new UpperCaseListener(); 36 | 37 | $c = new Compound('section', []); 38 | $c->add(new Paragraph('paragraph unit test')); 39 | $c->add(new Headline('headline unit test')); 40 | $listener->toUpperCase(new RenderContentTypeEvent('onBeforeRenderCompound', $c)); 41 | 42 | $this->assertEquals('PARAGRAPH UNIT TEST', $c->items[0]->text); 43 | $this->assertEquals('HEADLINE UNIT TEST', $c->items[1]->text); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /tests/unit/ORM/Storage/Doctrine/DoctrineEntityFinderTest.php: -------------------------------------------------------------------------------- 1 | createConnection([ 17 | [ 18 | 'foo' => 'bar' 19 | ], 20 | [ 21 | 'foo' => 'bar1' 22 | ] 23 | ]); 24 | 25 | $builder = new EntityBuilder(new Locator([ 26 | new RecursiveDirectoryStrategy(__DIR__) 27 | ])); 28 | $finder = new DoctrineEntityFinder($connection, 'test', 'Test', $builder); 29 | $finder->with('foo', Operator::EQUAL, 'bar'); 30 | 31 | $entity = $finder->getItem(); 32 | 33 | $this->assertNotNull($entity); 34 | $this->assertEquals('bar', $entity->foo); 35 | } 36 | 37 | public function testGetNoEntity() 38 | { 39 | $this->setExpectedException(EntityNotFoundException::class); 40 | 41 | $connection = $this->createConnection([]); 42 | 43 | $builder = new EntityBuilder(new Locator([ 44 | new RecursiveDirectoryStrategy(__DIR__) 45 | ])); 46 | $finder = new DoctrineEntityFinder($connection, 'test', 'Test', $builder); 47 | $finder->with('foo', Operator::EQUAL, 'bar1'); 48 | 49 | $finder->getItem(); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /TODO.md: -------------------------------------------------------------------------------- 1 | # ToDo List 2 | 3 | This is a non-complete list of tasks, that needs some work. 4 | Feel free to pick one to work on. In order to avoid confusion, 5 | it is appreciated if you give a short notice on the "Joomla 4 Working Group" channel on Glip 6 | or to Niels Braczek via email (nbraczek@bsds.de). 7 | 8 | ## Events 9 | 10 | - The Event system is missing completely, although the Event package from the framework already is there. 11 | This is IMO one of the most important things currently. 12 | 13 | ## ORM 14 | 15 | - The connection of the ORM (`EntityFinder`, `CollectionFinder`, and `Persistor`) to the 16 | Doctrine2 DBAL needs to be implemented. 17 | 18 | - Implement `store()` asnd `delete()` in `Joomla\ORM\Storage\CsvModel`. 19 | 20 | ## Renderer 21 | 22 | - A list of ContentTypes must be provided. Decision has to be made about, which types have to be 23 | implemented by the renderers. 24 | 25 | - Complete inline documentation (DocBlocks). 26 | 27 | ## Repository 28 | 29 | - The creation of the Repository in `Joomla\Component\Content\Command\AbstractCommand` 30 | must be moved to the Dependency Injection Container. 31 | 32 | ## Service Layer 33 | 34 | The CommandBus (and the QueryBus) are implemented in Chris Davenport's Service Layer using Tactician. 35 | 36 | - In the current 'article' example there's just one DisplayCommand together with its handler. 37 | However, the basic CRUD commands should be generic and be provided by the core, 38 | so that components don't have to implement them theirselves. 39 | -------------------------------------------------------------------------------- /tests/unit/ORM/data/JsonEntity.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "article", 3 | "storage": { 4 | "type": "special", 5 | "dsn": "csv://tests/unit/ORM/data/articles.csv" 6 | }, 7 | "fields": [ 8 | { 9 | "name": "id", 10 | "type": "id", 11 | "label": "JGLOBAL_FIELD_ID_LABEL", 12 | "description": "JGLOBAL_FIELD_ID_DESC", 13 | "default": null, 14 | "validation": [ 15 | { 16 | "rule": "positive" 17 | }, 18 | { 19 | "rule": "integer" 20 | } 21 | ] 22 | }, 23 | { 24 | "name": "title", 25 | "type": "title", 26 | "label": "JGLOBAL_TITLE", 27 | "validation": [ 28 | { 29 | "rule": "maxlen", 30 | "value": 64 31 | } 32 | ] 33 | }, 34 | { 35 | "name": "teaser", 36 | "type": "richtext" 37 | }, 38 | { 39 | "name": "body", 40 | "type": "richtext" 41 | }, 42 | { 43 | "name": "author", 44 | "type": "text", 45 | "default": "" 46 | }, 47 | { 48 | "name": "license", 49 | "type": "text", 50 | "validation": [ 51 | { 52 | "rule": "regex", 53 | "value": "copy(right|left)" 54 | } 55 | ] 56 | } 57 | ], 58 | "relations": [ 59 | { 60 | "type": "belongsTo", 61 | "name": "parent_id", 62 | "entity": "article" 63 | }, 64 | { 65 | "type": "hasMany", 66 | "name": "children", 67 | "entity": "article", 68 | "reference": "parent_id" 69 | } 70 | ] 71 | } 72 | -------------------------------------------------------------------------------- /libraries/incubator/Event/DispatcherInterface.php: -------------------------------------------------------------------------------- 1 | value) ? $validation->value : true; 47 | 48 | $this->validation[$validation->rule] = $value; 49 | } 50 | } 51 | 52 | /** 53 | * Set the options 54 | * 55 | * @param array $values The options 56 | * 57 | * @return void 58 | */ 59 | protected function setOption($values) 60 | { 61 | foreach ($values as $option) 62 | { 63 | $this->options[$option->value] = $option->label; 64 | } 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /tests/unit/Cms/ServiceProvider/RequestServiceProviderTest.php: -------------------------------------------------------------------------------- 1 | assertInstanceOf(ServiceProviderInterface::class, new RequestServiceProvider()); 19 | } 20 | 21 | /** 22 | * @testdox The RequestServiceProvider adds a RequestInterface to a 23 | * container 24 | */ 25 | public function testRequestServiceProviderCreatesRequestInterface() 26 | { 27 | $container = new Container(); 28 | 29 | $service = new RequestServiceProvider(); 30 | $service->register($container); 31 | 32 | $this->assertInstanceOf(ServerRequestInterface::class, $container->get('Request')); 33 | } 34 | 35 | /** 36 | * @testdox The RequestServiceProvider adds an RequestInterface to a 37 | * container with an alias 38 | */ 39 | public function testRequestServiceProviderCreatesDispatcherWithAlias() 40 | { 41 | $container = new Container(); 42 | 43 | $service = new RequestServiceProvider(); 44 | $service->register($container, 'unit'); 45 | 46 | $this->assertInstanceOf(ServerRequestInterface::class, $container->get('unit')); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /libraries/incubator/Cms/ServiceProvider/EventDispatcherServiceProvider.php: -------------------------------------------------------------------------------- 1 | set( 37 | $this->key, 38 | [ 39 | $this, 40 | 'createDispatcher' 41 | ], 42 | true, 43 | true 44 | ); 45 | 46 | if (!empty($alias)) 47 | { 48 | $container->alias($alias, $this->key); 49 | } 50 | } 51 | 52 | /** 53 | * Create the dispatcher 54 | * 55 | * @param Container $container The container 56 | * 57 | * @return ExtensionDispatcher 58 | */ 59 | public function createDispatcher(Container $container) 60 | { 61 | return new ExtensionDispatcher($container->get('extension_factory')); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /tests/functional/ORM/Storage/Doctrine/BasicDoctrineTestCase.php: -------------------------------------------------------------------------------- 1 | 'bar] ] 18 | * 19 | * @param array $data 20 | * @param string $tableName 21 | * @return Connection 22 | */ 23 | protected function createConnection($data = [], $tableName = 'test') 24 | { 25 | $connection = DriverManager::getConnection([ 26 | 'url' => 'sqlite::memory:' 27 | ]); 28 | 29 | $columns = []; 30 | foreach ($data as $row) 31 | { 32 | foreach ($row as $column => $value) 33 | { 34 | $columns[$column] = $column; 35 | } 36 | } 37 | 38 | $table = new Table($tableName); 39 | foreach ($columns as $col) 40 | { 41 | $type = 'string'; 42 | if ($col == 'id') 43 | { 44 | $type = 'integer'; 45 | } 46 | $table->addColumn($col, $type); 47 | } 48 | if ($table->hasColumn('id')) 49 | { 50 | $table->setPrimaryKey([ 51 | 'id' 52 | ]); 53 | } 54 | $connection->getSchemaManager()->createTable($table); 55 | 56 | foreach ($data as $row) 57 | { 58 | $connection->insert($tableName, $row); 59 | } 60 | 61 | return $connection; 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /tests/functional/ORM/Storage/Doctrine/DoctrineEntityFinderTest.php: -------------------------------------------------------------------------------- 1 | createConnection([ 17 | [ 18 | 'foo' => 'bar' 19 | ], 20 | [ 21 | 'foo' => 'bar1' 22 | ] 23 | ]); 24 | 25 | $builder = new EntityBuilder(new Locator([ 26 | new RecursiveDirectoryStrategy(__DIR__) 27 | ])); 28 | $finder = new DoctrineEntityFinder($connection, 'test', 'Test', $builder); 29 | $finder->with('foo', Operator::EQUAL, 'bar'); 30 | 31 | $entity = $finder->getItem(); 32 | 33 | $this->assertNotNull($entity); 34 | $this->assertEquals('bar', $entity->foo); 35 | } 36 | 37 | public function testGetNoEntity() 38 | { 39 | $this->setExpectedException(EntityNotFoundException::class); 40 | 41 | $connection = $this->createConnection([ 42 | [ 43 | 'foo' => 'bar' 44 | ] 45 | ]); 46 | 47 | $builder = new EntityBuilder(new Locator([ 48 | new RecursiveDirectoryStrategy(__DIR__) 49 | ])); 50 | $finder = new DoctrineEntityFinder($connection, 'test', 'Test', $builder); 51 | $finder->with('foo', Operator::EQUAL, 'bar1'); 52 | 53 | $finder->getItem(); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /tests/unit/DI/ContainerAwareTraitTest.php: -------------------------------------------------------------------------------- 1 | getObjectForTrait('\\Joomla\\DI\\ContainerAwareTrait'); 38 | $trait->setContainer($container); 39 | 40 | $this->assertSame($container, $trait->getContainer()); 41 | } 42 | 43 | /** 44 | * @testdox getContainer() throws an ContainerNotFoundException, if no container is set 45 | * @expectedException \Joomla\DI\Exception\ContainerNotFoundException 46 | */ 47 | public function testGetContainerException() 48 | { 49 | $trait = $this->getObjectForTrait('\\Joomla\\DI\\ContainerAwareTrait'); 50 | $trait->getContainer(); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /tests/unit/Renderer/Mock/Renderer.php: -------------------------------------------------------------------------------- 1 | getContents() . "\n"; 10 | $this->output .= $str; 11 | 12 | return strlen($str); 13 | } 14 | 15 | /** 16 | * Render a headline. 17 | * 18 | * @param \Joomla\Content\Type\Headline $headline The headline 19 | * 20 | * @return integer Number of bytes written to the output 21 | */ 22 | public function visitHeadline(\Joomla\Content\Type\Headline $headline) 23 | { 24 | return 0; 25 | } 26 | 27 | /** 28 | * Render a compound (block) element 29 | * 30 | * @param \Joomla\Content\Type\Compound $compound The compound 31 | * 32 | * @return integer Number of bytes written to the output 33 | */ 34 | public function visitCompound(\Joomla\Content\Type\Compound $compound) 35 | { 36 | return 0; 37 | } 38 | 39 | /** 40 | * Render an attribution to an author 41 | * 42 | * @param \Joomla\Content\Type\Attribution $attribution The attribution 43 | * 44 | * @return integer Number of bytes written to the output 45 | */ 46 | public function visitAttribution(\Joomla\Content\Type\Attribution $attribution) 47 | { 48 | return 0; 49 | } 50 | 51 | /** 52 | * Render a paragraph 53 | * 54 | * @param \Joomla\Content\Type\Paragraph $paragraph The paragraph 55 | * 56 | * @return integer Number of bytes written to the output 57 | */ 58 | public function visitParagraph(\Joomla\Content\Type\Paragraph $paragraph) 59 | { 60 | return 0; 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /extensions/UpperCase/Listener/UpperCaseListener.php: -------------------------------------------------------------------------------- 1 | getArgument('content'); 36 | $this->toUpper($contentType); 37 | } 38 | 39 | /** 40 | * Convert strings to uppercase 41 | * 42 | * @param ContentTypeInterface $content The content 43 | * 44 | * @return void 45 | */ 46 | private function toUpper(ContentTypeInterface $content) 47 | { 48 | if ($content instanceof Compound) 49 | { 50 | foreach ($content->items as $item) 51 | { 52 | $this->toUpper($item); 53 | } 54 | } 55 | elseif ($content instanceof Paragraph) 56 | { 57 | $content->text = strtoupper($content->text); 58 | } 59 | elseif ($content instanceof Headline) 60 | { 61 | $content->text = strtoupper($content->text); 62 | } 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /libraries/incubator/Cms/ServiceProvider/ExtensionFactoryServiceProvider.php: -------------------------------------------------------------------------------- 1 | set( 37 | $this->key, 38 | [ 39 | $this, 40 | 'createExtensionFactory' 41 | ], 42 | true, 43 | true 44 | ); 45 | 46 | if (!empty($alias)) 47 | { 48 | $container->alias($alias, $this->key); 49 | } 50 | } 51 | 52 | /** 53 | * Create the plugin factory 54 | * 55 | * @param Container $container The container 56 | * 57 | * @return FileExtensionFactory 58 | */ 59 | public function createExtensionFactory(Container $container) 60 | { 61 | return new FileExtensionFactory($container->get('ConfigDirectory') . '/extensions', $container); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /libraries/incubator/Content/Type/Compound.php: -------------------------------------------------------------------------------- 1 | type = $type; 34 | $this->items = array_filter($items); 35 | } 36 | 37 | /** 38 | * Add content items to the compound. 39 | * 40 | * @param ContentTypeInterface $content The content to add 41 | * 42 | * @return void 43 | */ 44 | public function add(ContentTypeInterface $content) 45 | { 46 | $this->items[] = $content; 47 | } 48 | 49 | /** 50 | * Visits the content type. 51 | * 52 | * @param ContentTypeVisitorInterface $visitor The Visitor 53 | * 54 | * @return mixed 55 | */ 56 | public function accept(ContentTypeVisitorInterface $visitor) 57 | { 58 | return $visitor->visitCompound($this); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /libraries/incubator/Content/ContentTypeVisitorInterface.php: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 17 | 18 | 19 | 20 | 21 | 25 | 26 | 27 | 28 | 31 | 32 | 35 | 36 | 40 | 41 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 53 | 57 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /tests/unit/Service/ImmutableTest.php: -------------------------------------------------------------------------------- 1 | doesNotExist; 15 | } 16 | 17 | /** 18 | * @expectedException \InvalidArgumentException 19 | * @testdox Throws a \InvalidArgumentException when trying to create a new property 20 | */ 21 | public function testThrowsAnInvalidArgumentExceptionWhenTryingToCreateANewProperty() 22 | { 23 | $testObject = new ImmutableClass; 24 | $testObject->test = 'something'; 25 | } 26 | 27 | /** 28 | * @testdox The constructor argument can be retrieved by a getter method. 29 | */ 30 | public function testTheConstructorArgumentCanBeRetrievedByAGetterMethod() 31 | { 32 | $this->assertEquals('testing', (new ImmutableClass('testing'))->getTest()); 33 | } 34 | 35 | /** 36 | * @testdox The constructor argument can be retrieved as an object property. 37 | */ 38 | public function testTheConstructorArgumentCanBeRetrievedAsAnObjectProperty() 39 | { 40 | $this->assertEquals('testing', (new ImmutableClass('testing'))->test); 41 | } 42 | 43 | /** 44 | * @testdox Property names are not case-sensitive. 45 | */ 46 | public function testPropertyNamesAreNotCasesensitive() 47 | { 48 | $this->assertEquals('testing', (new ImmutableClass('testing'))->TeSt); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /libraries/incubator/Cms/Service/ExtensionQueryMiddleware.php: -------------------------------------------------------------------------------- 1 | extensionFactory = $extensionFactory; 35 | } 36 | 37 | /** 38 | * @param object $command The command 39 | * @param callable $next The next middleware 40 | * 41 | * @return array 42 | */ 43 | public function execute($command, callable $next) 44 | { 45 | if ($command instanceof Query) 46 | { 47 | $return = []; 48 | 49 | foreach ($this->extensionFactory->getExtensions() as $extension) 50 | { 51 | foreach ($extension->getQueryHandlers($command) as $handler) 52 | { 53 | $return[] = $handler->handle($command); 54 | } 55 | } 56 | 57 | if ($return) 58 | { 59 | return $return; 60 | } 61 | } 62 | 63 | return $next($command); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /libraries/incubator/J3Compatibility/Http/Middleware/RouterMiddleware.php: -------------------------------------------------------------------------------- 1 | getAttributes(); 37 | 38 | if (!isset($attributes['command']) && $this->isLegacy()) 39 | { 40 | // @todo Emit afterRouting event 41 | } 42 | 43 | return $next($request, $response); 44 | } 45 | 46 | /** 47 | * Check if the requested option belongs to a legacy component 48 | * 49 | * @return boolean 50 | */ 51 | private function isLegacy() 52 | { 53 | return isset($_REQUEST['option']) && preg_match('~^com_~', $_REQUEST['option']); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /libraries/incubator/Service/Message.php: -------------------------------------------------------------------------------- 1 | raisedon = sprintf('%d%03d', $parts[1], $parts[0] * 1000); 35 | 36 | parent::__construct(); 37 | } 38 | 39 | /** 40 | * Get the properties of the object. 41 | * 42 | * @return array of key-value pairs. 43 | * 44 | * @since __DEPLOY_VERSION__ 45 | */ 46 | public function getProperties() 47 | { 48 | $properties = parent::getProperties(); 49 | 50 | // Unset the properties we don't want to expose. 51 | unset($properties['raisedon']); 52 | 53 | return $properties; 54 | } 55 | 56 | /** 57 | * Get the timestamp indicating when this message was raised. 58 | * 59 | * @return string 60 | * 61 | * @since __DEPLOY_VERSION__ 62 | */ 63 | public function getRaisedOn() 64 | { 65 | return $this->raisedon; 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /tests/unit/Extension/ExtensionDispatcherTest.php: -------------------------------------------------------------------------------- 1 | getMockBuilder(ExtensionFactoryInterface::class)->getMock(); 18 | $dispatcher = new ExtensionDispatcher($factory); 19 | 20 | $this->assertInstanceOf(DispatcherInterface::class, $dispatcher); 21 | $this->assertEmpty($dispatcher->getListeners('unit')); 22 | } 23 | 24 | public function testExtensionDispatcherListenersLoadedOnDispatch() 25 | { 26 | $testCallable = function () 27 | { 28 | }; 29 | 30 | /** @var $plugin */ 31 | $plugin = $this->getMockBuilder(ExtensionInterface::class)->getMock(); 32 | $plugin->method('getListeners')->willReturn([ 33 | $testCallable 34 | ]); 35 | 36 | /** @var ExtensionFactoryInterface|\PHPUnit_Framework_MockObject_MockObject $factory */ 37 | $factory = $this->getMockBuilder(ExtensionFactoryInterface::class)->getMock(); 38 | $factory->expects($this->once()) 39 | ->method('getExtensions') 40 | ->willReturn([ 41 | $plugin 42 | ]); 43 | $dispatcher = new ExtensionDispatcher($factory); 44 | $dispatcher->dispatch(new Event('unit')); 45 | 46 | $listeners = $dispatcher->getListeners('unit'); 47 | $this->assertCount(1, $listeners); 48 | $this->assertEquals($testCallable, $listeners[0]); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /libraries/incubator/ORM/Definition/Locator/Strategy/RecursiveDirectoryStrategy.php: -------------------------------------------------------------------------------- 1 | root = $root; 31 | } 32 | 33 | /** 34 | * Locate a definition file 35 | * 36 | * @param string $filename The name of the XML file 37 | * 38 | * @return string|null The path, if found, null else 39 | */ 40 | public function locate($filename) 41 | { 42 | return $this->scan($this->root, $filename); 43 | } 44 | 45 | /** 46 | * Scan a directory for a filename 47 | * 48 | * @param string $directory The start directory 49 | * @param string $filename The filename to search for 50 | * 51 | * @return string|null The path, if found, null else 52 | */ 53 | private function scan($directory, $filename) 54 | { 55 | $filename = strtolower($filename); 56 | 57 | foreach (new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($directory)) as $file) 58 | { 59 | if (strtolower($file->getFilename()) == $filename) 60 | { 61 | return $file->getRealPath(); 62 | } 63 | } 64 | 65 | return null; 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /libraries/incubator/ORM/Storage/CsvProvider.php: -------------------------------------------------------------------------------- 1 | dataFile = $dataFile; 35 | } 36 | 37 | /** 38 | * Get an EntityFinder. 39 | * 40 | * @param string $entityName T he name of the entity 41 | * 42 | * @return EntityFinderInterface The finder 43 | */ 44 | public function getEntityFinder($entityName) 45 | { 46 | return new CsvModel($this->dataFile); 47 | } 48 | 49 | /** 50 | * Get a CollectionFinder. 51 | * 52 | * @param string $entityName The name of the entity 53 | * 54 | * @return CollectionFinderInterface 55 | */ 56 | public function getCollectionFinder($entityName) 57 | { 58 | return new CsvModel($this->dataFile); 59 | } 60 | 61 | /** 62 | * Get a Persistor. 63 | * 64 | * @param string $entityName The name of the entity 65 | * 66 | * @return PersistorInterface 67 | */ 68 | public function getPersistor($entityName) 69 | { 70 | return new CsvModel($this->dataFile); 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /tests/unit/Cms/ServiceProvider/ExtensionFactoryServiceProviderTest.php: -------------------------------------------------------------------------------- 1 | assertInstanceOf(ServiceProviderInterface::class, new ExtensionFactoryServiceProvider()); 19 | } 20 | 21 | /** 22 | * @testdox The ExtensionFactoryServiceProvider adds an ExtensionFactory to a 23 | * container 24 | */ 25 | public function testExtensionFactoryServiceProviderCreatesExtensionFactory() 26 | { 27 | $container = new Container(); 28 | $container->set('ConfigDirectory', __DIR__); 29 | 30 | $service = new ExtensionFactoryServiceProvider(); 31 | $service->register($container); 32 | 33 | $this->assertInstanceOf(ExtensionFactoryInterface::class, $container->get('ExtensionFactory')); 34 | } 35 | 36 | /** 37 | * @testdox The ExtensionFactoryServiceProvider adds an ExtensionFactory to a 38 | * container with an alias 39 | */ 40 | public function testExtensionFactoryServiceProviderCreatesExtensionFactoryWithAlias() 41 | { 42 | $container = new Container(); 43 | $container->set('ConfigDirectory', __DIR__); 44 | 45 | $service = new ExtensionFactoryServiceProvider(); 46 | $service->register($container, 'unit'); 47 | 48 | $this->assertInstanceOf(ExtensionFactoryInterface::class, $container->get('unit')); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /libraries/incubator/ORM/Repository/RepositoryInterface.php: -------------------------------------------------------------------------------- 1 | findOne()->with('id', \Joomla\ORM\Finder\Operator::EQUAL, '$id)->get() 38 | * 39 | * @param mixed $id The id value 40 | * 41 | * @return EntityInterface The requested entity 42 | * 43 | * @throws EntityNotFoundException if the entity does not exist 44 | */ 45 | public function findById($id); 46 | 47 | /** 48 | * Find a single entity. 49 | * 50 | * @return EntityFinderInterface The responsible Finder object 51 | */ 52 | public function findOne(); 53 | 54 | /** 55 | * Find multiple entities. 56 | * 57 | * @return CollectionFinderInterface The responsible Finder object 58 | */ 59 | public function findAll(); 60 | 61 | /** 62 | * Get the persistor 63 | * 64 | * @return PersistorInterface 65 | */ 66 | public function persistor(); 67 | } 68 | -------------------------------------------------------------------------------- /libraries/incubator/Http/Middleware/CommandBusMiddleware.php: -------------------------------------------------------------------------------- 1 | commandBus = $commandBus; 36 | } 37 | 38 | /** 39 | * Execute the middleware. Don't call this method directly; it is used by the `Application` internally. 40 | * 41 | * @internal 42 | * 43 | * @param ServerRequestInterface $request The request object 44 | * @param ResponseInterface $response The response object 45 | * @param callable $next The next middleware handler 46 | * 47 | * @return ResponseInterface 48 | */ 49 | public function handle(ServerRequestInterface $request, ResponseInterface $response, callable $next = null) 50 | { 51 | $command = $request->getAttribute('command'); 52 | 53 | if (empty($command)) 54 | { 55 | throw new \RuntimeException('No command provided'); 56 | } 57 | 58 | $this->commandBus->handle($command); 59 | 60 | $response = $next($request, $response); 61 | 62 | return $response; 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /libraries/incubator/ORM/Finder/CollectionFinderInterface.php: -------------------------------------------------------------------------------- 1 | assertInstanceOf(ServiceProviderInterface::class, new EventDispatcherServiceProvider()); 20 | } 21 | 22 | /** 23 | * @testdox The EventDispatcherServiceProvider adds an EventDispatcher to a 24 | * container 25 | */ 26 | public function testEventDispatcherServiceProviderCreatesDispatcher() 27 | { 28 | $container = new Container(); 29 | $container->set('extension_factory', $this->getMockBuilder(ExtensionFactoryInterface::class)->getMock()); 30 | 31 | $service = new EventDispatcherServiceProvider(); 32 | $service->register($container); 33 | 34 | $this->assertInstanceOf(DispatcherInterface::class, $container->get('EventDispatcher')); 35 | } 36 | 37 | /** 38 | * @testdox The EventDispatcherServiceProvider adds an EventDispatcher to a 39 | * container with an alias 40 | */ 41 | public function testEventDispatcherServiceProviderCreatesDispatcherWithAlias() 42 | { 43 | $container = new Container(); 44 | $container->set('extension_factory', $this->getMockBuilder(ExtensionFactoryInterface::class)->getMock()); 45 | 46 | $service = new EventDispatcherServiceProvider(); 47 | $service->register($container, 'unit'); 48 | 49 | $this->assertInstanceOf(DispatcherInterface::class, $container->get('unit')); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /libraries/incubator/DI/Loader/IniLoader.php: -------------------------------------------------------------------------------- 1 | container = $container; 37 | } 38 | 39 | /** 40 | * Helper function to load the services from a file. 41 | * 42 | * @param string $filename The filename 43 | * 44 | * @return void 45 | * 46 | * @see LoaderInterface::load() 47 | */ 48 | public function loadFromFile($filename) 49 | { 50 | $this->load(file_get_contents($filename)); 51 | } 52 | 53 | /** 54 | * Loads service providers from the content. 55 | * 56 | * @param string $content The content 57 | * 58 | * @return void 59 | */ 60 | public function load($content) 61 | { 62 | $services = parse_ini_string($content, true); 63 | 64 | if (!key_exists('providers', $services)) 65 | { 66 | return; 67 | } 68 | 69 | foreach ($services['providers'] as $alias => $service) 70 | { 71 | if (!class_exists($service)) 72 | { 73 | continue; 74 | } 75 | 76 | $this->container->registerServiceProvider(new $service, $alias); 77 | } 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /tests/unit/DI/Loader/IniLoaderTest.php: -------------------------------------------------------------------------------- 1 | load($content); 33 | 34 | $this->assertEquals('called', $container->get('foo')); 35 | } 36 | 37 | /** 38 | * @testdox Loading an invalid string 39 | */ 40 | public function testLoadInvalidString() 41 | { 42 | $content = <<load($content); 50 | 51 | $this->assertFalse($container->has('foo')); 52 | } 53 | 54 | /** 55 | * @testdox Loading an invalid class 56 | */ 57 | public function testLoadWithInvalidClass() 58 | { 59 | $content = <<load($content); 67 | 68 | $this->assertFalse($container->has('foo')); 69 | } 70 | 71 | /** 72 | * @testdox Loading a file 73 | */ 74 | public function testLoadFile() 75 | { 76 | $container = new Container(); 77 | 78 | $loader = new IniLoader($container); 79 | $loader->loadFromFile(dirname(__DIR__) . '/data/services.ini'); 80 | 81 | $this->assertEquals('called', $container->get('foo')); 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /tests/unit/Event/Stubs/SomethingListener.php: -------------------------------------------------------------------------------- 1 | 'methodName') 70 | * * array('eventName' => array('methodName', $priority)) 71 | * 72 | * @return array 73 | * 74 | * @since __DEPLOY_VERSION__ 75 | */ 76 | public static function getSubscribedEvents() 77 | { 78 | return [ 79 | 'onBeforeSomething' => 'onBeforeSomething', 80 | 'onSomething' => 'onSomething', 81 | 'onAfterSomething' => ['onAfterSomething', Priority::HIGH] 82 | ]; 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /tests/unit/Cms/ServiceProvider/SessionServiceProviderTest.php: -------------------------------------------------------------------------------- 1 | assertInstanceOf(ServiceProviderInterface::class, new SessionServiceProvider()); 20 | } 21 | 22 | /** 23 | * @testdox The SessionServiceProvider adds a SessionInterface to a 24 | * container 25 | */ 26 | public function testSessionServiceProviderCreatesSessionInterface() 27 | { 28 | $request = $this->getMockBuilder(ServerRequestInterface::class)->getMock(); 29 | $request->method('getCookieParams')->willReturn([ 30 | 'unit' => 'test' 31 | ]); 32 | 33 | $container = new Container(); 34 | $container->set('Request', $request); 35 | 36 | $service = new SessionServiceProvider(); 37 | $service->register($container); 38 | 39 | $this->assertInstanceOf(SessionInterface::class, $container->get('Session')); 40 | } 41 | 42 | /** 43 | * @testdox The SessionServiceProvider adds an SessionInterface to a 44 | * container with an alias 45 | */ 46 | public function testSessionServiceProviderCreatesDispatcherWithAlias() 47 | { 48 | $request = $this->getMockBuilder(ServerRequestInterface::class)->getMock(); 49 | $request->method('getCookieParams')->willReturn([ 50 | 'unit' => 'test' 51 | ]); 52 | 53 | $container = new Container(); 54 | $container->set('Request', $request); 55 | 56 | $service = new SessionServiceProvider(); 57 | $service->register($container, 'unit'); 58 | 59 | $this->assertInstanceOf(SessionInterface::class, $container->get('unit')); 60 | } 61 | } 62 | --------------------------------------------------------------------------------