/[drupal]/contributions/modules/news_page/news_page.module
ViewVC logotype

Contents of /contributions/modules/news_page/news_page.module

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.15 - (show annotations) (download) (as text)
Sat May 9 23:54:37 2009 UTC (6 months, 2 weeks ago) by MegaGrunt
Branch: MAIN
CVS Tags: DRUPAL-6--1-0-RC1, DRUPAL-6--1-0-BETA1, HEAD
Branch point for: DRUPAL-6--1
Changes since 1.14: +157 -153 lines
File MIME type: text/x-php
- Drupal 6 update
1 <?php
2
3 /* $Id:$ */
4
5 function news_page_theme() {
6 return array(
7 'news_page_feed' => array(
8 'arguments' => array('items' => ''),
9 ),
10 'news_page_item' => array(
11 'arguments' => array('item' => NULL, 'blogit' => NULL, ),
12 ),
13 'news_page_rss' => array(
14 'arguments' => array('channel' => NULL, 'base_url' => NULL, 'items' => NULL),
15 ),
16 );
17 }
18
19 // Implementation of hook_node_info().
20 function news_page_node_info() {
21 return array('news_page' => array(
22 'name' => t('News Page'),
23 'module' => 'news_page',
24 'description' => 'Enables creation of pages displaying filtered syndicated news items from aggregator categories.',
25 )
26 );
27 }
28
29
30 // Implementation of hook_access().
31 function news_page_access($op, $node, $account) {
32 global $account;
33
34 switch($op) {
35 case 'create':
36 return user_access('create news page', $account);
37 break;
38
39 case 'view':
40 return user_access('access news page', $account);
41 break;
42
43 case 'update':
44 case 'delete':
45 if (user_access('edit own news page', $account) && ($account->uid == $node->uid)) {
46 return TRUE;
47 }
48 break;
49 }
50 }
51
52
53 // Implementation of hook_perm().
54 function news_page_perm() {
55 return array('access news page', 'access news page feed', 'create news page', 'edit own news page');
56 }
57
58 // Implementation of hook_menu().
59 function news_page_menu() {
60 $items = array();
61
62 /* TODO
63 Non menu code that was placed in hook_menu under the '!$may_cache' block
64 so that it could be run during initialization, should now be moved to hook_init.
65 Previously we called hook_init twice, once early in the bootstrap process, second
66 just after the bootstrap has finished. The first instance is now called boot
67 instead of init.
68
69 In Drupal 6, there are now two hooks that can be used by modules to execute code
70 at the beginning of a page request. hook_boot() replaces hook_boot() in Drupal 5
71 and runs on each page request, even for cached pages. hook_boot() now only runs
72 for non-cached pages and thus can be used for code that was previously placed in
73 hook_menu() with $may_cache = FALSE:
74
75 Dynamic menu items under a '!$may_cache' block can often be simplified
76 to remove references to arg(n) and use of '%<function-name>' to check
77 conditions. See http://drupal.org/node/103114.
78
79 The title and description arguments should not have strings wrapped in t(),
80 because translation of these happen in a later stage in the menu system.
81 */
82 if ($may_cache) {
83 $items['admin/content/news_page'] = array(
84 'title' => 'News Page',
85 'description' => 'News Page settings',
86 'page callback' => 'drupal_get_form',
87 'page arguments' => 'news_page_admin_settings',
88 'access arguments' => array('administer site configuration'),
89 'type' => MENU_NORMAL_ITEM,
90 );
91
92 }
93 else {
94
95 if (is_numeric(arg(2))) {
96
97 $account = NULL;
98
99 // Check if an external source wants to read this feed. The url must containe authentication information.
100 if (arg(3) && arg(4)) {
101
102 // Authenticate user
103 $account = user_load(array('name' => arg(3), 'pass' => arg(4), 'status' => 1));
104 if ($account === FALSE) {
105 $account = NULL;
106 }
107 }
108
109 $items['news_page/feed'] = array(
110 'title' => 'News page feed',
111 'page callback' => '_news_page_feed',
112 'page arguments' => array('nid' => arg(2)),
113 'access arguments' => array('access news page feed', $account),
114 'type' => MENU_CALLBACK);
115 }
116 }
117
118 return $items;
119 }
120
121
122 // Implementation of hook_form().
123 function news_page_form(&$node) {
124
125 $form['title'] = array(
126 '#type' => 'textfield',
127 '#title' => t('Title'),
128 '#default_value' => $node->title,
129 '#required' => TRUE,
130 );
131
132 $form['body_filter']['body'] = array(
133 '#type' => 'textarea',
134 '#title' => t('Body'),
135 '#default_value' => $node->body,
136 '#required' => FALSE,
137 '#cols' => 60,
138 '#rows' => 20,
139 );
140
141 $form['body_filter']['filter'] = filter_form($node->format);
142
143 $results = db_query("SELECT cid, title FROM {aggregator_category}");
144
145 if (empty($results)) form_set_error('cid', t('You must create at least 1 aggregator category before creating a news page.'));
146
147 $categories[0] = t('--none--');
148
149 while ($category = db_fetch_object($results)) {
150 $categories[$category->cid] = $category->title;
151 }
152
153 $form['cid'] = array(
154 '#type' => 'select',
155 '#title' => t('Aggregator Category'),
156 '#default_value' => $node->cid,
157 '#options' => $categories,
158 '#description' => t('Category to include on this page'),
159 '#extra' => '',
160 '#multiple' => '',
161 '#required' => TRUE,
162 );
163
164 $form['include'] = array(
165 '#type' => 'textfield',
166 '#title' => t('Include Words'),
167 '#default_value' => $node->include,
168 '#size' => 60,
169 '#maxlength' => 128,
170 '#description' => t('Keywords that must be included in a news item for it to be displayed - e.g. "iPhone, +battery, -problem"'),
171 '#attributes' => '',
172 );
173
174 $form['max_items'] = array(
175 '#type' => 'textfield',
176 '#title' => t('Maximum Items'),
177 '#default_value' => is_numeric($node->max_items) ? $node->max_items : 25,
178 '#size' => 5,
179 '#maxlength' => 5,
180 '#description' => t('Maximum number of news items to include on a page'),
181 '#attributes' => '',
182 '#required' => TRUE,
183 );
184
185 return $form;
186 }
187
188
189 // Implementation of hook_validate().
190 function news_page_validate($form, &$form_state) {
191
192 if ($node->validate) {
193
194 if (is_numeric($node->cid) == FALSE OR $node->cid == 0) {
195 form_set_error('cid', t('Please select an aggregator category.'));
196 }
197
198 if (!$node->include) {
199 form_set_error('news_page', '');
200 }
201
202 if (is_numeric($node->max_items) == FALSE OR $node->max_items == 0) {
203 $node->max_items = 25;
204 form_set_error('max_items', t('Maximum items must have a value, field has been reset to the default (25).'));
205 }
206
207 }
208
209 return;
210 }
211
212 function news_page_admin_settings() {
213
214 $form['RSS'] = array(
215 '#type' => 'fieldset',
216 '#title' => t('RSS Feed'),
217 '#description' => t('Users must have the "access news page feeds" <a href="!permission">permission</a> granted in order to use the News Page RSS feeds.', array('!permission' => url('admin/user/access')) ),
218 );
219
220 $form['RSS']['news_page_link_prepend'] = array(
221 '#type' => 'textfield',
222 '#title' => t('RSS Link prepend'),
223 '#default_value' => check_url( variable_get('news_page_link_prepend', '') ),
224 '#size' => 80,
225 '#maxlength' => 255,
226 '#description' => t('All item links generated will have this URL prepended to them. For example: "/jump.php?url=". If unsure, specify nothing. Note: the url is relative to the base url of this drupal site, the page cannot reside on a remote host.'),
227 );
228
229 $form['RSS']['news_page_channel_description'] = array(
230 '#type' => 'textarea',
231 '#title' => t('Global channel description'),
232 '#default_value' => filter_xss_admin( variable_get('news_page_channel_description', '') ),
233 '#cols' => 60,
234 '#rows' => 4,
235 '#description' => t('This text will precede the News Page nodes body text for the feed description, for every News page feed. If no body text is set the global settings <a href="!mission">mission statement</a> is used; if this is empty - nothing will be displayed.', array('!mission' => url('admin/settings/site-information')) ),
236 '#attributes' => '',
237 '#required' => FALSE,
238 );
239
240 return system_settings_form($form);
241 }
242
243 function _news_page_feed($nid) {
244 global $base_url, $locale;
245
246 // get node
247 $node = node_load($nid);
248
249 // Define RSS channel header
250 $channel = array(
251 'version' => '0.92',
252 'title' => check_plain($node->title) . ' | ' . check_plain( variable_get('site_name', 'drupal') ) .' - '. check_plain( variable_get('site_slogan', '') ),
253 'description' => $node->body ? variable_get('news_page_channel_description', '') . check_markup($node->body, $node->format, FALSE) : check_plain( variable_get('site_mission', '') ),
254 'link' => $base_url,
255 'language' => $locale
256 );
257
258 // --- Collect items associated with this node
259 $nodes = news_page_items($node);
260
261 $link_prepend = variable_get('news_page_link_prepend', '') ? $base_url . variable_get('news_page_link_prepend', '') : '';
262
263 while ($item = db_fetch_object($nodes)) {
264
265 $link = url($link_prepend . $item->link, array());
266 $items .= format_rss_item($item->title, $link, $item->description, array('pubDate' => date('r', $item->timestamp)));
267
268 }
269
270 // Output RSS feed
271 theme('news_page_rss', $channel, $base_url, $items);
272
273 return;
274 }
275
276 // Implementation of hook_insert().
277 function news_page_insert($node) {
278 $search = news_page_search_criteria($node->include, $node->cid);
279 db_query("INSERT INTO {news_page} (nid, include, search, cid, max_items) VALUES (%d, '%s', '%s', %d, %d)", $node->nid, $node->include, serialize($search), $node->cid, $node->max_items);
280 }
281
282 // Implementation of hook_update().
283 function news_page_update($node) {
284 $search = news_page_search_criteria($node->include, $node->cid);
285 db_query("UPDATE {news_page} SET include = '%s', search = '%s', cid = %d, max_items = %d WHERE nid = %d", $node->include, serialize($search), $node->cid, $node->max_items, $node->nid);
286 }
287
288 // Implementation of hook_delete().
289 function news_page_delete($node) {
290 db_query('DELETE FROM {news_page} WHERE nid = %d', $node->nid);
291 }
292
293 // Implementation of hook_load().
294 function news_page_load($node) {
295 $additions = db_fetch_object(db_query('SELECT include, search, cid, max_items FROM {news_page} WHERE nid = %d', $node->nid));
296 $additions->search = unserialize($additions->search);
297 return $additions;
298 }
299
300 function news_page_items(&$node) {
301
302 if (isset($node->max_items) == FALSE OR $node->max_items == 0) $node->max_items = 25;
303
304 if ($node->cid) {
305 $search = ($node->search) ? $node->search : news_page_search_criteria($node->include, $node->cid);
306 $result = db_query_range($search->sql, $search->arguments, 0, $node->max_items);
307 }
308
309 return $result;
310 }
311
312 // Implementation of hook_view().
313 function news_page_view(&$node, $teaser = FALSE, $page = FALSE) {
314 global $user;
315
316 $blog_support = module_exists('blog') && user_access('edit own blog');
317
318 $items = '';
319 $result = news_page_items($node);
320
321 while ($item = db_fetch_object($result)) {
322 $items .= theme('news_page_item', $item, $blog_support);
323 }
324
325 // Add RSS feed link if user has correct permission
326 if (user_access('access news page feed')) {
327 // $authenticated = '/' . $user->name . '/' . $user->pass;
328 //$feed_url = url('news_page/feed/' . $node->nid . $authenticated);
329 drupal_set_html_head("\n".'<link rel="alternate" type="application/rss+xml" title="' . check_plain($node->title) . '" href="' . $feed_url . '" />');
330 }
331
332 $node = node_prepare($node, $teaser);
333 $node->content['news_page_feed'] = array(
334 '#value' => theme('news_page_feed', $items),
335 '#weight' => 0,
336 );
337 $node->content['feed_icon'] = array(
338 '#value' => theme('xml_icon', url('news_page/feed/' . $node->nid)),
339 '#weight' => 1,
340 );
341
342 return $node;
343 }
344
345 function news_page_search_criteria($keywords, $cid) {
346
347 $arguments = array($cid);
348
349 if (!empty($keywords)) {
350 $words = explode(",", $keywords);
351
352 foreach ($words as $word) {
353
354 $word = trim($word);
355
356 if (preg_match("/^-/", $word)) {
357
358 $word = preg_replace('/^-/','', $word);
359 $not_title_filter[] = "lower(i.title) NOT LIKE '%%%s%%'";
360 $arguments[] = $word;
361 $not_content_filter[] = "lower(i.description) NOT LIKE '%%%s%%'";
362 $arguments[] = $word;
363 $not_filter_query = implode(" AND ", $not_title_filter) . ' AND ' . implode(" AND ", $not_content_filter);
364
365 } elseif (preg_match("/^\+/", $word)) {
366
367 $word = preg_replace('/^\+/','', $word);
368 $and_title_filter[] = "lower(i.title) LIKE '%%%s%%'";
369 $arguments[] = $word;
370 $and_content_filter[] = "lower(i.description) LIKE '%%%s%%'";
371 $arguments[] = $word;
372 $and_filter_query = implode(" AND ", $and_title_filter) . ' OR ' . implode(" AND ", $and_content_filter);
373
374 } else {
375
376 $title_filter[] = "lower(i.title) LIKE '%%%s%%'";
377 $arguments[] = $word;
378 $content_filter[] = "lower(i.description) LIKE '%%%s%%'";
379 $arguments[] = $word;
380 $filter_query = implode(" OR ", $title_filter) . ' OR ' . implode(" OR ", $content_filter);
381 }
382 }
383
384 $news_queries = array($filter_query, $and_filter_query, $not_filter_query);
385 $i = 0;
386
387 foreach ($news_queries as $query) {
388 if ($i > 0 && drupal_strlen($query) > 0) {
389 $news_query .= "AND " ;
390 }
391
392 if (drupal_strlen($query)) {
393 $news_query .= "(". $query .")";
394 $i++;
395 }
396 }
397 }
398
399 $search->sql = 'SELECT i.*, f.link AS flink, f.title AS ftitle
400 FROM {aggregator_item} i
401 LEFT JOIN {aggregator_feed} f ON i.fid = f.fid
402 LEFT JOIN {aggregator_category_feed} c ON c.fid = f.fid
403 WHERE c.cid = %d';
404
405 if (!empty($news_query)) $search->sql .= " AND ($news_query)";
406
407 $search->sql .= ' ORDER BY timestamp DESC';
408
409 $search->arguments = $arguments;
410
411 return $search;
412 }
413
414 // A custom theme function.
415 function theme_news_page_feed($items) {
416 $output = '<div id="news-page">' . $items . '</div>';
417 return $output;
418 }
419
420 function theme_news_page_item($item, $blogit) {
421
422 $output .= '<div class="feed-item">';
423
424 if ($item->title) {
425 $output .= '<h3 class="feed-item-title">' . filter_xss($item->title, array()) . '</h3>';
426 }
427
428 $output .= '<p>';
429
430 if ($item->description) {
431 $output .= '<span class="feed-item-body">' . aggregator_filter_xss($item->description) . '</span>';
432 }
433 /**
434 * @todo convert these links to just use an l()
435 */
436 if ($blogit) {
437 $blog_icon = '<a href="' . url('node/add/blog', array('query' => "iid=$item->iid")) . '"><img src="'. '/misc/blog.png" alt="'. t('Blog this') . '" title="' . t('blog it') . '" class="blog-it"/></a>' ;
438 }
439
440 $output .= '<br /><span class="feed-item-link"><a href="' . check_url($item->link) . '">' .t('Read more') . '</a></span> <span class="feed-item-source">[<a href="' . check_url($item->flink) . '">' . check_plain($item->ftitle) . '</a>] ' . $blog_icon . '</span>';
441
442 $output .= '</p>';
443 $output .= '</div>';
444
445 return $output;
446 }
447
448 function theme_news_page_rss($channel, $base_url, $items) {
449
450 // Output RSS feed
451 $output = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n";
452 $output .= "<rss version=\"". $channel["version"] . "\" xml:base=\"". $base_url ."\">\n";
453 $output .= format_rss_channel($channel['title'], $channel['link'], $channel['description'], $items, $channel['language']);
454 $output .= "</rss>\n";
455
456 drupal_set_header('Content-Type: text/xml; charset=utf-8');
457 print $output;
458 }

  ViewVC Help
Powered by ViewVC 1.1.2