comparison modules/aggregator/aggregator.pages.inc @ 1:c1f4ac30525a 6.0

Drupal 6.0
author Franck Deroche <webmaster@defr.org>
date Tue, 23 Dec 2008 14:28:28 +0100
parents
children 589fb7c02327
comparison
equal deleted inserted replaced
0:5a113a1c4740 1:c1f4ac30525a
1 <?php
2 // $Id: aggregator.pages.inc,v 1.12 2008/01/08 10:35:40 goba Exp $
3
4 /**
5 * @file
6 * User page callbacks for the aggregator module.
7 */
8
9 /**
10 * Menu callback; displays the most recent items gathered from any feed.
11 *
12 * @return
13 * The items HTML.
14 */
15 function aggregator_page_last() {
16 drupal_add_feed(url('aggregator/rss'), variable_get('site_name', 'Drupal') .' '. t('aggregator'));
17
18 $items = aggregator_feed_items_load('SELECT i.*, f.title AS ftitle, f.link AS flink FROM {aggregator_item} i INNER JOIN {aggregator_feed} f ON i.fid = f.fid ORDER BY i.timestamp DESC, i.iid DESC');
19
20 return _aggregator_page_list($items, arg(1));
21 }
22
23 /**
24 * Menu callback; displays all the items captured from a particular feed.
25 *
26 * If there are two arguments then this function is the categorize form.
27 *
28 * @param $arg1
29 * If there are two arguments then $arg1 is $form_state. Otherwise, $arg1 is $feed.
30 * @param $arg2
31 * If there are two arguments then $arg2 is feed.
32 * @return
33 * The items HTML.
34 */
35 function aggregator_page_source($arg1, $arg2 = NULL) {
36 // If there are two arguments then this function is the categorize form, and
37 // $arg1 is $form_state and $arg2 is $feed. Otherwise, $arg1 is $feed.
38 $feed = is_array($arg2) ? $arg2 : $arg1;
39 $feed = (object)$feed;
40 drupal_set_title(check_plain($feed->title));
41 $feed_source = theme('aggregator_feed_source', $feed);
42
43 // It is safe to include the fid in the query because it's loaded from the
44 // database by aggregator_feed_load.
45 $items = aggregator_feed_items_load('SELECT * FROM {aggregator_item} WHERE fid = '. $feed->fid .' ORDER BY timestamp DESC, iid DESC');
46
47 return _aggregator_page_list($items, arg(3), $feed_source);
48 }
49
50 /**
51 * Menu callback; displays all the items aggregated in a particular category.
52 *
53 * If there are two arguments then this function is called as a form.
54 *
55 * @param $arg1
56 * If there are two arguments then $arg1 is $form_state. Otherwise, $arg1 is $category.
57 * @param $arg2
58 * If there are two arguments then $arg2 is $category.
59 * @return
60 * The items HTML.
61 */
62 function aggregator_page_category($arg1, $arg2 = NULL) {
63 drupal_set_breadcrumb(array_merge(drupal_get_breadcrumb(), array(l(t('Categories'), 'aggregator/categories'))));
64 // If there are two arguments then we are called as a form, $arg1 is
65 // $form_state and $arg2 is $category. Otherwise, $arg1 is $category.
66 $category = is_array($arg2) ? $arg2 : $arg1;
67
68 drupal_add_feed(url('aggregator/rss/'. $category['cid']), variable_get('site_name', 'Drupal') .' '. t('aggregator - @title', array('@title' => $category['title'])));
69
70 // It is safe to include the cid in the query because it's loaded from the
71 // database by aggregator_category_load.
72 $items = aggregator_feed_items_load('SELECT i.*, f.title AS ftitle, f.link AS flink FROM {aggregator_category_item} c LEFT JOIN {aggregator_item} i ON c.iid = i.iid LEFT JOIN {aggregator_feed} f ON i.fid = f.fid WHERE cid = '. $category['cid'] .' ORDER BY timestamp DESC, i.iid DESC');
73
74 return _aggregator_page_list($items, arg(3));
75 }
76
77 /**
78 * Load feed items by passing a SQL query.
79 *
80 * @param $sql
81 * The query to be executed.
82 * @return
83 * An array of the feed items.
84 */
85 function aggregator_feed_items_load($sql) {
86 $items = array();
87 if (isset($sql)) {
88 $result = pager_query($sql, 20);
89 while ($item = db_fetch_object($result)) {
90 $result_category = db_query('SELECT c.title, c.cid FROM {aggregator_category_item} ci LEFT JOIN {aggregator_category} c ON ci.cid = c.cid WHERE ci.iid = %d ORDER BY c.title', $item->iid);
91 $item->categories = array();
92 while ($item_categories = db_fetch_object($result_category)) {
93 $item->categories[] = $item_categories;
94 }
95 $items[$item->iid] = $item;
96 }
97 }
98 return $items;
99 }
100
101 /**
102 * Prints an aggregator page listing a number of feed items.
103 *
104 * Various menu callbacks use this function to print their feeds.
105 *
106 * @param $items
107 * The items to be listed.
108 * @param $op
109 * Which form should be added to the items. Only 'categorize' is now recognized.
110 * @param $feed_source
111 * The feed source URL.
112 * @return
113 * The items HTML.
114 */
115 function _aggregator_page_list($items, $op, $feed_source = '') {
116 if (user_access('administer news feeds') && ($op == 'categorize')) {
117 // Get form data.
118 $output = aggregator_categorize_items($items, $feed_source);
119 }
120 else {
121 // Assemble themed output.
122 $output = $feed_source;
123 foreach ($items as $item) {
124 $output .= theme('aggregator_item', $item);
125 }
126 $output = theme('aggregator_wrapper', $output);
127 }
128 return $output;
129 }
130
131 /**
132 * Form builder; build the page list form.
133 *
134 * @param $items
135 * An array of the feed items.
136 * @param $feed_source
137 * The feed source URL.
138 * @return
139 * The form structure.
140 * @ingroup forms
141 * @see aggregator_categorize_items_validate()
142 * @see aggregator_categorize_items_submit()
143 */
144 function aggregator_categorize_items($items, $feed_source = '') {
145 $form['#submit'][] = 'aggregator_categorize_items_submit';
146 $form['#validate'][] = 'aggregator_categorize_items_validate';
147 $form['#theme'] = 'aggregator_categorize_items';
148 $form['feed_source'] = array('#value' => $feed_source);
149 $categories = array();
150 $done = FALSE;
151 $form['items'] = array();
152 $form['categories'] = array('#tree' => TRUE);
153 foreach ($items as $item) {
154 $form['items'][$item->iid] = array('#value' => theme('aggregator_item', $item));
155 $form['categories'][$item->iid] = array();
156 $categories_result = db_query('SELECT c.cid, c.title, ci.iid FROM {aggregator_category} c LEFT JOIN {aggregator_category_item} ci ON c.cid = ci.cid AND ci.iid = %d', $item->iid);
157 $selected = array();
158 while ($category = db_fetch_object($categories_result)) {
159 if (!$done) {
160 $categories[$category->cid] = check_plain($category->title);
161 }
162 if ($category->iid) {
163 $selected[] = $category->cid;
164 }
165 }
166 $done = TRUE;
167 $form['categories'][$item->iid] = array(
168 '#type' => variable_get('aggregator_category_selector', 'checkboxes'),
169 '#default_value' => $selected,
170 '#options' => $categories,
171 '#size' => 10,
172 '#multiple' => TRUE
173 );
174 }
175 $form['submit'] = array('#type' => 'submit', '#value' => t('Save categories'));
176
177 return $form;
178 }
179
180 /**
181 * Validate aggregator_categorize_items form submissions.
182 */
183 function aggregator_categorize_items_validate($form, &$form_state) {
184 if (!user_access('administer news feeds')) {
185 form_error($form, t('You are not allowed to categorize this feed item.'));
186 }
187 }
188
189 /**
190 * Process aggregator_categorize_items form submissions.
191 */
192 function aggregator_categorize_items_submit($form, &$form_state) {
193 if (!empty($form_state['values']['categories'])) {
194 foreach ($form_state['values']['categories'] as $iid => $selection) {
195 db_query('DELETE FROM {aggregator_category_item} WHERE iid = %d', $iid);
196 foreach ($selection as $cid) {
197 if ($cid) {
198 db_query('INSERT INTO {aggregator_category_item} (cid, iid) VALUES (%d, %d)', $cid, $iid);
199 }
200 }
201 }
202 }
203 drupal_set_message(t('The categories have been saved.'));
204 }
205
206 /**
207 * Theme the page list form for assigning categories.
208 *
209 * @param $form
210 * An associative array containing the structure of the form.
211 * @return
212 * The output HTML.
213 * @ingroup themeable
214 */
215 function theme_aggregator_categorize_items($form) {
216 $output = drupal_render($form['feed_source']);
217 $rows = array();
218 if ($form['items']) {
219 foreach (element_children($form['items']) as $key) {
220 if (is_array($form['items'][$key])) {
221 $rows[] = array(
222 drupal_render($form['items'][$key]),
223 array('data' => drupal_render($form['categories'][$key]), 'class' => 'categorize-item'),
224 );
225 }
226 }
227 }
228 $output .= theme('table', array('', t('Categorize')), $rows);
229 $output .= drupal_render($form['submit']);
230 $output .= drupal_render($form);
231 return theme('aggregator_wrapper', $output);
232 }
233
234 /**
235 * Process variables for aggregator-wrapper.tpl.php.
236 *
237 * @see aggregator-wrapper.tpl.php
238 */
239 function template_preprocess_aggregator_wrapper(&$variables) {
240 $variables['pager'] = theme('pager', NULL, 20, 0);
241 }
242
243 /**
244 * Process variables for aggregator-item.tpl.php.
245 *
246 * @see aggregator-item.tpl.php
247 */
248 function template_preprocess_aggregator_item(&$variables) {
249 $item = $variables['item'];
250
251 $variables['feed_url'] = check_url($item->link);
252 $variables['feed_title'] = check_plain($item->title);
253 $variables['content'] = aggregator_filter_xss($item->description);
254
255 $variables['source_url'] = '';
256 $variables['source_title'] = '';
257 if (isset($item->ftitle) && isset($item->fid)) {
258 $variables['source_url'] = url("aggregator/sources/$item->fid");
259 $variables['source_title'] = check_plain($item->ftitle);
260 }
261 if (date('Ymd', $item->timestamp) == date('Ymd')) {
262 $variables['source_date'] = t('%ago ago', array('%ago' => format_interval(time() - $item->timestamp)));
263 }
264 else {
265 $variables['source_date'] = format_date($item->timestamp, 'custom', variable_get('date_format_medium', 'D, m/d/Y - H:i'));
266 }
267
268 $variables['categories'] = array();
269 foreach ($item->categories as $category) {
270 $variables['categories'][$category->cid] = l($category->title, 'aggregator/categories/'. $category->cid);
271 }
272 }
273
274 /**
275 * Menu callback; displays all the feeds used by the aggregator.
276 */
277 function aggregator_page_sources() {
278 $result = db_query('SELECT f.fid, f.title, f.description, f.image, MAX(i.timestamp) AS last FROM {aggregator_feed} f LEFT JOIN {aggregator_item} i ON f.fid = i.fid GROUP BY f.fid, f.title, f.description, f.image ORDER BY last DESC, f.title');
279
280 $output = '';
281 while ($feed = db_fetch_object($result)) {
282 // Most recent items:
283 $summary_items = array();
284 if (variable_get('aggregator_summary_items', 3)) {
285 $items = db_query_range('SELECT i.title, i.timestamp, i.link FROM {aggregator_item} i WHERE i.fid = %d ORDER BY i.timestamp DESC', $feed->fid, 0, variable_get('aggregator_summary_items', 3));
286 while ($item = db_fetch_object($items)) {
287 $summary_items[] = theme('aggregator_summary_item', $item);
288 }
289 }
290 $feed->url = url('aggregator/sources/'. $feed->fid);
291 $output .= theme('aggregator_summary_items', $summary_items, $feed);
292 }
293 $output .= theme('feed_icon', url('aggregator/opml'), t('OPML feed'));
294
295 return theme('aggregator_wrapper', $output);
296 }
297
298 /**
299 * Menu callback; displays all the categories used by the aggregator.
300 */
301 function aggregator_page_categories() {
302 $result = db_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');
303
304 $output = '';
305 while ($category = db_fetch_object($result)) {
306 if (variable_get('aggregator_summary_items', 3)) {
307 $summary_items = array();
308 $items = db_query_range('SELECT i.title, i.timestamp, i.link, f.title as feed_title, f.link as feed_link FROM {aggregator_category_item} ci LEFT JOIN {aggregator_item} i ON i.iid = ci.iid LEFT JOIN {aggregator_feed} f ON i.fid = f.fid WHERE ci.cid = %d ORDER BY i.timestamp DESC', $category->cid, 0, variable_get('aggregator_summary_items', 3));
309 while ($item = db_fetch_object($items)) {
310 $summary_items[] = theme('aggregator_summary_item', $item);
311 }
312 }
313 $category->url = url('aggregator/categories/'. $category->cid);
314 $output .= theme('aggregator_summary_items', $summary_items, $category);
315 }
316
317 return theme('aggregator_wrapper', $output);
318 }
319
320 /**
321 * Menu callback; generate an RSS 0.92 feed of aggregator items or categories.
322 */
323 function aggregator_page_rss() {
324 $result = NULL;
325 // arg(2) is the passed cid, only select for that category
326 if (arg(2)) {
327 $category = db_fetch_object(db_query('SELECT cid, title FROM {aggregator_category} WHERE cid = %d', arg(2)));
328 $sql = 'SELECT i.*, f.title AS ftitle, f.link AS flink FROM {aggregator_category_item} c LEFT JOIN {aggregator_item} i ON c.iid = i.iid LEFT JOIN {aggregator_feed} f ON i.fid = f.fid WHERE cid = %d ORDER BY timestamp DESC, i.iid DESC';
329 $result = db_query_range($sql, $category->cid, 0, variable_get('feed_default_items', 10));
330 }
331 // or, get the default aggregator items
332 else {
333 $category = NULL;
334 $sql = 'SELECT i.*, f.title AS ftitle, f.link AS flink FROM {aggregator_item} i INNER JOIN {aggregator_feed} f ON i.fid = f.fid ORDER BY i.timestamp DESC, i.iid DESC';
335 $result = db_query_range($sql, 0, variable_get('feed_default_items', 10));
336 }
337
338 $feeds = array();
339 while ($item = db_fetch_object($result)) {
340 $feeds[] = $item;
341 }
342 return theme('aggregator_page_rss', $feeds, $category);
343 }
344
345 /**
346 * Theme the RSS output.
347 *
348 * @param $feeds
349 * An array of the feeds to theme.
350 * @param $category
351 * A common category, if any, for all the feeds.
352 * @ingroup themeable
353 */
354 function theme_aggregator_page_rss($feeds, $category = NULL) {
355 drupal_set_header('Content-Type: application/rss+xml; charset=utf-8');
356
357 $items = '';
358 $feed_length = variable_get('feed_item_length', 'teaser');
359 foreach ($feeds as $feed) {
360 switch ($feed_length) {
361 case 'teaser':
362 $teaser = node_teaser($feed->description);
363 if ($teaser != $feed->description) {
364 $teaser .= '<p><a href="'. check_url($feed->link) .'">'. t('read more') ."</a></p>\n";
365 }
366 $feed->description = $teaser;
367 break;
368 case 'title':
369 $feed->description = '';
370 break;
371 }
372 $items .= format_rss_item($feed->ftitle .': '. $feed->title, $feed->link, $feed->description, array('pubDate' => date('r', $feed->timestamp)));
373 }
374
375 $site_name = variable_get('site_name', 'Drupal');
376 $url = url((isset($category) ? 'aggregator/categories/'. $category->cid : 'aggregator'), array('absolute' => TRUE));
377 $description = isset($category) ? t('@site_name - aggregated feeds in category @title', array('@site_name' => $site_name, '@title' => $category->title)) : t('@site_name - aggregated feeds', array('@site_name' => $site_name));
378
379 $output = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n";
380 $output .= "<rss version=\"2.0\">\n";
381 $output .= format_rss_channel(t('@site_name aggregator', array('@site_name' => $site_name)), $url, $description, $items);
382 $output .= "</rss>\n";
383
384 print $output;
385 }
386
387 /**
388 * Menu callback; generates an OPML representation of all feeds.
389 *
390 * @param $cid
391 * If set, feeds are exported only from a category with this ID. Otherwise, all feeds are exported.
392 * @return
393 * The output XML.
394 */
395 function aggregator_page_opml($cid = NULL) {
396 if ($cid) {
397 $result = db_query('SELECT f.title, f.url FROM {aggregator_feed} f LEFT JOIN {aggregator_category_feed} c on f.fid = c.fid WHERE c.cid = %d ORDER BY title', $cid);
398 }
399 else {
400 $result = db_query('SELECT * FROM {aggregator_feed} ORDER BY title');
401 }
402
403 $feeds = array();
404 while ($item = db_fetch_object($result)) {
405 $feeds[] = $item;
406 }
407
408 return theme('aggregator_page_opml', $feeds);
409 }
410
411 /**
412 * Theme the OPML feed output.
413 *
414 * @param $feeds
415 * An array of the feeds to theme.
416 * @ingroup themeable
417 */
418 function theme_aggregator_page_opml($feeds) {
419
420 drupal_set_header('Content-Type: text/xml; charset=utf-8');
421
422 $output = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n";
423 $output .= "<opml version=\"1.1\">\n";
424 $output .= "<head>\n";
425 $output .= '<title>'. check_plain(variable_get('site_name', 'Drupal')) ."</title>\n";
426 $output .= '<dateModified>'. gmdate('r') ."</dateModified>\n";
427 $output .= "</head>\n";
428 $output .= "<body>\n";
429 foreach ($feeds as $feed) {
430 $output .= '<outline text="'. check_plain($feed->title) .'" xmlUrl="'. check_url($feed->url) ."\" />\n";
431 }
432 $output .= "</body>\n";
433 $output .= "</opml>\n";
434
435 print $output;
436 }
437
438 /**
439 * Process variables for aggregator-summary-items.tpl.php.
440 *
441 * @see aggregator-summary-item.tpl.php
442 */
443 function template_preprocess_aggregator_summary_items(&$variables) {
444 $variables['title'] = check_plain($variables['source']->title);
445 $variables['summary_list'] = theme('item_list', $variables['summary_items']);
446 $variables['source_url'] = $variables['source']->url;
447 }
448
449 /**
450 * Process variables for aggregator-summary-item.tpl.php.
451 *
452 * @see aggregator-summary-item.tpl.php
453 */
454 function template_preprocess_aggregator_summary_item(&$variables) {
455 $item = $variables['item'];
456
457 $variables['feed_url'] = check_url($item->link);
458 $variables['feed_title'] = check_plain($item->title);
459 $variables['feed_age'] = t('%age old', array('%age' => format_interval(time() - $item->timestamp)));
460
461 $variables['source_url'] = '';
462 $variables['source_title'] = '';
463 if (!empty($item->feed_link)) {
464 $variables['source_url'] = check_url($item->feed_link);
465 $variables['source_title'] = check_plain($item->feed_title);
466 }
467 }
468
469 /**
470 * Process variables for aggregator-feed-source.tpl.php.
471 *
472 * @see aggregator-feed-source.tpl.php
473 */
474 function template_preprocess_aggregator_feed_source(&$variables) {
475 $feed = $variables['feed'];
476
477 $variables['source_icon'] = theme('feed_icon', $feed->url, t('!title feed', array('!title' => $feed->title)));
478 $variables['source_image'] = $feed->image;
479 $variables['source_description'] = aggregator_filter_xss($feed->description);
480 $variables['source_url'] = check_url(url($feed->link, array('absolute' => TRUE)));
481
482 if ($feed->checked) {
483 $variables['last_checked'] = t('@time ago', array('@time' => format_interval(time() - $feed->checked)));
484 }
485 else {
486 $variables['last_checked'] = t('never');
487 }
488
489 if (user_access('administer news feeds')) {
490 $variables['last_checked'] = l($variables['last_checked'], 'admin/content/aggregator');
491 }
492 }