source: trunk/www.guidonia.net/wp/wp-content/plugins/google-news/google_news.php@ 44

Last change on this file since 44 was 44, checked in by luciano, 14 years ago
File size: 40.3 KB
Line 
1<?php
2/*
3Plugin Name: Google News
4Description: Displays a selectable Google News RSS feed, inline, widget or in theme.
5Version: 2.5
6Author: Olav Kolbu
7Author URI: http://www.kolbu.com/
8Plugin URI: http://www.kolbu.com/2008/04/07/google-news-plugin/
9License: GPL
10
11Minor parts of WordPress-specific code from various other GPL plugins.
12
13TODO: Multiple widget instances support (possibly)
14 Internationalize more output
15 See if nofollow should be added on links
16*/
17/*
18Copyright (C) 2008 kolbu.com (olav AT kolbu DOT com)
19
20This program is free software; you can redistribute it and/or modify
21it under the terms of the GNU General Public License as published by
22the Free Software Foundation; either version 3 of the License, or
23(at your option) any later version.
24
25This program is distributed in the hope that it will be useful,
26but WITHOUT ANY WARRANTY; without even the implied warranty of
27MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28GNU General Public License for more details.
29
30You should have received a copy of the GNU General Public License
31along with this program. If not, see <http://www.gnu.org/licenses/>.
32*/
33
34include_once(ABSPATH . WPINC . '/rss.php');
35
36global $google_news_instance;
37
38if ( ! class_exists('google_news_plugin')) {
39 class google_news_plugin {
40
41 // So we don't have to query database on every replacement
42 var $settings;
43
44 var $regions = array(
45 'Australia' => 'au',
46 'India' => 'in',
47 'Israel' => 'en_il',
48 'Malaysia' => 'en_my',
49 'New Zealand' => 'nz',
50 'Pakistan' => 'en_pk',
51 'Philippines' => 'en_ph',
52 'Singapore' => 'en_sg',
53 '&#1575;&#1604;&#1593;&#1575;&#1604;&#1605; &#1575;&#1604;&#1593;&#1585;&#1576;&#1610; (Arabic)' => 'ar_me',
54 '&#20013;&#22269;&#29256; (China)' => 'cn',
55 '&#39321;&#28207;&#29256; (Hong Kong)' => 'hk',
56 '&#2349;&#2366;&#2352;&#2340; (India)' => 'hi_in',
57 '&#2980;&#2990;&#3007;&#2996;&#3021; (India)' => 'ta_in',
58 '&#3374;&#3378;&#3375;&#3390;&#3379;&#3330; (India)' => 'ml_in',
59 '&#3108;&#3142;&#3122;&#3137;&#3095;&#3137; (India)' => 'te_in',
60 '&#1497;&#1513;&#1512;&#1488;&#1500; (Israel)' => 'iw_il',
61 '&#26085;&#26412; (Japan)' => 'jp',
62 '&#54620;&#44397; (Korea)' => 'kr',
63 '&#21488;&#28771;&#29256; (Taiwan)' => 'tw',
64 'Việt Nam (Vietnam)' => 'vi_vn',
65 '-------------' => 'us',
66 'België' => 'nl_be',
67 'Belgique' => 'fr_be',
68 'Botswana' => 'en_bw',
69 'Česká republika' => 'cs_cz',
70 'Deutschland' => 'de',
71 'España' => 'es',
72 'Ethiopia' => 'en_et',
73 'France' => 'fr',
74 'Ghana' => 'en_gh',
75 'Ireland' => 'en_ie',
76 'Italia' => 'it',
77 'Kenya' => 'en_ke',
78 'Magyarország' => 'hu_hu',
79 'Namibia' => 'en_na',
80 'Nederland' => 'nl_nl',
81 'Nigeria' => 'en_ng',
82 'Norge' => 'no_no',
83 'Österreich' => 'de_at',
84 'Polska' => 'pl_pl',
85 'Portugal' => 'pt:PT_pt',
86 'Schweiz' => 'de_ch',
87 'South Africa' => 'en_za',
88 'Suisse' => 'fr_ch',
89 'Sverige' => 'sv_se',
90 'Tanzania' => 'en_tz',
91 'TÃŒrkiye' => 'tr_tr',
92 'Uganda' => 'en_ug',
93 'U.K.' => 'uk',
94 'Zimbabwe' => 'en_zw',
95 '&#917;&#955;&#955;&#940;&#948;&#945; (Greece)' => 'el_gr',
96 '&#1056;&#1086;&#1089;&#1089;&#1080;&#1103; (Russia)' => 'ru_ru',
97 '&#1059;&#1082;&#1088;&#1072;&#1080;&#1085;&#1072; (Ukraine)' => 'ru_ua',
98 '&#1059;&#1082;&#1088;&#1072;&#1111;&#1085;&#1072; (Ukraine)' => 'uk_ua',
99 '------------' => 'us',
100 'Argentina' => 'es_ar',
101 'Brasil' => 'pt:BR_br',
102 'Canada English' => 'ca',
103 'Canada Français' => 'fr_ca',
104 'Chile' => 'es_cl',
105 'Colombia' => 'es_co',
106 'Cuba' => 'es_cu',
107 'Estados Unidos' => 'es_us',
108 'México' => 'es_mx',
109 'Perú' => 'es_pe',
110 'U.S.' => 'us',
111 'Venezuela' => 'es_ve',
112 );
113
114 var $newstypes = array(
115 'All' => '',
116 'Top News' => 'h',
117 'Foreign' => 'w',
118 'Domestic' => 'n',
119 'Business' => 'b',
120 'Sci/Tech' => 't',
121 'Health' => 'm',
122 'Sports' => 's',
123 'Entertainment' => 'e',
124 );
125
126 var $outputtypes = array(
127 'Standard' => '',
128 'Text Only' => 't',
129 'With Images' => '&imv=1',
130 );
131
132 var $desctypes = array(
133 'Short' => '',
134 'Long' => 'l',
135 );
136
137 // Constructor
138 function google_news_plugin() {
139
140 // Form POSTs dealt with elsewhere
141 if ( is_array($_POST) ) {
142 if ( $_POST['google_news-widget-submit'] ) {
143 $tmp = $_POST['google_news-widget-feed'];
144 $alloptions = get_option('google_news');
145 if ( $alloptions['widget-1'] != $tmp ) {
146 if ( $tmp == '*DEFAULT*' ) {
147 $alloptions['widget-1'] = '';
148 } else {
149 $alloptions['widget-1'] = $tmp;
150 }
151 update_option('google_news', $alloptions);
152 }
153 } else if ( $_POST['google_news-options-submit'] ) {
154 // noop
155 } else if ( $_POST['google_news-submit'] ) {
156 // noop
157 }
158 }
159
160 add_filter('the_content', array(&$this, 'insert_news'));
161 add_action('admin_menu', array(&$this, 'admin_menu'));
162 add_action('plugins_loaded', array(&$this, 'widget_init'));
163
164 // Hook for theme coders/hackers
165 add_action('google_news', array(&$this, 'display_feed'));
166
167 // Makes it backwards compat pre-2.5 I hope
168 if ( function_exists('add_shortcode') ) {
169 add_shortcode('google-news', array(&$this, 'my_shortcode_handler'));
170 }
171
172 }
173
174 // *************** Admin interface ******************
175
176 // Callback for admin menu
177 function admin_menu() {
178 add_options_page('Google News Options', 'Google News',
179 'administrator', __FILE__,
180 array(&$this, 'plugin_options'));
181 add_management_page('Google News', 'Google News',
182 'administrator', __FILE__,
183 array(&$this, 'admin_manage'));
184
185 }
186
187 // Settings -> Google News
188 function plugin_options() {
189
190 if (get_bloginfo('version') >= '2.7') {
191 $manage_page = 'tools.php';
192 } else {
193 $manage_page = 'edit.php';
194 }
195 print <<<EOT
196 <div class="wrap">
197 <h2>Google News</h2>
198 <p>This plugin allows you to define a number of Google News
199 feeds and have them displayed anywhere in content, in a widget
200 or in a theme. Any number of inline replacements or theme
201 inserts can be made, but only one widget instance is
202 permitted in this release. To use the feeds insert one or more
203 of the following special html comments or Shortcodes
204 anywhere in user content. Note that Shortcodes, i.e. the
205 ones using square brackets, are only available in
206 WordPress 2.5 and above.<p>
207 <ul><li><b>&lt;--google-news--&gt</b> (for default feed)</li>
208 <li><b>&lt;--google-news#feedname--&gt</b></li>
209 <li><b>[google-news]</b> (also for default feed)</li>
210 <li><b>[google-news name="feedname"]</b></li></ul><p>
211 To insert in a theme call <b>do_action('google_news');</b> or
212 alternatively <b>do_action('google_news', 'feedname');</b><p>
213 To manage feeds, go to <a href="$manage_page?page=google-news/google_news.php">Manage -> Google News</a>, where you will also find more information.<p>
214 <a href="http://www.kolbu.com/donations/">Donations Page</a>... ;-)<p>
215 <a href="http://www.kolbu.com/2008/04/07/google-news-plugin/">Widget Home Page</a>, leave a comment if you have questions etc.<p>
216 <a href="http://www.google.com/support/news/bin/answer.py?hl=en&answer=59255">Google Terms Of Use</a><p>
217
218
219EOT;
220 }
221
222 // Manage -> Google News
223 function admin_manage() {
224 // Edit/delete links
225 $mode = trim($_GET['mode']);
226 $id = trim($_GET['id']);
227
228 $this->upgrade_options();
229
230 $alloptions = get_option('google_news');
231
232 $flipregions = array_flip($this->regions);
233 $flipnewstypes = array_flip($this->newstypes);
234 $flipoutputtypes = array_flip($this->outputtypes);
235 $flipdesctypes = array_flip($this->desctypes);
236
237 if ( is_array($_POST) && $_POST['google_news-submit'] ) {
238
239 $newoptions = array();
240 $id = $_POST['google_news-id'];
241
242 $newoptions['name'] = $_POST['google_news-name'];
243 $newoptions['title'] = $_POST['google_news-title'];
244 $newoptions['region'] = $_POST['google_news-region'];
245 $newoptions['newstype'] = $_POST['google_news-newstype'];
246 $newoptions['outputtype'] = $_POST['google_news-outputtype'];
247 $newoptions['desctype'] = $_POST['google_news-desctype'];
248 $newoptions['numnews'] = $_POST['google_news-numnews'];
249 $newoptions['query'] = $_POST['google_news-query'];
250 $newoptions['feedtype'] = $flipregions[$newoptions['region']].' : '.
251 $flipnewstypes[$newoptions['newstype']];
252
253 if ( $alloptions['feeds'][$id] == $newoptions ) {
254 $text = 'No change...';
255 $mode = 'main';
256 } else {
257 $alloptions['feeds'][$id] = $newoptions;
258 update_option('google_news', $alloptions);
259
260 $mode = 'save';
261 }
262 } else if ( is_array($_POST) && $_POST['google_news-options-cachetime-submit'] ) {
263 if ( $_POST['google_news-options-cachetime'] != $alloptions['cachetime'] ) {
264 $alloptions['cachetime'] = $_POST['google_news-options-cachetime'];
265 update_option('google_news', $alloptions);
266 $text = "Cache time changed to {$alloptions[cachetime]} seconds.";
267 } else {
268 $text = "No change in cache time...";
269 }
270 $mode = 'main';
271 }
272
273 if ( $mode == 'newfeed' ) {
274 $newfeed = 0;
275 foreach ($alloptions['feeds'] as $k => $v) {
276 if ( $k > $newfeed ) {
277 $newfeed = $k;
278 }
279 }
280 $newfeed += 1;
281
282 $text = "Please configure new feed and press Save.";
283 $mode = 'main';
284 }
285
286 if ( $mode == 'save' ) {
287 $text = "Saved feed {$alloptions[feeds][$id][name]} [$id].";
288 $mode = 'main';
289 }
290
291 if ( $mode == 'edit' ) {
292 if ( ! empty($text) ) {
293 echo '<!-- Last Action --><div id="message" class="updated fade"><p>'.$text.'</p></div>';
294 }
295 $text = "Editing feed {$alloptions[feeds][$id][name]} [$id].";
296
297 $edit_id = $id;
298 $mode = 'main';
299 }
300
301 if ( $mode == 'delete' ) {
302
303 $text = "Deleted feed {$alloptions[feeds][$id][name]} [$id].";
304
305 unset($alloptions['feeds'][$id]);
306
307 update_option('google_news', $alloptions);
308
309 $mode = 'main';
310 }
311
312 // main
313 if ( empty($mode) or ($mode == 'main') ) {
314
315 if ( ! empty($text) ) {
316 echo '<!-- Last Action --><div id="message" class="updated fade"><p>'.$text.'</p></div>';
317 }
318 print '<div class="wrap">';
319 print ' <h2>';
320 print _e('Manage Google News Feeds','google_news');
321 print '</h2>';
322 print ' <table id="the-list-x" width="100%" cellspacing="3" cellpadding="3">';
323 print ' <thead>';
324 print ' <tr>';
325 print ' <th scope="col">';
326 print _e('Key','google_news');
327 print '</th>';
328 print ' <th scope="col">';
329 print _e('Name','google_news');
330 print '</th>';
331 print ' <th scope="col">';
332 print _e('Admin-defined title','google_news');
333 print '</th>';
334 print ' <th scope="col">';
335 print _e('Region','google_news');
336 print '</th>';
337 print ' <th scope="col">';
338 print _e('Type','google_news');
339 print '</th>';
340 print ' <th scope="col">';
341 print _e('Output','google_news');
342 print '</th>';
343 print ' <th scope="col">';
344 print _e('Item length','google_news');
345 print '</th>';
346 print ' <th scope="col">';
347 print _e('Max items','google_news');
348 print '</th>';
349 print ' <th scope="col">';
350 print _e('Optional query filter','google_news');
351 print '</th>';
352 print ' <th scope="col" colspan="3">';
353 print _e('Action','google_news');
354 print '</th>';
355 print ' </tr>';
356 print ' </thead>';
357
358 if (get_bloginfo('version') >= '2.7') {
359 $manage_page = 'tools.php';
360 } else {
361 $manage_page = 'edit.php';
362 }
363
364 if ( $alloptions['feeds'] || $newfeed ) {
365 $i = 0;
366
367 foreach ($alloptions['feeds'] as $key => $val) {
368 if ( $i % 2 == 0 ) {
369 print '<tr class="alternate">';
370 } else {
371 print '<tr>';
372 }
373 if ( isset($edit_id) && $edit_id == $key ) {
374 print "<form name=\"google_news_options\" action=\"".
375 htmlspecialchars($_SERVER['REQUEST_URI']).
376 "\" method=\"post\" id=\"google_news_options\">";
377
378 print "<th scope=\"row\">".$key."</th>";
379 print '<td><input size="10" maxlength="20" id="google_news-name" name="google_news-name" type="text" value="'.$val['name'].'" /></td>';
380 print '<td><input size="20" maxlength="20" id="google_news-title" name="google_news-title" type="text" value="'.$val['title'].'" /></td>';
381 print '<td><select name="google_news-region">';
382 $region = $val['region'];
383 foreach ($this->regions as $k => $v) {
384 print '<option '.(strcmp($v,$region)?'':'selected').' value="'.$v.'" >'.$k.'</option>';
385 }
386 print '</select></td>';
387 print '<td><select name="google_news-newstype">';
388 $newstype = $val['newstype'];
389 foreach ($this->newstypes as $k => $v) {
390 print '<option '.(strcmp($v,$newstype)?'':'selected').' value="'.$v.'" >'.$k.'</option>';
391 }
392 print '</select></td>';
393 print '<td><select name="google_news-outputtype">';
394 $outputtype = $val['outputtype'];
395 foreach ($this->outputtypes as $k => $v) {
396 print '<option '.(strcmp($v,$outputtype)?'':'selected').' value="'.$v.'" >'.$k.'</option>';
397 }
398 print '</select></td>';
399 print '<td><select name="google_news-desctype">';
400 $desctype = $val['desctype'];
401 foreach ($this->desctypes as $k => $v) {
402 print '<option '.(strcmp($v,$desctype)?'':'selected').' value="'.$v.'" >'.$k.'</option>';
403 }
404 print '</select></td>';
405 print '<td><input size="3" maxlength="3" id="google_news-numnews" name="google_news-numnews" type="text" value="'.$val['numnews'].'" /></td>';
406 print '<td><input size="10" maxlength="50" id="google_news-query" name="google_news-query" type="text" value="'.$val['query'].'" /></td>';
407 print '<td><input type="submit" value="Save &raquo;">';
408 print "</td>";
409 print "<input type=\"hidden\" id=\"google_news-id\" name=\"google_news-id\" value=\"$edit_id\" />";
410 print "<input type=\"hidden\" id=\"google_news-submit\" name=\"google_news-submit\" value=\"1\" />";
411 print "</form>";
412 } else {
413 print "<th scope=\"row\">".$key."</th>";
414 print "<td>".$val['name']."</td>";
415 print "<td>".$val['title']."</td>";
416 print "<td>".$flipregions[$val['region']]."</td>";
417 print "<td>".$flipnewstypes[$val['newstype']]."</td>";
418 print "<td>".$flipoutputtypes[$val['outputtype']]."</td>";
419 print "<td>".$flipdesctypes[$val['desctype']]."</td>";
420 print "<td>".$val['numnews']."</td>";
421 print "<td>".$val['query']."</td>";
422 print "<td><a href=\"$manage_page?page=google-news/google_news.php&amp;mode=edit&amp;id=$key\" class=\"edit\">";
423 print __('Edit','google_news');
424 print "</a></td>\n";
425 print "<td><a href=\"$manage_page?page=google-news/google_news.php&amp;mode=delete&amp;id=$key\" class=\"delete\" onclick=\"javascript:check=confirm( '".__("This feed entry will be erased. Delete?",'google_news')."');if(check==false) return false;\">";
426 print __('Delete', 'google_news');
427 print "</a></td>\n";
428 }
429 print '</tr>';
430
431 $i++;
432 }
433 if ( $newfeed ) {
434
435 print "<form name=\"google_news_options\" action=\"".
436 htmlspecialchars($_SERVER['REQUEST_URI']).
437 "\" method=\"post\" id=\"google_news_options\">";
438
439 print "<th scope=\"row\">".$newfeed."</th>";
440 print '<td><input size="10" maxlength="20" id="google_news-name" name="google_news-name" type="text" value="NEW" /></td>';
441 print '<td><input size="20" maxlength="20" id="google_news-title" name="google_news-title" type="text" value="" /></td>';
442 print '<td><select name="google_news-region">';
443 $region = 'us';
444 foreach ($this->regions as $k => $v) {
445 print '<option '.(strcmp($v,$region)?'':'selected').' value="'.$v.'" >'.$k.'</option>';
446 }
447 print '</select></td>';
448 print '<td><select name="google_news-newstype">';
449 foreach ($this->newstypes as $k => $v) {
450 print '<option value="'.$v.'" >'.$k.'</option>';
451 }
452 print '</select></td>';
453 print '<td><select name="google_news-outputtype">';
454 foreach ($this->outputtypes as $k => $v) {
455 print '<option value="'.$v.'" >'.$k.'</option>';
456 }
457 print '</select></td>';
458 print '<td><select name="google_news-desctype">';
459 foreach ($this->desctypes as $k => $v) {
460 print '<option value="'.$v.'" >'.$k.'</option>';
461 }
462 print '</select></td>';
463 print '<td><input size="3" maxlength="3" id="google_news-numnews" name="google_news-numnews" type="text" value="5" /></td>';
464 print '<td><input size="10" maxlength="50" id="google_news-query" name="google_news-query" type="text" value="" /></td>';
465 print '<td><input type="submit" value="Save &raquo;">';
466 print "</td>";
467 print "<input type=\"hidden\" id=\"google_news-id\" name=\"google_news-id\" value=\"$newfeed\" />";
468 print "<input type=\"hidden\" id=\"google_news-newfeed\" name=\"google_news-newfeed\" value=\"1\" />";
469 print "<input type=\"hidden\" id=\"google_news-submit\" name=\"google_news-submit\" value=\"1\" />";
470 print "</form>";
471 } else {
472 print "</tr><tr><td colspan=\"12\"><a href=\"$manage_page?page=google-news/google_news.php&amp;mode=newfeed\" class=\"newfeed\">";
473 print __('Add extra feed','google_news');
474 print "</a></td></tr>";
475
476 }
477 } else {
478 print '<tr><td colspan="12" align="center"><b>';
479 print __('No feeds found(!)','google_news');
480 print '</b></td></tr>';
481 print "</tr><tr><td colspan=\"12\"><a href=\"$manage_page?page=google-news/google_news.php&amp;mode=newfeed\" class=\"newfeed\">";
482 print __('Add feed','google_news');
483 print "</a></td></tr>";
484 }
485 print ' </table>';
486 print '<h2>';
487 print _e('Global configuration parameters','google_news');
488 print '</h2>';
489 print ' <form method="post">';
490 print ' <table id="the-cachetime" cellspacing="3" cellpadding="3">';
491 print '<tr><td><b>Cache time:</b></td>';
492 print '<td><input size="6" maxlength="6" id="google_news-options-cachetime" name="google_news-options-cachetime" type="text" value="'.$alloptions['cachetime'].'" /> seconds</td>';
493 print '<input type="hidden" id="google_news-options-cachetime-submit" name="google_news-options-cachetime-submit" value="1" />';
494 print '<td><input type="submit" value="Save &raquo;"></td></tr>';
495 print ' </table>';
496 print '</form>';
497
498 print '<h2>';
499 print _e('Information','google_news');
500 print '</h2>';
501 print ' <table id="the-list-x" width="100%" cellspacing="3" cellpadding="3">';
502 print '<tr><td><b>Key</b></td><td>Unique identifier used internally.</td></tr>';
503 print '<tr><td><b>Name</b></td><td>Optional name to be able to reference a specific feed as e.g. ';
504 print ' <b>&lt;!--google_news#myname--&gt;</b>. ';
505 print ' If more than one feed shares the same name, a random among these will be picked each time. ';
506 print ' The one(s) without a name will be treated as the default feed(s), i.e. used for <b>&lt;!--google_news--&gt;</b> ';
507 print ' or widget feed type <b>*DEFAULT*</b>. If you have Wordpress 2.5 ';
508 print ' or above, you can also use Shortcodes on the form <b>[google-news]</b> ';
509 print ' (for default feed) or <b>[google-news name="feedname"]</b>. And finally ';
510 print ' you can use <b>do_action(\'google_news\');</b> or <b>do_action(\'google_news\', \'feedname\');</b> ';
511 print ' in themes.</td></tr>';
512 print '<tr><td><b>Admin-defined title</b></td><td>Optional feed title. If not set, a reasonable title based on ';
513 print 'Region and Type will be used. Note Google Terms of Service require you to show that the feeds come from ';
514 print 'Google News.</td></tr>';
515 print '<tr><td><b>Region</b></td><td>The region/language of the feed.</td></tr>';
516 print '<tr><td><b>Type</b></td><td>The type of news to present.</td></tr>';
517 print '<tr><td><b>Output</b></td><td>Text only, allow for images or images with most news items. Note that ';
518 print 'there will be text in all three cases.</td></tr>';
519 print '<tr><td><b>Item length</b></td><td>Single sentence news items or 2-3 lines of text.</td></tr>';
520 print '<tr><td><b>Max items</b></td><td>Maximum number of news items to show for this feed. If the feed contains ';
521 print 'less than the requested items, only the number of items in the feed will obviously be displayed.</td></tr>';
522 print '<tr><td><b>Optional query filter</b></td><td>Pass the requested news through a query filter for very ';
523 print 'detailed control over the type of news to show. E.g. only sports news about the Yankees.</td></tr>';
524 print '<tr><td colspan="12">In all cases, output will depend on original news source and can and will ';
525 print 'differ from source to source. Google hasn\'t really done a great job with respect to formatting. ';
526 print 'Note specifically that a query filter will change the output slightly, as this is how Google wants it.</td></tr>';
527 print '<tr><td><b>Cache time</b></td><td>Minimum number of seconds that WordPress should cache a Google News feed before fetching it again.</td></tr>';
528 print ' </table>';
529 print '</div>';
530 }
531 }
532
533 // ************* Output *****************
534
535 // The function that gets called from themes
536 function display_feed($data) {
537 global $settings;
538 $settings = get_option('google_news');
539 print $this->random_feed($data);
540 unset($settings);
541 }
542
543 // Callback for inline replacement
544 function insert_news($data) {
545 global $settings;
546
547 // Allow for multi-feed sites
548 $tag = '/<!--google-news(|#.*?)-->/';
549
550 // We may have old style options
551 $this->upgrade_options();
552
553 // Avoid getting this for each callback
554 $settings = get_option('google_news');
555
556 $result = preg_replace_callback($tag,
557 array(&$this, 'inline_replace_callback'), $data);
558
559 unset($settings);
560
561 return $result;
562 }
563
564
565 // *********** Widget support **************
566 function widget_init() {
567
568 // Check for the required plugin functions. This will prevent fatal
569 // errors occurring when you deactivate the dynamic-sidebar plugin.
570 if ( !function_exists('register_sidebar_widget') )
571 return;
572
573 register_widget_control('Google News',
574 array(&$this, 'widget_control'), 200, 100);
575
576 // wp_* has more features, presumably fixed at a later date
577 register_sidebar_widget('Google News',
578 array(&$this, 'widget_output'));
579
580 }
581
582 function widget_control() {
583
584 // We may have old style options
585 $this->upgrade_options();
586
587 $alloptions = get_option('google_news');
588 $thisfeed = $alloptions['widget-1'];
589
590 print '<p><label for="google_news-feed">Select feed:</label>';
591 print '<select style="vertical-align:middle;" name="google_news-widget-feed">';
592
593 $allfeeds = array();
594 foreach ($alloptions['feeds'] as $k => $v) {
595 $allfeeds[strlen($v['name'])?$v['name']:'*DEFAULT*'] = 1;
596 }
597 foreach ($allfeeds as $k => $v) {
598 print '<option '.($k==$thisfeed?'':'selected').' value="'.$k.'" >'.$k.'</option>';
599 }
600 print '</select><p>';
601 print '<input type="hidden" id="google_news-widget-submit" name="google_news-widget-submit" value="1" />';
602
603
604 }
605
606 // Called every time we want to display ourselves as a sidebar widget
607 function widget_output($args) {
608 extract($args); // Gives us $before_ and $after_ I presume
609
610 // We may have old style options
611 $this->upgrade_options();
612
613 $alloptions = get_option('google_news');
614 $matching_feeds = array();
615 foreach ($alloptions['feeds'] as $k => $v) {
616 if ( (string)$v['name'] == $alloptions['widget-1'] ) {
617 $matching_feeds[] = $k;
618 }
619 }
620 if ( ! count($matching_feeds) ) {
621 if ( ! strlen($alloptions['widget-1']) ) {
622 $content = '<ul><b>No default feed available</b></ul>';
623 } else {
624 $content = "<ul>Unknown feed name <b>{$alloptions[widget-1]}</b> used</ul>";
625 }
626 echo $before_widget;
627 echo $before_title . __('Google News<br>Error','google_news') . $after_title . '<div>';
628 echo $content;
629 echo '</div>' . $after_widget;
630 return;
631 }
632 $feed_id = $matching_feeds[rand(0, count($matching_feeds)-1)];
633 $options = $alloptions['feeds'][$feed_id];
634
635 $feedtype = $options['feedtype'];
636 $cachetime = $alloptions['cachetime'];
637
638 if ( strlen($options['title']) ) {
639 $title = $options['title'];
640 } else {
641 $title = 'Google News<br>'.$feedtype;
642 }
643
644 echo $before_widget;
645 echo $before_title . $title . $after_title . '<div>';
646 echo $this->get_feed($options, $cachetime);
647 echo '</div>' . $after_widget;
648 }
649
650 // ************** The actual work ****************
651 function get_feed(&$options, $cachetime) {
652
653 if ( ! isset($options['region']) ) {
654 return 'Options not set, visit plugin configuation screen.';
655 }
656
657 $region = $options['region'] ? $options['region'] : 'us';
658 $newstype = $options['newstype'];
659 $outputtype = $options['outputtype'];
660 $query = $options['query'];
661 $numnews = $options['numnews'] ? $options['numnews'] : 5;
662 $desctype = $options['desctype'];
663
664 $result = '<ul>';
665 $feedurl = 'http://news.google.com/news?output=rss';
666
667 // This will also handle mixed mode text/image, when
668 // we get the parsing under control...
669 if ( $outputtype == 't' ) {
670 $region = 't'.$region; // Consistent API, wassat?
671 } else if ( strlen($outputtype) ) {
672 $feedurl .= $outputtype;
673 }
674 $feedurl .= "&ned=$region";
675 if ( strlen($newstype) ) {
676 $feedurl .= "&topic=$newstype";
677 }
678 if ( strlen($query) ) {
679 if ( substr($query,0,3) == 'OR ' ) {
680 $squery = urlencode(strtolower(substr($query,3)));
681 $feedurl .= "&as_oq=$squery";
682 } else {
683 $squery = urlencode(strtolower($query));
684 $feedurl .= "&q=$squery";
685 }
686 }
687
688 // Using the WP RSS fetcher (MagpieRSS). It has serious
689 // GC problems though.
690 define('MAGPIE_CACHE_AGE', $cachetime);
691 define('MAGPIE_CACHE_ON', 1);
692 define('MAGPIE_DEBUG', 1);
693
694 $rss = fetch_rss($feedurl);
695
696 if ( ! is_object($rss) ) {
697 return 'Google News unavailable</ul>';
698 }
699 $rss->items = array_slice($rss->items, 0, $numnews);
700 foreach ( $rss->items as $item ) {
701 $description = $this->html_decode($item['description']);
702
703 // All this is bound to break, but Google
704 // doesn't know usable markup from squat
705
706 // As per Google TOC, we need to retain related link
707 preg_match('|(<a class=p [^>]+><nobr>[^<]+</nobr></a>)|',
708 $description, $related);
709
710 // Try some tricks to lose useless markup
711 $bloc = strpos($description, '<font');
712 if ( $bloc ) {
713 $description = substr($description, $bloc);
714 }
715 $eloc = strpos($description, '<a href=',
716 strpos($description, '<a href=')+1);
717 if ( $eloc ) {
718 $description = substr($description,0,$eloc);
719 }
720
721 // No markup in tooltips
722 $tooltip = preg_replace('/<[^>]+>/','',$description);
723 $patterns = array(
724 '/<(td|tr|table|div|font|ul|li)[^>]*>/',
725 '/<.(td|tr|table|div|font|ul|li)[^>]*>/',
726 );
727 $replacements = array(
728 '',
729 '',
730 );
731 $description = preg_replace($patterns, $replacements,
732 $description);
733 $description = preg_replace('|<br>|', '', $description, 1);
734 $description = preg_replace('|(<img src[^>]+>)<br>([^<]+</a>)|',
735 '\\1\\2<br>', $description, 1);
736 $description = preg_replace('|</div><br><div|', '</div><div',
737 $description);
738 $description .= $related[1];
739
740 $title = $this->html_decode($item['title']);
741 $date = $item['pubdate'];
742 $link = $item['link'];
743 if ( strlen($desctype) ) {
744 $result .= "<li>$description</li>";
745 } else {
746 $result .= "<li><a href=\"$link\" target=\"_blank\" ".
747 "title=\"$tooltip\">$title<br>$related[1]</a></li>";
748 }
749 }
750 return $result.'</ul>';
751 }
752
753 // *********** Shortcode support **************
754 function my_shortcode_handler($atts, $content=null) {
755 global $settings;
756 $settings = get_option('google_news');
757 return $this->random_feed($atts['name']);
758 unset($settings);
759 }
760
761
762 // *********** inline replacement callback support **************
763 function inline_replace_callback($matches) {
764
765 if ( ! strlen($matches[1]) ) { // Default
766 $feedname = '';
767 } else {
768 $feedname = substr($matches[1], 1); // Skip #
769 }
770 return $this->random_feed($feedname);
771 }
772
773 // ************** Support functions ****************
774
775 function random_feed($name) {
776 global $settings;
777
778 $matching_feeds = array();
779 foreach ($settings['feeds'] as $k => $v) {
780 if ( (string)$v['name'] == $name ) {
781 $matching_feeds[] = $k;
782 }
783 }
784 if ( ! count($matching_feeds) ) {
785 if ( ! strlen($name) ) {
786 return '<ul><b>No default feed available</b></ul>';
787 } else {
788 return "<ul>Unknown feed name <b>$name</b> used</ul>";
789 }
790 }
791 $feed_id = $matching_feeds[rand(0, count($matching_feeds)-1)];
792 $feed = $settings['feeds'][$feed_id];
793
794 if ( strlen($feed['title']) ) {
795 $title = $feed['title'];
796 } else {
797 $title = 'Google News : '.$feed['feedtype'];
798 }
799
800 $result = '<!-- Start Google News code -->';
801 $result .= "<div id=\"google-news-inline\"><h3>$title</h3>";
802 $result .= $this->get_feed($feed, $settings['cachetime']);
803 $result .= '</div><!-- End Google News code -->';
804 return $result;
805 }
806
807 function html_decode($in) {
808 $patterns = array(
809 '/&amp;/',
810 '/&quot;/',
811 '/&lt;/',
812 '/&gt;/',
813 );
814 $replacements = array(
815 '&',
816 '"',
817 '<',
818 '>',
819 );
820 $tmp = preg_replace($patterns, $replacements, $in);
821 return preg_replace('/&#39;/','\'',$tmp);
822
823 }
824
825 // Unfortunately, we didn't finalize on a data structure
826 // until version 2.1ish of the plugin so we need to upgrade
827 // if needed
828 function upgrade_options() {
829 $options = get_option('google_news');
830
831 if ( !is_array($options) ) {
832
833 // From 1.0
834 $oldoptions = get_option('widget_google_news_widget');
835 if ( is_array($oldoptions) ) {
836 $flipregions = array_flip($this->regions);
837 $flipnewstypes = array_flip($this->newstypes);
838
839 $tmpfeed = array();
840 $tmpfeed['title'] = $oldoptions['title'];
841 $tmpfeed['name'] = '';
842 $tmpfeed['numnews'] = $oldoptions['numnews'];
843 $tmpfeed['region'] = $oldoptions['region'];
844 $tmpfeed['newstype'] = $oldoptions['newstype'];
845 $tmpfeed['outputtype'] = $oldoptions['outputtype'];
846 $tmpfeed['query'] = $oldoptions['query'];
847 $tmpfeed['feedtype'] = $flipregions[$tmpfeed['region']].
848 ' : '.
849 $flipnewstypes[$tmpfeed['newstype']];
850
851 $options = array();
852 $options['feeds'] = array( $tmpfeed );
853 $options['widget-1'] = 0;
854 $options['cachetime'] = 300;
855
856 delete_option('widget_google_news_widget');
857 update_option('google_news', $options);
858 } else {
859 // First time ever
860 $options = array();
861 $options['feeds'] = array( $this->default_feed() );
862 $options['widget-1'] = 0;
863 $options['cachetime'] = 300;
864 update_option('google_news', $options);
865 }
866 } else {
867 // From 2.0/2.0.1 to 2.1
868 if ( array_key_exists('region', $options) ) {
869 $newoptions = array('feeds' => array( $options));
870 $newoptions['feeds'][0]['name'] = '';
871 $newoptions['widget-1'] = 0;
872 $newoptions['cachetime'] = 300;
873 update_option('google_news', $newoptions);
874
875 } else if ( 0 ) {
876 // Messed up options, start from scratch
877 $options = array();
878 $options['feeds'] = array( $this->default_feed() );
879 $options['widget-1'] = 0;
880 $options['cachetime'] = 300;
881 update_option('google_news', $options);
882 }
883 }
884 }
885
886 function default_feed() {
887 return array( 'numnews' => 5,
888 'region' => 'us',
889 'name' => '',
890 'feedtype' => 'U.S. : All');
891 }
892 }
893
894 // Instantiate
895 $google_news_instance &= new google_news_plugin();
896
897}
898?>
Note: See TracBrowser for help on using the repository browser.