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

Diff of /contributions/modules/news_page/news_page.module

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

revision 1.13.2.1, Sun Jan 14 03:37:34 2007 UTC revision 1.13.2.2, Tue Jul 24 00:41:25 2007 UTC
# Line 0  Line 1 
1    <?php
2    
3    /* $Id: news_page.module,v 1.12.2.2 2007/01/14 03:22:34 MegaGrunt Exp $ */
4    
5    
6    // Implementation of hook_help().
7    function news_page_help($section) {
8      switch ($section) {
9        case 'node/add#news_page':
10        // This description shows up when users click "create content."
11        return t('Creates a page of keyword filtered news items from an <a href="!aggregator">aggregator</a> category.', array('!aggregator' => url('admin/content/aggregator')) );
12    
13        case 'admin/content/news_page':
14        return t('A News Page provides a way to only include items from an <a href="!aggregator">aggregator</a> category which match your keywords. The majority of settings are entered when you create a new news page node.', array('!aggregator' => url('admin/content/aggregator')) );
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    // Implementation of hook_access().
30    function news_page_access($op, $node) {
31      global $user;
32    
33      switch($op) {
34        case 'create':
35          return user_access('create news page');
36          break;
37    
38        case 'view':
39          return user_access('access news page');
40          break;
41    
42        case 'update':
43        case 'delete':
44          if (user_access('edit own news page') && ($user->uid == $node->uid)) {
45            return TRUE;
46          }
47          break;
48    
49    
50      }
51    }
52    
53    
54    // Implementation of hook_perm().
55    function news_page_perm() {
56      return array('access news page', 'access news page feed', 'create news page', 'edit own news page');
57    }
58    
59    
60    // Implementation of hook_link().
61    function news_page_link($type, $node = 0, $main) {
62      $links = array();
63    
64      if ($type == 'node' && $node->type == 'news_page') {
65        if (news_page_access('update', $node) && !user_access('administer nodes')) {
66          $links['news_page_edit_page_node'] = array (
67            'title' => t('edit this news page node'),
68            'href' => 'node/'. $node->nid . '/edit',
69          );
70        }
71      }
72    
73      return $links;
74    }
75    
76    
77    // Implementation of hook_menu().
78    function news_page_menu($may_cache) {
79      $items = array();
80    
81      if ($may_cache) {
82        $items[] = array('path' => 'node/add/news_page',
83                                  'title' => t('news page'),
84                                  'access' => user_access('create news page'));
85      }
86    
87      if ( is_numeric( arg(2) ) ) {
88    
89        $account = NULL;
90    
91        // Check if an external source wants to read this feed. The url must containe authentication information.
92        if ( arg(3) && arg(4) ) {
93    
94          // Authenticate user
95          $account = user_load(array('name' => arg(3), 'pass' => arg(4), 'status' => 1));
96           if ( $account === FALSE ) {
97                $account = NULL;
98            }
99        }
100    
101        $items[] = array('path' => 'news_page/feed',
102                                  'title' => t('News page feed'),
103                                  'callback' => '_news_page_feed',
104                                  'callback arguments' => array('nid' => arg(2)),
105                                  'access' => user_access('access news page feed', $account),
106                                  'type' => MENU_CALLBACK);
107      }
108    
109      $items[] = array(
110        'path' => 'admin/content/news_page',
111        'title' => t('News Page'),
112        'description' => t('News Page settings'),
113        'callback' => 'drupal_get_form',
114        'callback arguments' => 'news_page_admin_settings',
115        'access' => user_access('administer site configuration'),
116        'type' => MENU_NORMAL_ITEM,
117      );
118    
119      return $items;
120    }
121    
122    
123    // Implementation of hook_form().
124    function news_page_form(&$node) {
125    
126      $form['title'] = array(
127        '#type' => 'textfield',
128        '#title' => t('Title'),
129        '#default_value' => $node->title,
130        '#required' => TRUE,
131      );
132    
133    /* CRUFT ??
134      $form['validate'] = array(
135        '#type' => 'hidden',
136        '#value' => 'validate',
137      );
138    
139      */
140    
141      $form['body_filter']['body'] = array(
142        '#type' => 'textarea',
143        '#title' => t('Body'),
144        '#default_value' => $node->body,
145        '#required' => FALSE,
146        '#cols' => 60,
147        '#rows' => 20,
148      );
149    
150      $form['body_filter']['filter'] = filter_form($node->format);
151    
152      $results = db_query("SELECT cid, title FROM {aggregator_category}");
153      $row_count = db_num_rows($results);
154    
155      if ($row_count == 0) form_set_error('cid', t('You must create at least 1 aggregator category before creating a news page.'));
156    
157      $categories[0] = t('--none--');
158    
159      for ($counter = 1; $counter <=  $row_count; $counter++) {
160        $category= db_fetch_object ($results);
161        $categories[$category->cid] = $category->title;
162      }
163    
164      $form['cid'] = array(
165        '#type' => 'select',
166        '#title' => t('Aggregator Category'),
167        '#default_value' => $node->cid,
168        '#options' => $categories,
169        '#description' => t('Category to include on this page'),
170        '#extra' => '',
171        '#multiple' => '',
172        '#required' => TRUE,
173      );
174    
175      $form['include'] = array(
176        '#type' => 'textfield',
177        '#title' => t('Include Words'),
178        '#default_value' => $node->include,
179        '#size' => 60,
180        '#maxlength' => 128,
181        '#description' => t('Keywords that must be included in a news item for it to be displayed - e.g. "iPhone, +battery, -problem"'),
182        '#attributes' => '',
183        '#required' => TRUE,
184      );
185    
186      $form['max_items'] = array(
187        '#type' => 'textfield',
188        '#title' => t('Maximum Items'),
189        '#default_value' => is_numeric($node->max_items) ? $node->max_items : 25,
190        '#size' => 5,
191        '#maxlength' => 5,
192        '#description' => t('Maximum number of news items to include on a page'),
193        '#attributes' => '',
194        '#required' => TRUE,
195      );
196    
197      return $form;
198    }
199    
200    
201    // Implementation of hook_validate().
202    function news_page_validate(&$node) {
203    
204        if ($node->validate) {
205    
206            if (is_numeric($node->cid) == FALSE OR $node->cid == 0) {
207              form_set_error('cid', t('Please select an aggregator category.'));
208            }
209    
210            if (!$node->include) {
211              form_set_error('include', t('Please add at least one word to the list of include words.'));
212            }
213    
214            if (is_numeric($node->max_items) == FALSE OR $node->max_items == 0) {
215              $node->max_items = 25;
216              form_set_error('max_items', t('Maximum items must have a value, field has been reset to the default (25).'));
217            }
218    
219        }
220    
221      return;
222    }
223    
224    function news_page_admin_settings() {
225    
226      $form['RSS'] = array(
227        '#type' => 'fieldset',
228        '#title' => t('RSS Feed'),
229        '#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')) ),
230      );
231    
232      $form['RSS']['news_page_link_prepend'] = array(
233        '#type' => 'textfield',
234        '#title' => t('RSS Link prepend'),
235        '#default_value' => check_url( variable_get('news_page_link_prepend', '') ),
236        '#size' => 80,
237        '#maxlength' => 255,
238        '#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.'),
239      );
240    
241      $form['RSS']['news_page_channel_description'] = array(
242        '#type' => 'textarea',
243        '#title' => t('Global channel description'),
244        '#default_value' => filter_xss_admin( variable_get('news_page_channel_description', '') ),
245        '#cols' => 60,
246        '#rows' => 4,
247        '#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')) ),
248        '#attributes' => '',
249        '#required' => FALSE,
250      );
251    
252      return system_settings_form($form);
253    }
254    
255    
256    
257    function _news_page_feed($nid) {
258      global $base_url, $locale;
259    
260      // get node
261      $node = node_load($nid);
262    
263      // Define RSS channel header
264      $channel = array(
265        'version'     => '0.92',
266        'title'       => check_plain($node->title) . ' | ' . check_plain( variable_get('site_name', 'drupal') ) .' - '. check_plain( variable_get('site_slogan', '') ),
267        'description' => $node->body ? variable_get('news_page_channel_description', '') . check_markup($node->body, $node->format, FALSE) : check_plain( variable_get('site_mission', '') ),
268        'link'        => $base_url,
269        'language'    => $locale
270      );
271    
272      // --- Collect items associated with this node
273      $nodes = news_page_items($node);
274    
275      $link_prepend = variable_get('news_page_link_prepend', '') ? $base_url . variable_get('news_page_link_prepend', '') : '';
276    
277      while ($item = db_fetch_object($nodes)) {
278    
279        $link = url( $link_prepend . $item->link, NULL, NULL, FALSE);
280        $items .= format_rss_item($item->title, $link, $item->description, array('pubDate' => date('r', $item->timestamp)));
281    
282     }
283    
284      // Output RSS feed
285      theme('news_page_rss', $channel, $base_url, $items);
286    
287      return;
288    }
289    
290    
291    // Implementation of hook_insert().
292    function news_page_insert($node) {
293      $search = news_page_search_criteria($node->include, $node->cid);
294      db_query("INSERT INTO {news_page} (nid, include, search, cid, max_items) VALUES (%d, '%s', '%s', %d, %d)", $node->nid, $node->include, $search, $node->cid, $node->max_items);
295    }
296    
297    
298    // Implementation of hook_update().
299    function news_page_update($node) {
300      $search = news_page_search_criteria($node->include, $node->cid);
301      db_query("UPDATE {news_page} SET include = '%s', search = '%s', cid = %d, max_items = %d WHERE nid = %d", $node->include, $search, $node->cid, $node->max_items, $node->nid);
302    }
303    
304    // Implementation of hook_delete().
305    
306    function news_page_delete($node) {
307      db_query('DELETE FROM {news_page} WHERE nid = %d', $node->nid);
308    }
309    
310    // Implementation of hook_load().
311    function news_page_load($node) {
312      $additions = db_fetch_object(db_query('SELECT include, search, cid, max_items FROM {news_page} WHERE nid = %d', $node->nid));
313      return $additions;
314    }
315    
316    
317    function news_page_items(&$node) {
318    
319      if (isset($node->max_items) == FALSE OR $node->max_items == 0) $node->max_items = 25;
320    
321      if ($node->include && $node->cid) {
322        $search = ($node->search) ? $node->search : news_page_search_criteria($node->include, $node->cid);
323        $result = db_query_range($search, 0, $node->max_items);
324      }
325    
326      return $result;
327    }
328    
329    
330    // Implementation of hook_view().
331    function news_page_view(&$node, $teaser = FALSE, $page = FALSE) {
332      global $user;
333    
334      $blog_support = module_exists('blog') && user_access('edit own blog');
335    
336      $items = '';
337      $result = news_page_items($node);
338    
339      while ($item = db_fetch_object($result)) {
340              $items .= theme('news_page_item', $item, $blog_support);
341      }
342      // Add RSS feed link if user has correct permission
343      if (user_access('access news page feed')) {
344        // $authenticated =  '/' . $user->name . '/' . $user->pass;
345        //$feed_url = url('news_page/feed/' . $node->nid . $authenticated);
346        drupal_set_html_head("\n".'<link rel="alternate" type="application/rss+xml" title="' . check_plain($node->title) . '" href="' . $feed_url . '" />');
347      }
348    
349      $node = node_prepare($node, $teaser);
350      $node->content['news_page_feed'] = array(
351        '#value' => theme('news_page_feed', $items),
352        '#weight' => 0,
353      );
354      $node->content['feed_icon'] = array(
355        '#value' => theme('xml_icon', url('news_page/feed/' . $node->nid)),
356        '#weight' => 1,
357      );
358      return $node;
359    }
360    
361    function news_page_search_criteria($keywords, $cid) {
362    
363        $words = explode(",", $keywords);
364    
365        foreach ($words as $word) {
366          $word = trim($word);
367          if (preg_match("/^-/", $word)) {
368          $word = preg_replace('/^-/','', $word);
369          $not_title_filter[] = "lower(i.title) NOT LIKE '%%" . $word . "%%'";
370          $not_content_filter[] = "lower(i.description) NOT LIKE '%%" . $word . "%%'";
371          $not_filter_query = implode(" AND ", $not_title_filter) . ' AND ' . implode(" AND ", $not_content_filter);
372          } elseif (preg_match("/^\+/", $word)) {
373          $word = preg_replace('/^\+/','', $word);
374          $and_title_filter[] = "lower(i.title) LIKE '%%" . $word . "%%'";
375          $and_content_filter[] = "lower(i.description) LIKE '%%" . $word . "%%'";
376          $and_filter_query = implode(" AND ", $and_title_filter) . ' OR ' . implode(" AND ", $and_content_filter);
377          } else {
378          $title_filter[] = "lower(i.title) LIKE '%%" . $word . "%%'";
379          $content_filter[] = "lower(i.description) LIKE '%%" . $word . "%%'";
380          $filter_query = implode(" OR ", $title_filter) . ' OR ' . implode(" OR ", $content_filter);
381          }
382        }
383        $news_queries = array($not_filter_query, $and_filter_query, $filter_query);
384        $i = 0;
385        foreach ($news_queries as $query) {
386          if ($i>0 && drupal_strlen($query) > 0) {
387            $news_query .= "AND " ;
388          }
389          if (drupal_strlen($query)) {
390          $news_query .= "(". $query .")";
391          $i++;
392          }
393        }
394    
395        $filter_query =
396        "SELECT i.*, f.link AS flink, f.title AS ftitle
397        FROM {aggregator_item} i
398        LEFT JOIN {aggregator_feed} f
399        ON i.fid = f.fid
400        LEFT JOIN {aggregator_category_feed} c
401        ON c.fid = f.fid
402        WHERE c.cid = '$cid'
403        AND ( $news_query )
404        ORDER BY timestamp DESC";
405    
406        return $filter_query;
407    }
408    
409    // A custom theme function.
410    function theme_news_page_feed($items) {
411    
412      $output = '<div id="news-page">' . $items . '</div>';
413      return $output;
414    }
415    
416    function theme_news_page_item($item, $blogit) {
417    
418            $output .= '<div class="feed-item">';
419    
420            if ($item->title) {
421              $output .= '<h3 class="feed-item-title">' . check_plain($item->title) . '</h3>';
422            }
423    
424            $output .= '<p>';
425    
426            if ($item->description) {
427              $output .= '<span class="feed-item-body">' . aggregator_filter_xss($item->description) . '</span>';
428            }
429    
430            if ($blogit) {
431              $blog_icon = '<a href="' . url('node/add/blog', "iid=$item->iid") . '"><img src="'. base_path() .'/misc/blog.png" alt="'. t('Blog this') . '" title="' . t('blog it') . '" class="blog-it"/></a>' ;
432            }
433    
434            $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>';
435    
436            $output .= '</p>';
437            $output .= '</div>';
438    
439      return $output;
440    }
441    
442    function theme_news_page_rss($channel, $base_url, $items) {
443    
444        // Output RSS feed
445        $output = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n";
446        $output .= "<!DOCTYPE rss [<!ENTITY % HTMLlat1 PUBLIC \"-//W3C//ENTITIES Latin 1 for XHTML//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml-lat1.ent\">]>\n";
447        $output .= "<rss version=\"". $channel["version"] . "\" xml:base=\"". $base_url ."\">\n";
448        $output .= format_rss_channel($channel['title'], $channel['link'], $channel['description'], $items, $channel['language']);
449        $output .= "</rss>\n";
450    
451        drupal_set_header('Content-Type: text/xml; charset=utf-8');
452        print $output;
453    }
454    ?>

Legend:
Removed from v.1.13.2.1  
changed lines
  Added in v.1.13.2.2

  ViewVC Help
Powered by ViewVC 1.1.2