/[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.14, Tue Jul 24 00:54:07 2007 UTC revision 1.15, Sat May 9 23:54:37 2009 UTC
# Line 1  Line 1 
1  <?php  <?php
2    
3  /* $Id: news_page.module,v 1.12.2.2 2007/01/14 03:22:34 MegaGrunt Exp $ */  /* $Id:$ */
4    
5    function news_page_theme() {
6  // Implementation of hook_help().    return array(
7  function news_page_help($section) {      'news_page_feed' => array(
8    switch ($section) {        'arguments' => array('items' => ''),
9      case 'node/add#news_page':      ),
10      // This description shows up when users click "create content."            'news_page_item' => array(
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')) );              'arguments' => array('item' => NULL, 'blogit' => NULL, ),
12              ),
13      case 'admin/content/news_page':            'news_page_rss' => array(
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')) );              'arguments' => array('channel' => NULL, 'base_url' => NULL, 'items' => NULL),
15              ),
16    }    );
17  }  }
18    
19  // Implementation of hook_node_info().  // Implementation of hook_node_info().
20  function news_page_node_info() {  function news_page_node_info() {
21    return array('news_page' => array(    return array('news_page' => array(
22      'name' => t('News page'),                                                           'name' => t('News Page'),
23      'module' => 'news_page'),                                                           'module' => 'news_page',
24      'description' => 'Enables creation of pages displaying filtered syndicated news items from aggregator categories.'                                                           'description' => 'Enables creation of pages displaying filtered syndicated news items from aggregator categories.',
25                                                            )
26    );    );
27  }  }
28    
29    
30  // Implementation of hook_access().  // Implementation of hook_access().
31  function news_page_access($op, $node) {  function news_page_access($op, $node, $account) {
32    global $user;    global $account;
33    
34    switch($op) {    switch($op) {
35      case 'create':      case 'create':
36        return user_access('create news page');        return user_access('create news page', $account);
37        break;        break;
38    
39      case 'view':      case 'view':
40        return user_access('access news page');        return user_access('access news page', $account);
41        break;        break;
42    
43      case 'update':      case 'update':
44      case 'delete':      case 'delete':
45        if (user_access('edit own news page') && ($user->uid == $node->uid)) {        if (user_access('edit own news page', $account) && ($account->uid == $node->uid)) {
46          return TRUE;          return TRUE;
47        }        }
48        break;        break;
   
   
49    }    }
50  }  }
51    
# Line 56  function news_page_perm() { Line 55  function news_page_perm() {
55    return array('access news page', 'access news page feed', 'create news page', 'edit own news page');    return array('access news page', 'access news page feed', 'create news page', 'edit own news page');
56  }  }
57    
   
 // Implementation of hook_link().  
 function news_page_link($type, $node = 0, $main) {  
   $links = array();  
   
   if ($type == 'node' && $node->type == 'news_page') {  
     if (news_page_access('update', $node) && !user_access('administer nodes')) {  
       $links['news_page_edit_page_node'] = array (  
         'title' => t('edit this news page node'),  
         'href' => 'node/'. $node->nid . '/edit',  
       );  
     }  
   }  
   
   return $links;  
 }  
   
   
