diff --git a/core/modules/aggregator/aggregator.module b/core/modules/aggregator/aggregator.module index f7a908a..b5124bd 100644 --- a/core/modules/aggregator/aggregator.module +++ b/core/modules/aggregator/aggregator.module @@ -189,12 +189,8 @@ function aggregator_menu() { 'file' => 'aggregator.admin.inc', ); $items['aggregator/sources/%aggregator_feed'] = array( - 'title callback' => 'entity_page_label', - 'title arguments' => array(2), - 'page callback' => 'aggregator_page_source', - 'page arguments' => array(2), - 'access arguments' => array('access news feeds'), - 'file' => 'aggregator.pages.inc', + 'title' => 'View', + 'route_name' => 'aggregator_page_source', ); $items['aggregator/sources/%aggregator_feed/view'] = array( 'title' => 'View', diff --git a/core/modules/aggregator/aggregator.pages.inc b/core/modules/aggregator/aggregator.pages.inc index c524505..30233e6 100644 --- a/core/modules/aggregator/aggregator.pages.inc +++ b/core/modules/aggregator/aggregator.pages.inc @@ -20,6 +20,7 @@ * @see aggregator_menu() */ function aggregator_page_source(Feed $feed) { + drupal_set_title($feed->label()); $feed_source = entity_view($feed, 'default'); // It is safe to include the fid in the query because it's loaded from the diff --git a/core/modules/aggregator/aggregator.routing.yml b/core/modules/aggregator/aggregator.routing.yml index 2c69045..d86de63 100644 --- a/core/modules/aggregator/aggregator.routing.yml +++ b/core/modules/aggregator/aggregator.routing.yml @@ -47,6 +47,13 @@ aggregator_opml_add: requirements: _permission: 'administer news feeds' +aggregator_page_source: + pattern: 'aggregator/sources/{aggregator_feed}' + defaults: + _content: '\Drupal\aggregator\Controller\AggregatorController::viewFeed' + requirements: + _permission: 'access news feeds' + aggregator_page_last: pattern: '/aggregator' defaults: diff --git a/core/modules/aggregator/lib/Drupal/aggregator/Controller/AggregatorController.php b/core/modules/aggregator/lib/Drupal/aggregator/Controller/AggregatorController.php index a8b1d80..fafb698 100644 --- a/core/modules/aggregator/lib/Drupal/aggregator/Controller/AggregatorController.php +++ b/core/modules/aggregator/lib/Drupal/aggregator/Controller/AggregatorController.php @@ -8,11 +8,11 @@ namespace Drupal\aggregator\Controller; use Drupal\aggregator\FeedInterface; +use Drupal\aggregator\ItemInterface; use Drupal\Core\Config\ConfigFactory; use Drupal\Core\Controller\ControllerInterface; use Drupal\Core\Database\Connection; use Drupal\Core\Entity\EntityManager; -use Drupal\Core\Extension\ModuleHandlerInterface; use Drupal\Core\Routing\PathBasedGeneratorInterface; use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\HttpFoundation\RedirectResponse; @@ -46,13 +46,6 @@ class AggregatorController implements ControllerInterface { protected $database; /** - * The module handler. - * - * @var \Drupal\Core\Extension\ModuleHandlerInterface - */ - protected $moduleHandler; - - /** * The url generator. * * @var \Drupal\Core\Routing\PathBasedGeneratorInterface @@ -70,14 +63,11 @@ class AggregatorController implements ControllerInterface { * The database connection. * @param \Drupal\Core\Config\ConfigFactory $config_factory * The config factory. - * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler - * The module handler. */ - public function __construct(EntityManager $entity_manager, Connection $database, ConfigFactory $config_factory, ModuleHandlerInterface $module_handler, PathBasedGeneratorInterface $url_generator) { + public function __construct(EntityManager $entity_manager, Connection $database, ConfigFactory $config_factory, PathBasedGeneratorInterface $url_generator) { $this->entityManager = $entity_manager; $this->database = $database; $this->configFactory = $config_factory; - $this->moduleHandler = $module_handler; $this->urlGenerator = $url_generator; } @@ -89,7 +79,6 @@ public static function create(ContainerInterface $container) { $container->get('plugin.manager.entity'), $container->get('database'), $container->get('config.factory'), - $container->get('module_handler'), $container->get('url_generator') ); } @@ -111,6 +100,54 @@ public function feedAdd() { } /** + * Displays all the items captured from the particular feed. + * + * @param \Drupal\aggregator\FeedInterface $aggregator_feed + * The feed for which to display all items. + * + * @return string + * The rendered list of items for the feed. + */ + public function viewFeed(FeedInterface $aggregator_feed) { + drupal_set_title($aggregator_feed->label()); + $feed_source = $this->entityManager->getRenderController($aggregator_feed->entityType()) + ->view($aggregator_feed, 'default'); + // Load aggregator feed item for the particular feed id. + $items = $this->entityManager + ->getStorageController('aggregator_item') + ->loadFeedItems('source', $aggregator_feed); + // Print the feed items. + return $this->buildPageList($items, $feed_source); + } + + /** + * Prints an aggregator page listing a number of feed items. + * + * @param \Drupal\aggregator\ItemInterface[] $items + * The items to be listed. + * @param array|string $feed_source + * The feed source URL. + * + * @return array + * The rendered list of items for the feed. + */ + protected function buildPageList(array $items, $feed_source = '') { + // Assemble output. + $build = array( + '#type' => 'container', + '#attributes' => array('class' => array('aggregator-wrapper')), + ); + $build['feed_source'] = is_array($feed_source) ? $feed_source : array('#markup' => $feed_source); + if ($items) { + $build['items'] = $this->entityManager->getRenderController(reset($items)->entityType()) + ->viewMultiple($items, 'default'); + $build['pager']['#theme'] = 'pager'; + } + return $build; + } + + + /** * Refreshes a feed, then redirects to the overview page. * * @param \Drupal\aggregator\FeedInterface $aggregator_feed @@ -228,9 +265,6 @@ public function adminOverview() { * A render array. */ public function categories() { - // @todo Refactor this once all controller conversions are complete. - $this->moduleHandler->loadInclude('aggregator', 'inc', 'aggregator.pages'); - $result = $this->database->query('SELECT c.cid, c.title, c.description FROM {aggregator_category} c LEFT JOIN {aggregator_category_item} ci ON c.cid = ci.cid LEFT JOIN {aggregator_item} i ON ci.iid = i.iid GROUP BY c.cid, c.title, c.description'); $build = array( @@ -242,7 +276,10 @@ public function categories() { foreach ($result as $category) { $summary_items = array(); if ($aggregator_summary_items) { - if ($items = aggregator_load_feed_items('category', $category, $aggregator_summary_items)) { + $items = $this->entityManager + ->getStorageController('aggregator_item') + ->loadFeedItems('category', $category, $aggregator_summary_items); + if ($items) { $summary_items = $this->entityManager->getRenderController('aggregator_item')->viewMultiple($items, 'summary'); } } @@ -265,14 +302,10 @@ public function categories() { public function pageLast() { drupal_add_feed('aggregator/rss', $this->configFactory->get('system.site')->get('name') . ' ' . t('aggregator')); - // @todo Refactor this function once after all controller conversions are - // done. - $this->moduleHandler->loadInclude('aggregator', 'inc', 'aggregator.pages'); - $items = aggregator_load_feed_items('sum'); - - // @todo Refactor this function once after all controller conversions are - // done. - return _aggregator_page_list($items, arg(1)); + $items = $this->entityManager + ->getStorageController('aggregator_item') + ->loadFeedItems('sum'); + return $this->buildPageList($items); } /** @@ -291,10 +324,6 @@ public function sources() { '#sorted' => TRUE, ); - // @todo remove this once aggregator_load_feed_items() is refactored after - // http://drupal.org/node/15266 is in. - $this->moduleHandler->loadInclude('aggregator', 'inc', 'aggregator.pages'); - foreach ($feeds as $feed) { // Most recent items: $summary_items = array(); @@ -302,7 +331,10 @@ public function sources() { ->get('aggregator.settings') ->get('source.list_max'); if ($aggregator_summary_items) { - if ($items = aggregator_load_feed_items('source', $feed, $aggregator_summary_items)) { + $items = $this->entityManager + ->getStorageController('aggregator_item') + ->loadFeedItems('source', $feed, $aggregator_summary_items); + if ($items) { $summary_items = $this->entityManager ->getRenderController('aggregator_item') ->viewMultiple($items, 'summary'); diff --git a/core/modules/aggregator/lib/Drupal/aggregator/ItemStorageController.php b/core/modules/aggregator/lib/Drupal/aggregator/ItemStorageController.php index 016e8ae..73ef25b 100644 --- a/core/modules/aggregator/lib/Drupal/aggregator/ItemStorageController.php +++ b/core/modules/aggregator/lib/Drupal/aggregator/ItemStorageController.php @@ -112,4 +112,44 @@ public function saveCategories(Item $item) { ->execute(); } } + + /** + * {@inheritdoc} + */ + public function loadFeedItems($type, $data = NULL, $limit = 20) { + switch ($type) { + case 'sum': + $query = $this->database->select('aggregator_item', 'i'); + $query->join('aggregator_feed', 'f', 'i.fid = f.fid'); + $query->fields('i', array('iid')); + break; + case 'source': + $query = $this->database->select('aggregator_item', 'i'); + $query + ->fields('i', array('iid')) + ->condition('i.fid', $data->id()); + break; + case 'category': + $query = $this->database->select('aggregator_category_item', 'c'); + $query->leftJoin('aggregator_item', 'i', 'c.iid = i.iid'); + $query->leftJoin('aggregator_feed', 'f', 'i.fid = f.fid'); + $query + ->fields('i', array('iid')) + ->condition('cid', $data->cid); + break; + } + + $result = $query + ->extend('Drupal\Core\Database\Query\PagerSelectExtender') + ->limit($limit) + ->orderBy('i.timestamp', 'DESC') + ->orderBy('i.iid', 'DESC') + ->execute() + ->fetchCol(); + + $feed_items = $this->load($result); + + return $feed_items; + } + } diff --git a/core/modules/aggregator/lib/Drupal/aggregator/ItemStorageControllerInterface.php b/core/modules/aggregator/lib/Drupal/aggregator/ItemStorageControllerInterface.php index 5c00345..07c1784 100644 --- a/core/modules/aggregator/lib/Drupal/aggregator/ItemStorageControllerInterface.php +++ b/core/modules/aggregator/lib/Drupal/aggregator/ItemStorageControllerInterface.php @@ -41,4 +41,30 @@ public function deleteCategories(array $entities); * The storage backend should save the categories of this item. */ public function saveCategories(Item $item); + + /** + * Loads and optionally filters feed items. + * + * @param string $type + * The type of filter for the items. Possible values are: + * - sum: No filtering. + * - source: Filter the feed items, limiting the result to items from a + * single source. + * - category: Filter the feed items by category. + * @param \Drupal\aggregator\FeedInterface|array $data + * Feed or category data used for filtering. The type and value of $data + * depends on $type: + * - source: $data is an object with $data->fid identifying the feed used to + * as filter. + * - category: $data is an array with $data['cid'] being the category id to + * filter on. + * The $data parameter is not used when $type is 'sum'. + * @param int $limit + * Limit for fetching the number of feed items. + * + * @return array + * An array of the feed items. + */ + public function loadFeedItems($type, $data = NULL, $limit = 20); + }