AggregatorController.php 9.16 KB
Newer Older
1 2 3 4
<?php

/**
 * @file
5
 * Contains \Drupal\aggregator\Controller\AggregatorController.
6 7
 */

8
namespace Drupal\aggregator\Controller;
9

10
use Drupal\Component\Utility\Xss;
11
use Drupal\Core\Controller\ControllerBase;
12
use Drupal\Core\Datetime\Date as DateFormatter;
13
use Drupal\aggregator\FeedInterface;
14
use Symfony\Component\HttpFoundation\Request;
15
use Symfony\Component\HttpFoundation\Response;
16
use Symfony\Component\DependencyInjection\ContainerInterface;
17 18 19 20

/**
 * Returns responses for aggregator module routes.
 */
21
class AggregatorController extends ControllerBase {
22

23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
  /**
   * The date formatter service.
   *
   * @var \Drupal\Core\Datetime\Date
   */
  protected $dateFormatter;

  /**
   * Constructs a \Drupal\aggregator\Controller\AggregatorController object.
   *
   * @param \Drupal\Core\Datetime\Date $date_formatter
   *    The date formatter service.
   */
  public function __construct(DateFormatter $date_formatter) {
    $this->dateFormatter = $date_formatter;
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container) {
    return new static(
      $container->get('date')
    );
  }

49 50 51 52 53 54 55
  /**
   * Presents the aggregator feed creation form.
   *
   * @return array
   *   A form array as expected by drupal_render().
   */
  public function feedAdd() {
56
    $feed = $this->entityManager()->getStorage('aggregator_feed')
57 58 59
      ->create(array(
        'refresh' => 3600,
      ));
60
    return $this->entityFormBuilder()->getForm($feed);
61 62 63 64 65 66 67 68 69 70 71 72 73
  }

  /**
   * Displays all the items captured from the particular feed.
   *
   * @param \Drupal\aggregator\FeedInterface $aggregator_feed
   *   The feed for which to display all items.
   *
   * @return array
   *   The rendered list of items for the feed.
   */
  public function viewFeed(FeedInterface $aggregator_feed) {
    $entity_manager = $this->entityManager();
74
    $feed_source = $entity_manager->getViewBuilder('aggregator_feed')
75 76
      ->view($aggregator_feed, 'default');
    // Load aggregator feed item for the particular feed id.
77
    $items = $entity_manager->getStorage('aggregator_item')->loadByFeed($aggregator_feed->id(), 20);
78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101
    // Print the feed items.
    $build = $this->buildPageList($items, $feed_source);
    return $build;
  }

  /**
   * Builds a listing of aggregator 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) {
102
      $build['items'] = $this->entityManager()->getViewBuilder('aggregator_item')
103 104 105 106
        ->viewMultiple($items, 'default');
      $build['pager'] = array('#theme' => 'pager');
    }
    return $build;
107 108
  }

109 110 111 112 113 114 115 116 117 118 119 120
  /**
   * Refreshes a feed, then redirects to the overview page.
   *
   * @param \Drupal\aggregator\FeedInterface $aggregator_feed
   *   An object describing the feed to be refreshed.
   *
   * @return \Symfony\Component\HttpFoundation\RedirectResponse
   *   A redirection to the admin overview page.
   *
   * @throws \Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException
   *   If the query token is missing or invalid.
   */
121
  public function feedRefresh(FeedInterface $aggregator_feed) {
122 123 124 125
    $message = $aggregator_feed->refreshItems()
      ? $this->t('There is new syndicated content from %site.', array('%site' => $aggregator_feed->label()))
      : $this->t('There is no new syndicated content from %site.', array('%site' => $aggregator_feed->label()));
    drupal_set_message($message);
126
    return $this->redirect('aggregator.admin_overview');
127 128
  }

129 130 131 132 133 134 135
  /**
   * Displays the aggregator administration page.
   *
   * @return array
   *   A render array as expected by drupal_render().
   */
  public function adminOverview() {
136
    $entity_manager = $this->entityManager();
137
    $feeds = $entity_manager->getStorage('aggregator_feed')
138
      ->loadMultiple();
139

140
    $header = array($this->t('Title'), $this->t('Items'), $this->t('Last update'), $this->t('Next update'), $this->t('Operations'));
141
    $rows = array();
142
    foreach ($feeds as $feed) {
143
      $row = array();
144
      $row[] = l($feed->label(), "aggregator/sources/" . $feed->id());
145
      $row[] = $this->dateFormatter->formatInterval($entity_manager->getStorage('aggregator_item')->getItemCount($feed), '1 item', '@count items');
146 147
      $last_checked = $feed->getLastCheckedTime();
      $refresh_rate = $feed->getRefreshRate();
148 149
      $row[] = ($last_checked ? $this->t('@time ago', array('@time' => $this->dateFormatter->formatInterval(REQUEST_TIME - $last_checked))) : $this->t('never'));
      $row[] = ($last_checked && $refresh_rate ? $this->t('%time left', array('%time' => $this->dateFormatter->formatInterval($last_checked + $refresh_rate - REQUEST_TIME))) : $this->t('never'));
150
      $links['edit'] = array(
151
        'title' => $this->t('Edit'),
152
        'route_name' => 'aggregator.feed_configure',
153
        'route_parameters' => array('aggregator_feed' => $feed->id()),
154 155
      );
      $links['delete'] = array(
156
        'title' => $this->t('Delete'),
157
        'route_name' => 'aggregator.feed_delete',
158
        'route_parameters' => array('aggregator_feed' => $feed->id()),
159
      );
160 161
      $links['delete_items'] = array(
        'title' => $this->t('Delete items'),
162
        'route_name' => 'aggregator.feed_items_delete',
163
        'route_parameters' => array('aggregator_feed' => $feed->id()),
164 165
      );
      $links['update'] = array(
166
        'title' => $this->t('Update items'),
167
        'route_name' => 'aggregator.feed_refresh',
168
        'route_parameters' => array('aggregator_feed' => $feed->id()),
169 170 171 172 173 174 175 176 177 178
      );
      $row[] = array(
        'data' => array(
          '#type' => 'operations',
          '#links' => $links,
        ),
      );
      $rows[] = $row;
    }
    $build['feeds'] = array(
179
      '#prefix' => '<h3>' . $this->t('Feed overview') . '</h3>',
180
      '#type' => 'table',
181 182
      '#header' => $header,
      '#rows' => $rows,
183
      '#empty' => $this->t('No feeds available. <a href="@link">Add feed</a>.', array('@link' => $this->url('aggregator.feed_add'))),
184 185
    );

186 187 188
    return $build;
  }

189 190 191 192 193 194 195
  /**
   * Displays the most recent items gathered from any feed.
   *
   * @return string
   *   The rendered list of items for the feed.
   */
  public function pageLast() {
196
    $items = $this->entityManager()->getStorage('aggregator_item')->loadAll(20);
197 198 199
    $build = $this->buildPageList($items);
    $build['#attached']['drupal_add_feed'][] = array('aggregator/rss', $this->config('system.site')->get('name') . ' ' . $this->t('aggregator'));
    return $build;
200
  }
201 202 203 204 205 206 207 208

