Commit cf60fb8d authored by Tino Goratsch's avatar Tino Goratsch

Merge branch 'feature/module-compiler-pass' into develop

parents 54f0ce1a e4c74be3
......@@ -92,11 +92,14 @@ class ServiceContainerBuilder extends ContainerBuilder
foreach ($availableModules as $module) {
foreach ($vendors as $vendor) {
$path = $this->applicationPath->getModulesDir() . $vendor . '/' . $module['dir'] . '/Resources/config/services.yml';
$modulePath = $this->applicationPath->getModulesDir() . $vendor . '/' . $module['dir'];
$path = $modulePath . '/Resources/config/services.yml';
if (is_file($path)) {
$loader->load($path);
}
$this->registerCompilerPass($vendor, $module['dir']);
}
}
......@@ -118,4 +121,21 @@ class ServiceContainerBuilder extends ContainerBuilder
) {
return new static($applicationPath, $symfonyRequest, $applicationMode, $allModules);
}
/**
* @param string $vendor
* @param string $moduleName
*/
private function registerCompilerPass($vendor, $moduleName)
{
$fqn = "\\ACP3\\Modules\\" . $vendor . "\\" . $moduleName . "\\ModuleRegistration";
if (class_exists($fqn)) {
$instance = new $fqn;
if ($instance instanceof Modules\ModuleRegistration) {
$instance->build($this);
}
}
}
}
<?php
/**
* Copyright (c) 2016 by the ACP3 Developers.
* See the LICENCE file at the top-level module directory for licencing details.
*/
namespace ACP3\Core\Modules;
use Symfony\Component\DependencyInjection\ContainerBuilder;
class ModuleRegistration
{
/**
* @param ContainerBuilder $containerBuilder
*/
public function build(ContainerBuilder $containerBuilder)
{
}
}
<?php
/**
* Copyright (c) 2016 by the ACP3 Developers.
* See the LICENCE file at the top-level module directory for licencing details.
*/
namespace ACP3\Modules\ACP3\Articles\Event\Listener;
use ACP3\Modules\ACP3\Search\Event\AvailableModulesEvent;
/**
* Class OnAvailableModulesListener
* @package ACP3\Modules\ACP3\Articles\Event\Listener
*/
class OnAvailableModulesListener
{
/**
* @param \ACP3\Modules\ACP3\Search\Event\AvailableModulesEvent $availableModules
*/
public function onAvailableModules(AvailableModulesEvent $availableModules)
{
$availableModules->addAvailableModule('articles');
}
}
......@@ -9,22 +9,6 @@ services:
tags:
- { name: core.eventListener, event: articles.model.articles.after_delete, method: execute }
articles.events.on_available_modules_listener:
class: ACP3\Modules\ACP3\Articles\Event\Listener\OnAvailableModulesListener
tags:
- { name: core.eventListener, event: search.events.availableModules, method: onAvailableModules }
articles.events.on_display_search_results_listener:
class: ACP3\Modules\ACP3\Articles\Event\Listener\OnDisplaySearchResultsListener
arguments:
- '@core.acl'
- '@core.date'
- '@core.lang'
- '@core.router'
- '@articles.model.articlerepository'
tags:
- { name: core.eventListener, event: search.events.displaySearchResults, method: onDisplaySearchResults }
articles.events.update_article_cache_on_model_save_after_listener:
class: ACP3\Modules\ACP3\Articles\Event\Listener\UpdateArticleCacheOnModelSaveAfterListener
arguments:
......
services:
articles.search.search_availability:
class: ACP3\Modules\ACP3\Articles\Search\SearchAvailability
arguments:
- '@core.date'
- '@core.router'
- '@articles.model.articlerepository'
tags:
- { name: search.available_module }
......@@ -4,6 +4,7 @@ imports:
- { resource: components/events.yml }
- { resource: components/installer.yml }
- { resource: components/models.yml }
- { resource: components/search.yml }
- { resource: components/validation.yml }
services:
......
......@@ -4,33 +4,21 @@
* See the LICENCE file at the top-level module directory for licencing details.
*/
namespace ACP3\Modules\ACP3\Articles\Event\Listener;
namespace ACP3\Modules\ACP3\Articles\Search;
use ACP3\Core\ACL;
use ACP3\Core\Date;
use ACP3\Core\I18n\Translator;
use ACP3\Core\Router\RouterInterface;
use ACP3\Modules\ACP3\Articles\Installer\Schema;
use ACP3\Modules\ACP3\Articles\Model\Repository\ArticleRepository;
use ACP3\Modules\ACP3\Search\Event\SearchResultsEvent;
use ACP3\Modules\ACP3\Search\Utility\SearchAvailabilityInterface;
/**
* Class OnDisplaySearchResultsListener
* @package ACP3\Modules\ACP3\Articles\Event\Listener
*/
class OnDisplaySearchResultsListener
class SearchAvailability implements SearchAvailabilityInterface
{
/**
* @var \ACP3\Core\ACL
*/
private $acl;
/**
* @var \ACP3\Core\Date
*/
private $date;
/**
* @var \ACP3\Core\I18n\Translator
*/
private $translator;
/**
* @var \ACP3\Core\Router\RouterInterface
*/
......@@ -41,62 +29,52 @@ class OnDisplaySearchResultsListener
private $articleRepository;
/**
* OnDisplaySearchResultsListener constructor.
*
* @param \ACP3\Core\ACL $acl
* @param \ACP3\Core\Date $date
* @param \ACP3\Core\I18n\Translator $translator
* @param \ACP3\Core\Router\RouterInterface $router
* @param \ACP3\Modules\ACP3\Articles\Model\Repository\ArticleRepository $articleRepository
* SearchAvailability constructor.
* @param Date $date
* @param RouterInterface $router
* @param ArticleRepository $articleRepository
*/
public function __construct(
ACL $acl,
Date $date,
Translator $translator,
RouterInterface $router,
ArticleRepository $articleRepository
) {
$this->acl = $acl;
$this->date = $date;
$this->translator = $translator;
$this->router = $router;
$this->articleRepository = $articleRepository;
}
/**
* @param \ACP3\Modules\ACP3\Search\Event\SearchResultsEvent $displaySearchResults
* @return string
*/
public function onDisplaySearchResults(SearchResultsEvent $displaySearchResults)
public function getModuleName()
{
if (in_array('articles', $displaySearchResults->getModules())
&& $this->acl->hasPermission('frontend/articles') === true
) {
$fields = $this->mapSearchAreasToFields($displaySearchResults->getAreas());
return Schema::MODULE_NAME;
}
$results = $this->articleRepository->getAllSearchResults(
$fields,
$displaySearchResults->getSearchTerm(),
$displaySearchResults->getSortDirection(),
$this->date->getCurrentDateTime()
);
$cResults = count($results);
/**
* @param string $searchTerm
* @param string $areas
* @param string $sortDirection
* @return array
*/
public function fetchSearchResults($searchTerm, $areas, $sortDirection)
{
$fields = $this->mapSearchAreasToFields($areas);
if ($cResults > 0) {
$searchResults = [];
$searchResults['dir'] = 'articles';
for ($i = 0; $i < $cResults; ++$i) {
$searchResults['results'][$i] = $results[$i];
$searchResults['results'][$i]['hyperlink'] = $this->router->route(
'articles/index/details/id_' . $results[$i]['id']
);
}
$results = $this->articleRepository->getAllSearchResults(
$fields,
$searchTerm,
$sortDirection,
$this->date->getCurrentDateTime()
);
$cResults = count($results);
$displaySearchResults->addSearchResultsByModule(
$this->translator->t('articles', 'articles'),
$searchResults
);
}
for ($i = 0; $i < $cResults; ++$i) {
$results[$i]['hyperlink'] = $this->router->route('articles/index/details/id_' . $results[$i]['id']);
}
return $results;
}
/**
......
......@@ -19,21 +19,28 @@ class Index extends Core\Controller\AbstractFrontendAction
use Core\Cache\CacheResponseTrait;
/**
* @var \ACP3\Modules\ACP3\Feeds\Helper\FeedGenerator
* @var \ACP3\Modules\ACP3\Feeds\View\Renderer\FeedGenerator
*/
protected $feedGenerator;
/**
* @var Feeds\Utility\AvailableFeedsRegistrar
*/
protected $availableFeedsRegistrar;
/**
* @param \ACP3\Core\Controller\Context\FrontendContext $context
* @param \ACP3\Modules\ACP3\Feeds\Helper\FeedGenerator $feedGenerator
* @param \ACP3\Modules\ACP3\Feeds\View\Renderer\FeedGenerator $feedGenerator
* @param Feeds\Utility\AvailableFeedsRegistrar $availableFeedsRegistrar
*/
public function __construct(
Core\Controller\Context\FrontendContext $context,
Feeds\Helper\FeedGenerator $feedGenerator)
{
Feeds\View\Renderer\FeedGenerator $feedGenerator,
Feeds\Utility\AvailableFeedsRegistrar $availableFeedsRegistrar
) {
parent::__construct($context);
$this->feedGenerator = $feedGenerator;
$this->availableFeedsRegistrar = $availableFeedsRegistrar;
}
/**
......@@ -49,17 +56,21 @@ class Index extends Core\Controller\AbstractFrontendAction
$this->config->getSettings(Schema::MODULE_NAME)['cache_lifetime']
);
$this->feedGenerator
->setTitle($this->config->getSettings(Schema::MODULE_NAME)['site_title'])
->setDescription($this->translator->t($feed, $feed));
try {
$feedItems = $this->availableFeedsRegistrar
->getFeedItemsByModuleName($feed)
->fetchFeedItems();
$this->eventDispatcher->dispatch(
'feeds.events.displayFeed.' . strtolower($feed),
new Feeds\Event\DisplayFeed($this->feedGenerator)
);
$this->feedGenerator
->setTitle($this->config->getSettings(Schema::MODULE_NAME)['site_title'])
->setDescription($this->translator->t($feed, $feed))
->assign($feedItems);
$this->setContentType('text/xml');
return $this->response->setContent($this->feedGenerator->generateFeed());
} catch (\InvalidArgumentException $e) {
$this->setContentType('text/xml');
return $this->response->setContent($this->feedGenerator->generateFeed());
}
}
throw new Core\Controller\Exception\ResultNotExistsException();
......
<?php
/**
* Copyright (c) 2016 by the ACP3 Developers.
* See the LICENCE file at the top-level module directory for licencing details.
*/
namespace ACP3\Modules\ACP3\Feeds\DependencyInjection;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Reference;
class FeedAvailabilityCompilerPass implements CompilerPassInterface
{
/**
* You can modify the container here before it is dumped to PHP code.
*
* @param ContainerBuilder $container
*/
public function process(ContainerBuilder $container)
{
$definition = $container->findDefinition('feeds.utility.available_feeds_registrar');
$plugins = $container->findTaggedServiceIds('feeds.available_module');
foreach ($plugins as $serviceId => $tags) {
$definition->addMethodCall(
'registerModule',
[new Reference($serviceId)]
);
}
}
}
<?php
/**
* Copyright (c) 2016 by the ACP3 Developers.
* See the LICENCE file at the top-level module directory for licencing details.
*/
namespace ACP3\Modules\ACP3\Feeds\Event;
use ACP3\Modules\ACP3\Feeds\Helper\FeedGenerator;
use Symfony\Component\EventDispatcher\Event;
/**
* Class DisplayFeed
* @package ACP3\Modules\ACP3\Feeds\Event
*/
class DisplayFeed extends Event
{
/**
* @var \ACP3\Modules\ACP3\Feeds\Helper\FeedGenerator
*/
protected $feedGenerator;
/**
* @param \ACP3\Modules\ACP3\Feeds\Helper\FeedGenerator $feedGenerator
*/
public function __construct(FeedGenerator $feedGenerator)
{
$this->feedGenerator = $feedGenerator;
}
/**
* @return \ACP3\Modules\ACP3\Feeds\Helper\FeedGenerator
*/
public function getFeedGenerator()
{
return $this->feedGenerator;
}
}
......@@ -8,6 +8,7 @@ namespace ACP3\Modules\ACP3\Feeds\Event\Listener;
use ACP3\Core\View;
use ACP3\Modules\ACP3\Feeds\Utility\AvailableFeedsRegistrar;
class OnLayoutHeadListener
{
......@@ -15,18 +16,28 @@ class OnLayoutHeadListener
* @var View
*/
private $view;
/**
* @var AvailableFeedsRegistrar
*/
private $availableFeedsRegistrar;
/**
* OnLayoutHeadListener constructor.
* @param View $view
* @param AvailableFeedsRegistrar $availableFeedsRegistrar
*/
public function __construct(View $view)
{
public function __construct(
View $view,
AvailableFeedsRegistrar $availableFeedsRegistrar
) {
$this->view = $view;
$this->availableFeedsRegistrar = $availableFeedsRegistrar;
}
public function renderFeedLinkTags()
{
echo $this->view->fetchTemplate('Feeds/Partials/feed_link_tags.tpl');
$this->view->assign('available_feeds', $this->availableFeedsRegistrar->getAvailableModuleNames());
$this->view->displayTemplate('Feeds/Partials/head.feed_links.tpl');
}
}
<?php
/**
* Copyright (c) 2016 by the ACP3 Developers.
* See the LICENCE file at the top-level module directory for licencing details.
*/
namespace ACP3\Modules\ACP3\Feeds;
use ACP3\Modules\ACP3\Feeds\DependencyInjection\FeedAvailabilityCompilerPass;
use Symfony\Component\DependencyInjection\ContainerBuilder;
class ModuleRegistration extends \ACP3\Modules\ACP3\Search\ModuleRegistration
{
public function build(ContainerBuilder $containerBuilder)
{
$containerBuilder->addCompilerPass(new FeedAvailabilityCompilerPass());
}
}
<link rel="alternate"
type="application/rss+xml"
href="{uri args="feeds/index/index/feed_news"}"
title="{site_title} - {lang t="news|news"}">
<link rel="alternate"
type="application/rss+xml"
href="{uri args="feeds/index/index/feed_files"}"
title="{site_title} - {lang t="files|files"}">
{foreach $available_feeds as $feed}
<link rel="alternate"
type="application/rss+xml"
href="{uri args="feeds/index/index/feed_`$feed`"}"
title="{site_title} - {lang t="`$feed`|`$feed`"}">
{/foreach}
......@@ -11,5 +11,5 @@ services:
class: ACP3\Modules\ACP3\Feeds\Controller\Frontend\Index\Index
arguments:
- '@core.context.frontend'
- '@feeds.helper.feedgenerator'
- '@feeds.view.renderer.feedgenerator'
- '@feeds.utility.available_feeds_registrar'
......@@ -3,5 +3,6 @@ services:
class: ACP3\Modules\ACP3\Feeds\Event\Listener\OnLayoutHeadListener
arguments:
- '@core.view'
- '@feeds.utility.available_feeds_registrar'
tags:
- { name: core.eventListener, event: core.layout.head, method: renderFeedLinkTags }
......@@ -5,8 +5,11 @@ imports:
- { resource: components/validation.yml }
services:
feeds.helper.feedgenerator:
class: ACP3\Modules\ACP3\Feeds\Helper\FeedGenerator
feeds.view.renderer.feedgenerator:
class: ACP3\Modules\ACP3\Feeds\View\Renderer\FeedGenerator
arguments:
- '@core.config'
- '@core.router'
feeds.utility.available_feeds_registrar:
class: ACP3\Modules\ACP3\Feeds\Utility\AvailableFeedsRegistrar
<?php
/**
* Copyright (c) 2016 by the ACP3 Developers.
* See the LICENCE file at the top-level module directory for licencing details.
*/
namespace ACP3\Modules\ACP3\Feeds\Utility;
class AvailableFeedsRegistrar
{
/**
* @var FeedAvailabilityInterface[]
*/
protected $availableModules = [];
/**
* @param FeedAvailabilityInterface $searchAvailability
* @return $this
*/
public function registerModule(FeedAvailabilityInterface $searchAvailability)
{
$this->availableModules[$searchAvailability->getModuleName()] = $searchAvailability;
return $this;
}
/**
* @return array
*/
public function getAvailableModuleNames()
{
return array_keys($this->availableModules);
}
/**
* @param string $moduleName
* @return FeedAvailabilityInterface
*/
public function getFeedItemsByModuleName($moduleName)
{
if (isset($this->availableModules[$moduleName])) {
return $this->availableModules[$moduleName];
}
throw new \InvalidArgumentException('There are no available feeds items for the requested module "' . $moduleName . '".');
}
}
<?php
/**
* Copyright (c) 2016 by the ACP3 Developers.
* See the LICENCE file at the top-level module directory for licencing details.
*/
namespace ACP3\Modules\ACP3\Feeds\Utility;
interface FeedAvailabilityInterface
{
/**
* @return string
*/
public function getModuleName();
/**
* @return array
*/
public function fetchFeedItems();
}
<?php
/**
* Copyright (c) 2016 by the ACP3 Developers.
* See the LICENCE file at the top-level module directory for licencing details.
*/
namespace ACP3\Modules\ACP3\Feeds\Helper;
namespace ACP3\Modules\ACP3\Feeds\View\Renderer;
use ACP3\Core\Router\RouterInterface;
use ACP3\Core\Settings\SettingsInterface;
......@@ -9,7 +13,7 @@ use FeedWriter\ATOM;
/**
* Renderer for the output of RSS and ATOM News feeds
* @package ACP3\Modules\ACP3\Feeds\Helpe
* @package ACP3\Modules\ACP3\Feeds\View\Renderer
*/
class FeedGenerator
{
......@@ -46,8 +50,8 @@ class FeedGenerator
*/
public function __construct(
SettingsInterface $config,
RouterInterface $router)
{
RouterInterface $router
) {
$this->config = $config;
$this->router = $router;
}
......
<?php
namespace ACP3\Modules\ACP3\Files\Event\Listener;
use ACP3\Modules\ACP3\Search\Event\AvailableModulesEvent;
/**
* Class OnAvailableModulesListener
* @package ACP3\Modules\ACP3\Files\Event\Listener
*/
class OnAvailableModulesListener
{
/**
* @param \ACP3\Modules\ACP3\Search\Event\AvailableModulesEvent $availableModules
*/
public function onAvailableModules(AvailableModulesEvent $availableModules)
{
$availableModules->addAvailableModule('files');
}
}
<?php
namespace ACP3\Modules\ACP3\Files\Event\Listener;
/**
* Copyright (c) 2016 by the ACP3 Developers.
* See the LICENCE file at the top-level module directory for licencing details.
*/
namespace ACP3\Modules\ACP3\Files\Feeds;
use ACP3\Core\Date;
use ACP3\Core\Helpers\StringFormatter;
use ACP3\Core\Router\RouterInterface;
use ACP3\Modules\ACP3\Feeds\Event\DisplayFeed;
use ACP3\Modules\ACP3\Feeds\Utility\FeedAvailabilityInterface;
use ACP3\Modules\ACP3\Files\Installer\Schema;
use ACP3\Modules\ACP3\Files\Model\Repository\FilesRepository;
/**
* Class OnDisplayFeedListener
* @package ACP3\Modules\ACP3\Files\Event\Listener
*/
class OnDisplayFeedListener
class FeedAvailability implements FeedAvailabilityInterface
{
/**
* @var \ACP3\Core\Date
......@@ -33,9 +36,9 @@ class OnDisplayFeedListener
/**
* OnDisplayFeedListener constructor.
*
* @param \ACP3\Core\Date $date
* @param \ACP3\Core\Router\RouterInterface $router
* @param \ACP3\Core\Helpers\StringFormatter $formatter
* @param \ACP3\Core\Date $date
* @param \ACP3\Core\Router\RouterInterface $router
* @param \ACP3\Core\Helpers\StringFormatter $formatter
* @param \ACP3\Modules\ACP3\Files\Model\Repository\FilesRepository $filesRepository
*/
public function __construct(
......@@ -51,9 +54,17 @@ class OnDisplayFeedListener
}
/**
* @param \ACP3\Modules\ACP3\Feeds\Event\DisplayFeed $displayFeed
* @return string
*/
public function getModuleName()
{
return Schema::MODULE_NAME;
}
/**
* @return array
*/
public function onDisplayFeed(DisplayFeed $displayFeed)
public function fetchFeedItems()
{
$items = [];
$results = $this->filesRepository->getAll($this->date->getCurrentDateTime(), 10);
......@@ -68,6 +79,6 @@ class OnDisplayFeedListener
];
}
$displayFeed->getFeedGenerator()->assign($items);
return $items;