AggregatorController.php 9.22 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\DependencyInjection\ContainerInjectionInterface;
13
14
use Drupal\aggregator\FeedInterface;
use Drupal\aggregator\ItemInterface;
15
use Drupal\Core\Database\Connection;
16
17
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpFoundation\Request;
18
use Symfony\Component\HttpFoundation\Response;
19
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
20
21
22
23

/**
 * Returns responses for aggregator module routes.
 */
24
class AggregatorController extends ControllerBase implements ContainerInjectionInterface {
25

26
  /**
27
   * The database connection.
28
   *
29
   * @var \Drupal\Core\Database\Connection;
30
   */
31
  protected $database;
32

33
  /**
34
   * Constructs a \Drupal\aggregator\Controller\AggregatorController object.
35
   *
36
37
   * @param \Drupal\Core\Database\Connection $database
   *   The database connection.
38
   */
39
  public function __construct(Connection $database) {
40
    $this->database = $database;
41
42
43
44
45
46
  }

  /**
   * {inheritdoc}
   */
  public static function create(ContainerInterface $container) {
47
    return new static(
48
      $container->get('database')
49
    );
50
51
52
53
54
55
56
57
58
  }

  /**
   * Presents the aggregator feed creation form.
   *
   * @return array
   *   A form array as expected by drupal_render().
   */
  public function feedAdd() {
59
60
    $entity_manager = $this->entityManager();
    $feed = $entity_manager->getStorageController('aggregator_feed')
61
62
63
      ->create(array(
        'refresh' => 3600,
      ));
64
65
66
67
68
69
70
71
72
73
74
75
76
77
    return $entity_manager->getForm($feed);
  }

  /**
   * 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();
78
    $feed_source = $entity_manager->getViewBuilder('aggregator_feed')
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
      ->view($aggregator_feed, 'default');
    // Load aggregator feed item for the particular feed id.
    $items = $entity_manager->getStorageController('aggregator_item')->loadByFeed($aggregator_feed->id());
    // 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) {
106
      $build['items'] = $this->entityManager()->getViewBuilder('aggregator_item')
107
108
109
110
        ->viewMultiple($items, 'default');
      $build['pager'] = array('#theme' => 'pager');
    }
    return $build;
111
112
  }

113
114
115
116
117
118
119
120
121
122
123
124
  /**
   * 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.
   */
125
  public function feedRefresh(FeedInterface $aggregator_feed) {
126
127
    // @todo after https://drupal.org/node/1972246 find a new place for it.
    aggregator_refresh($aggregator_feed);
128
    return $this->redirect('aggregator.admin_overview');
129
130
  }

131
132
133
134
135
136
137
  /**
   * Displays the aggregator administration page.
   *
   * @return array
   *   A render array as expected by drupal_render().
   */
  public function adminOverview() {
138
    $result = $this->database->query('SELECT f.fid, f.title, f.url, f.refresh, f.checked, f.link, f.description, f.hash, f.etag, f.modified, f.image, COUNT(i.iid) AS items FROM {aggregator_feed} f LEFT JOIN {aggregator_item} i ON f.fid = i.fid GROUP BY f.fid, f.title, f.url, f.refresh, f.checked, f.link, f.description, f.hash, f.etag, f.modified, f.image ORDER BY f.title');
139

140
    $header = array($this->t('Title'), $this->t('Items'), $this->t('Last update'), $this->t('Next update'), $this->t('Operations'));
141
142
143
144
145
    $rows = array();
    foreach ($result as $feed) {
      $row = array();
      $row[] = l($feed->title, "aggregator/sources/$feed->fid");
      $row[] = format_plural($feed->items, '1 item', '@count items');
146
147
      $row[] = ($feed->checked ? $this->t('@time ago', array('@time' => format_interval(REQUEST_TIME - $feed->checked))) : $this->t('never'));
      $row[] = ($feed->checked && $feed->refresh ? $this->t('%time left', array('%time' => format_interval($feed->checked + $feed->refresh - REQUEST_TIME))) : $this->t('never'));
148
149
      $links = array();
      $links['edit'] = array(
150
        'title' => $this->t('Edit'),
151
152
        'route_name' => 'aggregator.feed_edit',
        'route_parameters' => array('aggregator_feed' => $feed->fid),
153
154
      );
      $links['delete'] = array(
155
        'title' => $this->t('Delete'),
156
157
        'route_name' => 'aggregator.feed_delete',
        'route_parameters' => array('aggregator_feed' => $feed->fid),
158
159
      );
      $links['remove'] = array(
160
        'title' => $this->t('Remove items'),
161
162
        'route_name' => 'aggregator.feed_items_delete',
        'route_parameters' => array('aggregator_feed' => $feed->fid),
163
164
      );
      $links['update'] = array(
165
        'title' => $this->t('Update items'),
166
167
        'route_name' => 'aggregator.feed_refresh',
        'route_parameters' => array('aggregator_feed' => $feed->fid),
168
169
170
171
172
173
174
175
176
177
      );
      $row[] = array(
        'data' => array(
          '#type' => 'operations',
          '#links' => $links,
        ),
      );
      $rows[] = $row;
    }
    $build['feeds'] = array(
178
      '#prefix' => '<h3>' . $this->t('Feed overview') . '</h3>',
179
180
181
      '#theme' => 'table',
      '#header' => $header,
      '#rows' => $rows,
182
      '#empty' => $this->t('No feeds available. <a href="@link">Add feed</a>.', array('@link' => $this->urlGenerator()->generateFromPath('admin/config/services/aggregator/add/feed'))),
183
184
    );

185
186
187
    return $build;
  }

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

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

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

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

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

246
  /**
247
   * Generates an OPML representation of all feeds.
248
249
250
   *
   * @return \Symfony\Component\HttpFoundation\Response
   *   The response containing the OPML.
251
   */
252
  public function opmlPage() {
253
    $result = $this->database->query('SELECT * FROM {aggregator_feed} ORDER BY title');
254
255
256
257
258
259
260
261
262
263
264
265
266

    $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;
267
268
  }

269
270
271
272
273
274
275
276
277
278
279
280
281
  /**
   * 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());
  }

282
}