58  // Implementation of hook_menu().  // Implementation of hook_menu().
59  function news_page_menu($may_cache) {  function news_page_menu() {
60    $items = array();    $items = array();
61    
62    if ($may_cache) {  /* TODO
63      $items[] = array('path' => 'node/add/news_page',     Non menu code that was placed in hook_menu under the '!$may_cache' block
64                                'title' => t('news page'),     so that it could be run during initialization, should now be moved to hook_init.
65                                'access' => user_access('create news page'));     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) ) ) {            if (is_numeric(arg(2))) {
96    
97      $account = NULL;              $account = NULL;
98    
99      // Check if an external source wants to read this feed. The url must containe authentication information.              // Check if an external source wants to read this feed. The url must containe authentication information.
100      if ( arg(3) && arg(4) ) {              if (arg(3) && arg(4)) {
101    
102        // Authenticate user                // Authenticate user
103        $account = user_load(array('name' => arg(3), 'pass' => arg(4), 'status' => 1));                $account = user_load(array('name' => arg(3), 'pass' => arg(4), 'status' => 1));
104         if ( $account === FALSE ) {                 if ($account === FALSE) {
105              $account = NULL;                      $account = NULL;
106          }                  }
107      }              }
108    
109      $items[] = array('path' => 'news_page/feed',              $items['news_page/feed'] = array(
110                                'title' => t('News page feed'),                                        'title' => 'News page feed',
111                                'callback' => '_news_page_feed',                                        'page callback' => '_news_page_feed',
112                                'callback arguments' => array('nid' => arg(2)),                                        'page arguments' => array('nid' => arg(2)),
113                                'access' => user_access('access news page feed', $account),                                        'access arguments' => array('access news page feed', $account),
114                                'type' => MENU_CALLBACK);                                        'type' => MENU_CALLBACK);
115    }            }
116            }
   $items[] = array(  
     'path' => 'admin/content/news_page',  
     'title' => t('News Page'),  
     'description' => t('News Page settings'),  
     'callback' => 'drupal_get_form',  
     'callback arguments' => 'news_page_admin_settings',  
     'access' => user_access('administer site configuration'),  
     'type' => MENU_NORMAL_ITEM,  
   );  
117    
118    return $items;    return $items;
119  }  }
# Line 130  function news_page_form(&$node) { Line 129  function news_page_form(&$node) {
129      '#required' => TRUE,      '#required' => TRUE,
130    );    );
131    
 /* CRUFT ??  
   $form['validate'] = array(  
     '#type' => 'hidden',  
     '#value' => 'validate',  
   );  
   
   */  
   
132    $form['body_filter']['body'] = array(    $form['body_filter']['body'] = array(
133      '#type' => 'textarea',      '#type' => 'textarea',
134      '#title' => t('Body'),      '#title' => t('Body'),
# Line 150  function news_page_form(&$node) { Line 141  function news_page_form(&$node) {
141    $form['body_filter']['filter'] = filter_form($node->format);    $form['body_filter']['filter'] = filter_form($node->format);
142    
143    $results = db_query("SELECT cid, title FROM {aggregator_category}");    $results = db_query("SELECT cid, title FROM {aggregator_category}");
   $row_count = db_num_rows($results);  
144    
145    if ($row_count == 0) form_set_error('cid', t('You must create at least 1 aggregator category before creating a news page.'));    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--');    $categories[0] = t('--none--');
148    
149    for ($counter = 1; $counter <=  $row_count; $counter++) {          while ($category = db_fetch_object($results)) {
     $category= db_fetch_object ($results);  
150      $categories[$category->cid] = $category->title;      $categories[$category->cid] = $category->title;
151    }          }
152    
153    $form['cid'] = array(    $form['cid'] = array(
154      '#type' => 'select',      '#type' => 'select',
# Line 180  function news_page_form(&$node) { Line 169  function news_page_form(&$node) {
169      '#maxlength' => 128,      '#maxlength' => 128,
170      '#description' => t('Keywords that must be included in a news item for it to be displayed - e.g. "iPhone, +battery, -problem"'),      '#description' => t('Keywords that must be included in a news item for it to be displayed - e.g. "iPhone, +battery, -problem"'),
171      '#attributes' => '',      '#attributes' => '',
     '#required' => TRUE,  
172    );    );
173    
174    $form['max_items'] = array(    $form['max_items'] = array(
# Line 199  function news_page_form(&$node) { Line 187  function news_page_form(&$node) {
187    
188    
189  // Implementation of hook_validate().  // Implementation of hook_validate().
190  function news_page_validate(&$node) {  function news_page_validate($form, &$form_state) {
191    
192      if ($node->validate) {      if ($node->validate) {
193    
# Line 208  function news_page_validate(&$node) { Line 196  function news_page_validate(&$node) {
196          }          }
197    
198          if (!$node->include) {          if (!$node->include) {
199            form_set_error('include', t('Please add at least one word to the list of include words.'));            form_set_error('news_page', '');
200          }          }
201    
202          if (is_numeric($node->max_items) == FALSE OR $node->max_items == 0) {          if (is_numeric($node->max_items) == FALSE OR $node->max_items == 0) {
# Line 252  function news_page_admin_settings() { Line 240  function news_page_admin_settings() {
240    return system_settings_form($form);    return system_settings_form($form);
241  }  }
242    
   
   
243  function _news_page_feed($nid) {  function _news_page_feed($nid) {
244    global $base_url, $locale;    global $base_url, $locale;
245    
# Line 276  function _news_page_feed($nid) { Line 262  function _news_page_feed($nid) {
262    
263    while ($item = db_fetch_object($nodes)) {    while ($item = db_fetch_object($nodes)) {
264    
265      $link = url( $link_prepend . $item->link, NULL, NULL, FALSE);      $link = url($link_prepend . $item->link, array());
266      $items .= format_rss_item($item->title, $link, $item->description, array('pubDate' => date('r', $item->timestamp)));      $items .= format_rss_item($item->title, $link, $item->description, array('pubDate' => date('r', $item->timestamp)));
267    
268   }   }
# Line 287  function _news_page_feed($nid) { Line 273  function _news_page_feed($nid) {
273    return;    return;
274  }  }
275    
   
276  // Implementation of hook_insert().  // Implementation of hook_insert().
277  function news_page_insert($node) {  function news_page_insert($node) {
278    $search = news_page_search_criteria($node->include, $node->cid);    $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, $search, $node->cid, $node->max_items);    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().  // Implementation of hook_update().
283  function news_page_update($node) {  function news_page_update($node) {
284    $search = news_page_search_criteria($node->include, $node->cid);    $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, $search, $node->cid, $node->max_items, $node->nid);    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().  // Implementation of hook_delete().
   
289  function news_page_delete($node) {  function news_page_delete($node) {
290    db_query('DELETE FROM {news_page} WHERE nid = %d', $node->nid);    db_query('DELETE FROM {news_page} WHERE nid = %d', $node->nid);
291  }  }
# Line 310  function news_page_delete($node) { Line 293  function news_page_delete($node) {
293  // Implementation of hook_load().  // Implementation of hook_load().
294  function news_page_load($node) {  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));    $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;    return $additions;
298  }  }
299    
   
300  function news_page_items(&$node) {  function news_page_items(&$node) {
301    
302    if (isset($node->max_items) == FALSE OR $node->max_items == 0) $node->max_items = 25;    if (isset($node->max_items) == FALSE OR $node->max_items == 0) $node->max_items = 25;
303    
304    if ($node->include && $node->cid) {    if ($node->cid) {
305      $search = ($node->search) ? $node->search : news_page_search_criteria($node->include, $node->cid);      $search = ($node->search) ? $node->search : news_page_search_criteria($node->include, $node->cid);
306      $result = db_query_range($search, 0, $node->max_items);      $result = db_query_range($search->sql, $search->arguments, 0, $node->max_items);
307    }    }
308    
309    return $result;    return $result;
310  }  }
311    
   
312  // Implementation of hook_view().  // Implementation of hook_view().
313  function news_page_view(&$node, $teaser = FALSE, $page = FALSE) {  function news_page_view(&$node, $teaser = FALSE, $page = FALSE) {
314    global $user;    global $user;
# Line 336  function news_page_view(&$node, $teaser Line 318  function news_page_view(&$node, $teaser
318    $items = '';    $items = '';
319    $result = news_page_items($node);    $result = news_page_items($node);
320    
321    while ($item = db_fetch_object($result)) {    while ($item = db_fetch_object($result)) {
322            $items .= theme('news_page_item', $item, $blog_support);            $items .= theme('news_page_item', $item, $blog_support);
323    }    }
324    
325    // Add RSS feed link if user has correct permission    // Add RSS feed link if user has correct permission
326    if (user_access('access news page feed')) {    if (user_access('access news page feed')) {
327      // $authenticated =  '/' . $user->name . '/' . $user->pass;      // $authenticated =  '/' . $user->name . '/' . $user->pass;
# Line 355  function news_page_view(&$node, $teaser Line 338  function news_page_view(&$node, $teaser
338      '#value' => theme('xml_icon', url('news_page/feed/' . $node->nid)),      '#value' => theme('xml_icon', url('news_page/feed/' . $node->nid)),
339      '#weight' => 1,      '#weight' => 1,
340    );    );
341    
342    return $node;    return $node;
343  }  }
344    
345  function news_page_search_criteria($keywords, $cid) {  function news_page_search_criteria($keywords, $cid) {
346    
347      $words = explode(",", $keywords);          $arguments = array($cid);
   
     foreach ($words as $word) {  
       $word = trim($word);  
       if (preg_match("/^-/", $word)) {  
       $word = preg_replace('/^-/','', $word);  
       $not_title_filter[] = "lower(i.title) NOT LIKE '%%" . $word . "%%'";  
       $not_content_filter[] = "lower(i.description) NOT LIKE '%%" . $word . "%%'";  
       $not_filter_query = implode(" AND ", $not_title_filter) . ' AND ' . implode(" AND ", $not_content_filter);  
       } elseif (preg_match("/^\+/", $word)) {  
       $word = preg_replace('/^\+/','', $word);  
       $and_title_filter[] = "lower(i.title) LIKE '%%" . $word . "%%'";  
       $and_content_filter[] = "lower(i.description) LIKE '%%" . $word . "%%'";  
       $and_filter_query = implode(" AND ", $and_title_filter) . ' OR ' . implode(" AND ", $and_content_filter);  
       } else {  
       $title_filter[] = "lower(i.title) LIKE '%%" . $word . "%%'";  
       $content_filter[] = "lower(i.description) LIKE '%%" . $word . "%%'";  
       $filter_query = implode(" OR ", $title_filter) . ' OR ' . implode(" OR ", $content_filter);  
       }  
     }  
     $news_queries = array($not_filter_query, $and_filter_query, $filter_query);  
     $i = 0;  
     foreach ($news_queries as $query) {  
       if ($i>0 && drupal_strlen($query) > 0) {  
         $news_query .= "AND " ;  
       }  
       if (drupal_strlen($query)) {  
       $news_query .= "(". $query .")";  
       $i++;  
       }  
     }  
348    
349      $filter_query =          if (!empty($keywords)) {
350      "SELECT i.*, f.link AS flink, f.title AS ftitle                  $words = explode(",", $keywords);
351      FROM {aggregator_item} i  
352      LEFT JOIN {aggregator_feed} f                  foreach ($words as $word) {
353      ON i.fid = f.fid  
354      LEFT JOIN {aggregator_category_feed} c                    $word = trim($word);
355      ON c.fid = f.fid  
356      WHERE c.cid = '$cid'                    if (preg_match("/^-/", $word)) {
357      AND ( $news_query )  
358      ORDER BY timestamp DESC";                          $word = preg_replace('/^-/','', $word);
359                            $not_title_filter[] = "lower(i.title) NOT LIKE '%%%s%%'";
360      return $filter_query;                                  $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.  // A custom theme function.
415  function theme_news_page_feed($items) {  function theme_news_page_feed($items) {
   
416    $output = '<div id="news-page">' . $items . '</div>';    $output = '<div id="news-page">' . $items . '</div>';
417    return $output;    return $output;
418  }  }
# Line 418  function theme_news_page_item($item, $bl Line 422  function theme_news_page_item($item, $bl
422          $output .= '<div class="feed-item">';          $output .= '<div class="feed-item">';
423    
424          if ($item->title) {          if ($item->title) {
425            $output .= '<h3 class="feed-item-title">' . check_plain($item->title) . '</h3>';            $output .= '<h3 class="feed-item-title">' . filter_xss($item->title, array()) . '</h3>';
426          }          }
427    
428          $output .= '<p>';          $output .= '<p>';
# Line 426  function theme_news_page_item($item, $bl Line 430  function theme_news_page_item($item, $bl
430          if ($item->description) {          if ($item->description) {
431            $output .= '<span class="feed-item-body">' . aggregator_filter_xss($item->description) . '</span>';            $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) {          if ($blogit) {
437            $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>' ;            $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>';          $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>';
# Line 443  function theme_news_page_rss($channel, $ Line 449  function theme_news_page_rss($channel, $
449    
450      // Output RSS feed      // Output RSS feed
451      $output = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n";      $output = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n";
     $output .= "<!DOCTYPE rss [<!ENTITY % HTMLlat1 PUBLIC \"-//W3C//ENTITIES Latin 1 for XHTML//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml-lat1.ent\">]>\n";  
452      $output .= "<rss version=\"". $channel["version"] . "\" xml:base=\"". $base_url ."\">\n";      $output .= "<rss version=\"". $channel["version"] . "\" xml:base=\"". $base_url ."\">\n";
453      $output .= format_rss_channel($channel['title'], $channel['link'], $channel['description'], $items, $channel['language']);      $output .= format_rss_channel($channel['title'], $channel['link'], $channel['description'], $items, $channel['language']);
454      $output .= "</rss>\n";      $output .= "</rss>\n";
# Line 451  function theme_news_page_rss($channel, $ Line 456  function theme_news_page_rss($channel, $
456      drupal_set_header('Content-Type: text/xml; charset=utf-8');      drupal_set_header('Content-Type: text/xml; charset=utf-8');
457      print $output;      print $output;
458  }  }
 ?>  

Legend:
Removed from v.1.14  
changed lines
  Added in v.1.15

  ViewVC Help
Powered by ViewVC 1.1.2