  /**
   * Displays all the feeds used by the Aggregator module.
   *
   * @return array
   *   A render array as expected by drupal_render().
   */
  public function sources() {
209
    $entity_manager = $this->entityManager();
210

211
    $feeds = $entity_manager->getStorage('aggregator_feed')->loadMultiple();
212 213 214 215 216 217 218 219 220 221

    $build = array(
      '#type' => 'container',
      '#attributes' => array('class' => array('aggregator-wrapper')),
      '#sorted' => TRUE,
    );

    foreach ($feeds as $feed) {
      // Most recent items:
      $summary_items = array();
222
      $aggregator_summary_items = $this->config('aggregator.settings')
223 224
        ->get('source.list_max');
      if ($aggregator_summary_items) {
225
        $items = $entity_manager->getStorage('aggregator_item')
226
          ->loadByFeed($feed->id(), 20);
227
        if ($items) {
228
          $summary_items = $entity_manager->getViewBuilder('aggregator_item')
229 230 231
            ->viewMultiple($items, 'summary');
        }
      }
232
      $feed->url = $this->url('aggregator.feed_view', array('aggregator_feed' => $feed->id()));
233 234 235 236
      $build[$feed->id()] = array(
        '#theme' => 'aggregator_summary_items',
        '#summary_items' => $summary_items,
        '#source' => $feed,
237 238 239
        '#cache' => array(
          'tags' => $feed->getCacheTag(),
        ),
240 241 242 243 244
      );
    }
    $build['feed_icon'] = array(
      '#theme' => 'feed_icon',
      '#url' => 'aggregator/opml',
245
      '#title' => $this->t('OPML feed'),
246 247 248 249
    );
    return $build;
  }

250
  /**
251
   * Generates an OPML representation of all feeds.
252 253 254
   *
   * @return \Symfony\Component\HttpFoundation\Response
   *   The response containing the OPML.
255
   */
256
  public function opmlPage() {
257
     $feeds = $this->entityManager()
258
      ->getStorage('aggregator_feed')
259
      ->loadMultiple();
260 261 262 263 264 265 266 267 268 269 270 271 272

    $feeds = $result->fetchAll();
    $aggregator_page_opml = array(
      '#theme' => 'aggregator_page_opml',
      '#feeds' => $feeds,
    );
    $output = drupal_render($aggregator_page_opml);

    $response = new Response();
    $response->headers->set('Content-Type', 'text/xml; charset=utf-8');
    $response->setContent($output);

    return $response;
273 274
  }

275 276 277 278 279 280 281 282 283 284 285 286 287
  /**
   * Route title callback.
   *
   * @param \Drupal\aggregator\FeedInterface $aggregator_feed
   *   The aggregator feed.
   *
   * @return string
   *   The feed label.
   */
  public function feedTitle(FeedInterface $aggregator_feed) {
    return Xss::filter($aggregator_feed->label());
  }

288
}