| 1 | <?php |
|---|
| 2 | |
|---|
| 3 | |
|---|
| 4 | /********************************************************************\ |
|---|
| 5 | * This program is free software; you can redistribute it and/or * |
|---|
| 6 | * modify it under the terms of the GNU General Public License as * |
|---|
| 7 | * published by the Free Software Foundation; either version 2 of * |
|---|
| 8 | * the License, or (at your option) any later version. * |
|---|
| 9 | * * |
|---|
| 10 | * This program is distributed in the hope that it will be useful, * |
|---|
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * |
|---|
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * |
|---|
| 13 | * GNU General Public License for more details. * |
|---|
| 14 | * * |
|---|
| 15 | * You should have received a copy of the GNU General Public License* |
|---|
| 16 | * along with this program; if not, contact: * |
|---|
| 17 | * * |
|---|
| 18 | * Free Software Foundation Voice: +1-617-542-5942 * |
|---|
| 19 | * 59 Temple Place - Suite 330 Fax: +1-617-542-2652 * |
|---|
| 20 | * Boston, MA 02111-1307, USA gnu@gnu.org * |
|---|
| 21 | * * |
|---|
| 22 | \********************************************************************/ |
|---|
| 23 | /**@file RssPressReview.inc |
|---|
| 24 | * @author Copyright (C) 2004-2005 Benoit Grégoire (http://benoitg.coeus.ca/) et Technologies Coeus inc. |
|---|
| 25 | */ |
|---|
| 26 | //define('MAGPIE_DEBUG', 0); |
|---|
| 27 | define('DEFAULT_PUBLICATION_INTERVAL', (1 * 24 * 3600)); |
|---|
| 28 | |
|---|
| 29 | class RssPressReview |
|---|
| 30 | { |
|---|
| 31 | var $output_encoding; |
|---|
| 32 | var $magpie_dir = ''; |
|---|
| 33 | var $rss_sources; /**< |
|---|
| 34 | $rss_sources is an array of arrays, each of which must contain: |
|---|
| 35 | );*/ |
|---|
| 36 | |
|---|
| 37 | var $algorithm_strength_modifier = 0.75; |
|---|
| 38 | var $max_item_age = null; |
|---|
| 39 | |
|---|
| 40 | /** Allow you to select the absolute or relative directory path where the class can find Magpie. |
|---|
| 41 | * If you do not set it, the class will look in the current include path. |
|---|
| 42 | * */ |
|---|
| 43 | function _setMagpieDir($path) |
|---|
| 44 | { |
|---|
| 45 | $this->magpie_dir = $path; |
|---|
| 46 | } |
|---|
| 47 | |
|---|
| 48 | function RssPressReview($magpie_dir, $output_encoding) |
|---|
| 49 | { |
|---|
| 50 | $this->_setOutputEncoding($output_encoding); |
|---|
| 51 | $this->_setMagpieDir($magpie_dir); |
|---|
| 52 | require_once ($this->magpie_dir.'rss_fetch.inc'); |
|---|
| 53 | require_once ($this->magpie_dir.'rss_utils.inc'); |
|---|
| 54 | } |
|---|
| 55 | |
|---|
| 56 | /** Set the current output encoding. The default is defined by MAGPIE (usually ISO-8859-1), the list of possible value is returned by mb_list_encodings(). |
|---|
| 57 | * See http://ca.php.net/manual/en/function.mb-list-encodings.php |
|---|
| 58 | * Note that because of the way magpie is implemented, this function can only be called ONCE PER SCRIPT, even if you destroy and recreate the object. |
|---|
| 59 | * Should you try to call it again, it will return false and have no effect. |
|---|
| 60 | * @return true if successfull, false if the encoding had already been specified */ |
|---|
| 61 | function _setOutputEncoding($encoding) |
|---|
| 62 | { |
|---|
| 63 | if (!defined('MAGPIE_OUTPUT_ENCODING')) |
|---|
| 64 | { |
|---|
| 65 | define('MAGPIE_OUTPUT_ENCODING', $encoding); |
|---|
| 66 | $retval = true; |
|---|
| 67 | } |
|---|
| 68 | else |
|---|
| 69 | { |
|---|
| 70 | $retval = false; |
|---|
| 71 | } |
|---|
| 72 | return $retval; |
|---|
| 73 | } |
|---|
| 74 | |
|---|
| 75 | /** Get the current output encoding */ |
|---|
| 76 | function getOutputEncoding() |
|---|
| 77 | { |
|---|
| 78 | return MAGPIE_OUTPUT_ENCODING; |
|---|
| 79 | } |
|---|
| 80 | |
|---|
| 81 | /** Set the how much bonus feeds that do not publish as often get over feed that publish more often. |
|---|
| 82 | * @param $algorithm_strength A positive float, defaults to 0.75. Typical range is between 0 and 1. |
|---|
| 83 | * At 0, you have a normal RSS aggregator, meaning the n most recent entries picked from all feeds |
|---|
| 84 | * will be displayed. 1 is usually as high as you'll want to go. Assuming that all |
|---|
| 85 | * feeds have an homogenous internal distribution (say one publishes exactly one entry a day, the |
|---|
| 86 | * other one entry every two days, and the third one entry every three days), and you ask for 15 entries, |
|---|
| 87 | * there will be 5 of each. While that may not sound usefull, it still is, as the feed's distribution is |
|---|
| 88 | * usually not homogenous. Most people will probably be happy with values between 0.5 and 1 |
|---|
| 89 | * @return true if successfull, false if $algorithm_strength < 0 */ |
|---|
| 90 | function setAlgorithmStrength($algorithm_strength = 0.75) |
|---|
| 91 | { |
|---|
| 92 | $retval = false; |
|---|
| 93 | if ($algorithm_strength > 0) |
|---|
| 94 | { |
|---|
| 95 | $this->algorithm_strength_modifier = $algorithm_strength; |
|---|
| 96 | $retval = true; |
|---|
| 97 | } |
|---|
| 98 | return $retval; |
|---|
| 99 | } |
|---|
| 100 | |
|---|
| 101 | /** Set the oldest entries you are willing to see. Any entries older than this will not |
|---|
| 102 | * be considered at all for display. Note that they will still be considered for |
|---|
| 103 | * publication interval calculations. Most people do NOT want to set this, it's only usefull if |
|---|
| 104 | * all your feed publish very rarely, and you don't want entries older than a month, even if |
|---|
| 105 | * there aren't enough items left to reach the number of items you asked for. |
|---|
| 106 | * @param $max_item_age: Age in seconds or null. null means no limit (the default), a typical value would be 3600 * 24 * 30 (a month) |
|---|
| 107 | * @return true if successfull, false if $max_item_age < 0 */ |
|---|
| 108 | function setMaxItemAge($max_item_age = null) |
|---|
| 109 | { |
|---|
| 110 | $retval = false; |
|---|
| 111 | if (is_numeric($max_item_age) && $max_item_age >= 0) |
|---|
| 112 | { |
|---|
| 113 | $this->max_item_age = $max_item_age; |
|---|
| 114 | $retval = true; |
|---|
| 115 | } |
|---|
| 116 | return $retval; |
|---|
| 117 | } |
|---|
| 118 | |
|---|
| 119 | /** Figures out a date for the Magpie RSS item and return's it |
|---|
| 120 | * @return the date in timestamp format or -1 if unavailable |
|---|
| 121 | */ |
|---|
| 122 | function _get_item_date($item, $debug = 0) |
|---|
| 123 | { |
|---|
| 124 | $retval = -1; |
|---|
| 125 | if (!empty ($item['dc']['date'])) |
|---|
| 126 | { |
|---|
| 127 | $datestr = $item['dc']['date']; |
|---|
| 128 | } |
|---|
| 129 | else |
|---|
| 130 | if (!empty ($item['pubdate'])) |
|---|
| 131 | { |
|---|
| 132 | $datestr = $item['pubdate']; |
|---|
| 133 | } |
|---|
| 134 | else |
|---|
| 135 | if (!empty ($item['date'])) |
|---|
| 136 | { |
|---|
| 137 | $datestr = $item['date']; |
|---|
| 138 | } |
|---|
| 139 | else |
|---|
| 140 | if (!empty ($item['created'])) |
|---|
| 141 | { |
|---|
| 142 | $datestr = $item['created']; |
|---|
| 143 | } |
|---|
| 144 | else |
|---|
| 145 | { |
|---|
| 146 | if ($debug) |
|---|
| 147 | { |
|---|
| 148 | echo "<p>_get_item_date(): No date present!</p>"; |
|---|
| 149 | } |
|---|
| 150 | $datestr = null; |
|---|
| 151 | } |
|---|
| 152 | |
|---|
| 153 | if ($datestr == null) |
|---|
| 154 | { |
|---|
| 155 | $retval = -1; |
|---|
| 156 | } |
|---|
| 157 | else |
|---|
| 158 | { |
|---|
| 159 | if ($debug) |
|---|
| 160 | { |
|---|
| 161 | echo "<p>_get_item_date(): String to convert: $datestr</p>"; |
|---|
| 162 | } |
|---|
| 163 | |
|---|
| 164 | $retval = parse_w3cdtf($datestr); |
|---|
| 165 | if ($retval == -1) |
|---|
| 166 | { |
|---|
| 167 | $retval = strtotime($datestr); |
|---|
| 168 | } |
|---|
| 169 | |
|---|
| 170 | if ($debug) |
|---|
| 171 | { |
|---|
| 172 | if ($retval == -1) |
|---|
| 173 | { |
|---|
| 174 | echo "<p>_get_item_date(): Conversion of $datestr failed!</p>"; |
|---|
| 175 | } |
|---|
| 176 | else |
|---|
| 177 | { |
|---|
| 178 | echo "<p>_get_item_date(): Conversion succeded</p>"; |
|---|
| 179 | setlocale(LC_TIME, "fr_CA"); |
|---|
| 180 | echo strftime("%c", $retval); |
|---|
| 181 | } |
|---|
| 182 | } |
|---|
| 183 | } |
|---|
| 184 | |
|---|
| 185 | if ($debug) |
|---|
| 186 | { |
|---|
| 187 | echo "<p>_get_item_date(): Retval: $retval</p>"; |
|---|
| 188 | } |
|---|
| 189 | return $retval; |
|---|
| 190 | } |
|---|
| 191 | |
|---|
| 192 | /** Inverted compare function for adjusted date. Used to sort by adjusted date, most recent first */ |
|---|
| 193 | function _cmp_rpr_adjusted_date($a, $b) |
|---|
| 194 | { |
|---|
| 195 | if ($a['rpr_adjusted_date'] == $b['rpr_adjusted_date']) |
|---|
| 196 | { |
|---|
| 197 | return 0; |
|---|
| 198 | } |
|---|
| 199 | return ($a['rpr_adjusted_date'] > $b['rpr_adjusted_date']) ? -1 : 1; |
|---|
| 200 | } |
|---|
| 201 | |
|---|
| 202 | /** This is the static comparing function to sort rss items in chronological order: */ |
|---|
| 203 | function _cmp_date_item($a, $b) |
|---|
| 204 | { |
|---|
| 205 | $a_date = RssPressReview :: _get_item_date($a); |
|---|
| 206 | $b_date = RssPressReview :: _get_item_date($b); |
|---|
| 207 | if ($a_date == $b_date) |
|---|
| 208 | { |
|---|
| 209 | return 0; |
|---|
| 210 | } |
|---|
| 211 | /*echo "_cmp_date_item(): a:$a_date, b:$b_date "; |
|---|
| 212 | echo ($a_date < $b_date) ? +1 : -1;*/ |
|---|
| 213 | return ($a_date < $b_date) ? +1 : -1; |
|---|
| 214 | } |
|---|
| 215 | |
|---|
| 216 | /** Add a RSS source feed to be merged into the review |
|---|
| 217 | * @param $url: The feed's URL |
|---|
| 218 | * @param $estimated_publication_interval: The average time interval in seconds between items published on this |
|---|
| 219 | * feed. If unset (or set to null), defaults to DEFAULT_PUBLICATION_INTERVAL (1 * 24 * 3600 (one day) as of this writing) |
|---|
| 220 | * This parameter is ignored if the the value can be computed exactly, which is usually the case for |
|---|
| 221 | * RSS 2.0 and atom feeds. |
|---|
| 222 | * However, if the feed does not include the date, the system needs to be able to compute approximate |
|---|
| 223 | * publication date for each entry, so the entry can be weighted against the others. |
|---|
| 224 | * @param $source_bias Optional, integer > 0. The bias to be given to the source by the selection algorithm. |
|---|
| 225 | * Default is 1 (no bias). A bias of 2 will cause the items to "look" twice as recent to the algorithm. |
|---|
| 226 | * A bias of 0.5 to look twice as old. Be carefull, a bias of 2 will statistically cause the |
|---|
| 227 | * feed to have MORE than twice as many items displayed. Typical values would be between 0.75 and 1.5 |
|---|
| 228 | * @return true if successfull, false otherwise */ |
|---|
| 229 | |
|---|
| 230 | function addSourceFeed($url, $estimated_publication_interval = DEFAULT_PUBLICATION_INTERVAL, $source_bias = 1) |
|---|
| 231 | { |
|---|
| 232 | //echo "RssPressReview::addSourceFeed($url, $estimated_publication_interval)<br>\n"; |
|---|
| 233 | $retval = false; |
|---|
| 234 | if(empty($estimated_publication_interval)) |
|---|
| 235 | { |
|---|
| 236 | $estimated_publication_interval = DEFAULT_PUBLICATION_INTERVAL; |
|---|
| 237 | } |
|---|
| 238 | if (!empty ($url)) |
|---|
| 239 | { |
|---|
| 240 | $old_error_level = error_reporting(E_ERROR); |
|---|
| 241 | $rss = fetch_rss(trim($url)); |
|---|
| 242 | //echo "<pre>"; print_r($rss);echo "</pre>"; |
|---|
| 243 | error_reporting($old_error_level); |
|---|
| 244 | |
|---|
| 245 | if ($rss && $source_bias > 0) |
|---|
| 246 | { |
|---|
| 247 | $this->rss_sources[trim($url)] = array ('default_publication_interval' => $estimated_publication_interval, 'magpie_array' => $rss, 'source_bias' => $source_bias); |
|---|
| 248 | $this->computePublicationInterval(trim($url)); |
|---|
| 249 | $retval = true; |
|---|
| 250 | } |
|---|
| 251 | |
|---|
| 252 | } |
|---|
| 253 | else |
|---|
| 254 | { |
|---|
| 255 | echo _('addSourceFeed(): url is empty!'); |
|---|
| 256 | } |
|---|
| 257 | return $retval; |
|---|
| 258 | } |
|---|
| 259 | |
|---|
| 260 | /** Is the feed in rss_sources. Equivalent to checking the |
|---|
| 261 | * return of addSourceFeed(), but can be called at any time. Will |
|---|
| 262 | * return false if the feed could not be retrieven or coulsdn't be parsed. |
|---|
| 263 | * @param $url |
|---|
| 264 | * @return true if the feed has been successfully retrieved */ |
|---|
| 265 | function isFeedAvailable($url) |
|---|
| 266 | { |
|---|
| 267 | if (isset ($this->rss_sources[$url])) |
|---|
| 268 | { |
|---|
| 269 | $retval = true; |
|---|
| 270 | } |
|---|
| 271 | else |
|---|
| 272 | { |
|---|
| 273 | $retval = false; |
|---|
| 274 | } |
|---|
| 275 | return $retval; |
|---|
| 276 | } |
|---|
| 277 | |
|---|
| 278 | /** Return the title of the feed, if the feed contains title information. |
|---|
| 279 | * @param $url |
|---|
| 280 | * @return Title or false if unavailable */ |
|---|
| 281 | function getFeedTitle($url) |
|---|
| 282 | { |
|---|
| 283 | $retval = false; |
|---|
| 284 | if (isset ($this->rss_sources[$url])&& isset ($this->rss_sources[$url]['magpie_array']->channel['title'])) |
|---|
| 285 | { |
|---|
| 286 | $retval = $this->rss_sources[$url]['magpie_array']->channel['title']; |
|---|
| 287 | } |
|---|
| 288 | return $retval; |
|---|
| 289 | } |
|---|
| 290 | |
|---|
| 291 | /** Return the computed publication interval of the feed, if the feed contained date information. |
|---|
| 292 | * @param $url |
|---|
| 293 | * @return publication interval in seconds or false if unavailable */ |
|---|
| 294 | function getFeedPublicationInterval($url) |
|---|
| 295 | { |
|---|
| 296 | if (isset ($this->rss_sources[$url]['rpr_real_publication_interval'])) |
|---|
| 297 | { |
|---|
| 298 | $retval = $this->rss_sources[$url]['rpr_real_publication_interval']; |
|---|
| 299 | } |
|---|
| 300 | else |
|---|
| 301 | { |
|---|
| 302 | $retval = false; |
|---|
| 303 | } |
|---|
| 304 | return $retval; |
|---|
| 305 | } |
|---|
| 306 | |
|---|
| 307 | /** Calculate the publication interval of a feed's items. This will fail if there is no date field that can be used. In this case we calculate approximate intervals based on the default publication interval. That is we assume one item is published every default publication interval, starting from half the interval in the past (to avoid always having one item published now, skewing the result. |
|---|
| 308 | * @param $url The feed's url |
|---|
| 309 | * @return true on success, false on failure |
|---|
| 310 | */ |
|---|
| 311 | function computePublicationInterval($url) |
|---|
| 312 | { |
|---|
| 313 | $i = 0; |
|---|
| 314 | $real_date_missing = false; /**< Is at least one of the item missing a date? */ |
|---|
| 315 | $publication_interval_total = null; |
|---|
| 316 | /**< running total of the difference between the date of the current item and the previous one */ |
|---|
| 317 | $feed_publication_interval = null; |
|---|
| 318 | $previous_item_date = null; |
|---|
| 319 | $rss = & $this->rss_sources[trim($url)]['magpie_array']; |
|---|
| 320 | if (!$rss) |
|---|
| 321 | { |
|---|
| 322 | echo _("computePublicationInterval(): Missing feed!"); |
|---|
| 323 | return false; |
|---|
| 324 | } |
|---|
| 325 | |
|---|
| 326 | //$rss->show_channel(); |
|---|
| 327 | //$rss->show_list(); |
|---|
| 328 | |
|---|
| 329 | /* Sort the array in chronological order */ |
|---|
| 330 | |
|---|
| 331 | /* foreach ($rss->items as $item) {echo "$item[title] ". self::_get_item_date($item) . "<br>\n";}*/ |
|---|
| 332 | if (!uasort($rss->items, array ("RssPressReview", "_cmp_date_item"))) |
|---|
| 333 | { |
|---|
| 334 | echo _('computePublicationInterval(): uasort() failed'); |
|---|
| 335 | return false; |
|---|
| 336 | } |
|---|
| 337 | /* foreach ($rss->items as $item) {echo "$item[title] ". self::_get_item_date($item) . "<br>\n";}*/ |
|---|
| 338 | |
|---|
| 339 | /* Calculate the publication interval for the feed */ |
|---|
| 340 | foreach ($rss->items as $item_key => $item) |
|---|
| 341 | { |
|---|
| 342 | $date = $this->_get_item_date($item); |
|---|
| 343 | $rss->items[$item_key]['rpr_realphpdate'] = $date; |
|---|
| 344 | if ($date == -1) |
|---|
| 345 | { |
|---|
| 346 | /* |
|---|
| 347 | * If we do not know the date, for statistics purposes, |
|---|
| 348 | * we will set the date as if a news item was published |
|---|
| 349 | * every default_publication_interval, starting from half the interval in the past |
|---|
| 350 | * (to avoid always having one item published now, skewing the result). |
|---|
| 351 | */ |
|---|
| 352 | $date = time() - ($i * $this->rss_sources[$url]['default_publication_interval'] + $this->rss_sources[$url]['default_publication_interval'] / 2); |
|---|
| 353 | $real_date_missing = true; |
|---|
| 354 | } |
|---|
| 355 | |
|---|
| 356 | if ($i > 0) |
|---|
| 357 | { |
|---|
| 358 | $publication_interval_total += $previous_item_date - $date; |
|---|
| 359 | } |
|---|
| 360 | |
|---|
| 361 | $previous_item_date = $date; |
|---|
| 362 | $rss->items[$item_key]['rpr_computed_phpdate'] = $date; /** So every item has sone kind of a date */ |
|---|
| 363 | $i ++; |
|---|
| 364 | } // End foreach items |
|---|
| 365 | |
|---|
| 366 | $this->rss_sources[$url]['rpr_number_of_items'] = $i; |
|---|
| 367 | |
|---|
| 368 | if ($i >= 2 && $publication_interval_total != 0) |
|---|
| 369 | { |
|---|
| 370 | $feed_publication_interval = $publication_interval_total / ($i -1); |
|---|
| 371 | $this->rss_sources[$url]['rpr_computed_publication_interval'] = $feed_publication_interval; |
|---|
| 372 | if ($real_date_missing == false) |
|---|
| 373 | { |
|---|
| 374 | $this->rss_sources[$url]['rpr_real_publication_interval'] = $feed_publication_interval; |
|---|
| 375 | } |
|---|
| 376 | } |
|---|
| 377 | else |
|---|
| 378 | { |
|---|
| 379 | $this->rss_sources[$url]['rpr_computed_publication_interval'] = $this->rss_sources[$url]['default_publication_interval']; |
|---|
| 380 | } |
|---|
| 381 | //echo "<pre>"; print_r($this->rss_sources[$url]);echo "</pre>"; |
|---|
| 382 | return true; |
|---|
| 383 | } |
|---|
| 384 | |
|---|
| 385 | /** Return the combined RSS of all the sources, in an extended magpie format |
|---|
| 386 | @param $number_of_items_to_display The total number of items to display. |
|---|
| 387 | @param $last_visit: Optionnal, timestamp. The date of the user's last visit. If set, allows the system to set the rpr_is_new field. |
|---|
| 388 | Note that it will only do it for items that have the are |
|---|
| 389 | in the return array |
|---|
| 390 | @return An array of RSS information, false on failure |
|---|
| 391 | */ |
|---|
| 392 | function get_rss_info($number_of_items_to_display = 20, $last_visit = null) |
|---|
| 393 | { |
|---|
| 394 | $debug = false; |
|---|
| 395 | //echo "<pre>"; print_r($this->rss_sources);echo "</pre>"; |
|---|
| 396 | if ($debug) |
|---|
| 397 | echo "RssPressReview::get_rss_info($number_of_items_to_display)<br>\n"; |
|---|
| 398 | |
|---|
| 399 | /* Calculate the average publication interval for all feeds */ |
|---|
| 400 | $all_feed_publication_interval_total = null; |
|---|
| 401 | reset($this->rss_sources); |
|---|
| 402 | foreach ($this->rss_sources as $rss_source) |
|---|
| 403 | { |
|---|
| 404 | $all_feed_publication_interval_total += $rss_source['rpr_computed_publication_interval']; |
|---|
| 405 | } |
|---|
| 406 | $all_feed_publication_interval = $all_feed_publication_interval_total / count($this->rss_sources); |
|---|
| 407 | |
|---|
| 408 | /*Calculate the adjusted dates and create the date list array. */ |
|---|
| 409 | $item_date_array = array (); |
|---|
| 410 | $item_date_array_index = 0; |
|---|
| 411 | |
|---|
| 412 | foreach ($this->rss_sources as $rss_sources_key => $rss_source) |
|---|
| 413 | { |
|---|
| 414 | foreach ($rss_source['magpie_array']->items as $item_key => $item) |
|---|
| 415 | { |
|---|
| 416 | /* Calculate the adjusted date */ |
|---|
| 417 | $feed_publication_interval = $rss_source['rpr_computed_publication_interval']; |
|---|
| 418 | $source_bias = $rss_source['source_bias']; |
|---|
| 419 | $distance_to_today = abs(time() - $item['rpr_computed_phpdate']); |
|---|
| 420 | /* With no strength modifier, a feed with a publication twice as long will get a 2x bonus on the distance to today */ |
|---|
| 421 | $original_adjust_factor = $all_feed_publication_interval / $feed_publication_interval; |
|---|
| 422 | if ($original_adjust_factor < 1) |
|---|
| 423 | { |
|---|
| 424 | $algorithm_strength_modifier = 1 / $this->algorithm_strength_modifier; |
|---|
| 425 | } |
|---|
| 426 | |
|---|
| 427 | /*Algorithm strength modifier doit modifier la difference de lécart du ratio |
|---|
| 428 | $all_feed_publication_interval / $feed_publication_interval avec 1/1.*/ |
|---|
| 429 | $adjust_factor = 1 - (1 - $original_adjust_factor) * $this->algorithm_strength_modifier; |
|---|
| 430 | |
|---|
| 431 | $this->rss_sources[$rss_sources_key]['magpie_array']->items[$item_key]['rpr_adjusted_date'] = time() - ($distance_to_today * $adjust_factor) / $source_bias; |
|---|
| 432 | |
|---|
| 433 | /* Memorize each date, and publication intervals so we can determine the "oldest" item to publish |
|---|
| 434 | * Only consider items whose date is not farther from today than max_item_age */ |
|---|
| 435 | if ($this->max_item_age == null || abs(time() - $item['rpr_computed_phpdate']) < $this->max_item_age) |
|---|
| 436 | { |
|---|
| 437 | $item_date_array[$item_date_array_index]['rpr_adjusted_date'] = $this->rss_sources[$rss_sources_key]['magpie_array']->items[$item_key]['rpr_adjusted_date']; |
|---|
| 438 | $item_date_array[$item_date_array_index]['rpr_computed_phpdate'] = $this->rss_sources[$rss_sources_key]['magpie_array']->items[$item_key]['rpr_computed_phpdate']; |
|---|
| 439 | $item_date_array[$item_date_array_index]['rss_sources_key'] = $rss_sources_key; |
|---|
| 440 | $item_date_array_index ++; |
|---|
| 441 | } |
|---|
| 442 | |
|---|
| 443 | if (isset ($this->rss_sources[$rss_sources_key]['magpie_array']->items[$item_key]['rpr_realphpdate'])) |
|---|
| 444 | { |
|---|
| 445 | /* Check if the item is newer than the last visit */ |
|---|
| 446 | if ($last_visit != null && $item['rpr_realphpdate'] > $last_visit) |
|---|
| 447 | { |
|---|
| 448 | $this->rss_sources[$rss_sources_key]['magpie_array']->items[$item_key]['rpr_is_new'] = true; |
|---|
| 449 | } |
|---|
| 450 | |
|---|
| 451 | /* Check if the item has been published today */ |
|---|
| 452 | $item_getdate = getdate($this->rss_sources[$rss_sources_key]['magpie_array']->items[$item_key]['rpr_realphpdate']); |
|---|
| 453 | $today_getdate = getdate(); |
|---|
| 454 | if ($item_getdate['year'] == $today_getdate['year'] && $item_getdate['yday'] == $today_getdate['yday']) |
|---|
| 455 | { |
|---|
| 456 | $this->rss_sources[$rss_sources_key]['magpie_array']->items[$item_key]['rpr_is_today'] = true; |
|---|
| 457 | } |
|---|
| 458 | else |
|---|
| 459 | { |
|---|
| 460 | $this->rss_sources[$rss_sources_key]['magpie_array']->items[$item_key]['rpr_is_today'] = false; |
|---|
| 461 | } |
|---|
| 462 | } |
|---|
| 463 | $content = null; |
|---|
| 464 | if(!empty($item['atom_content'])) |
|---|
| 465 | { |
|---|
| 466 | $content = $item['atom_content']; |
|---|
| 467 | } |
|---|
| 468 | else if(!empty($item['content']['encoded'])) |
|---|
| 469 | { |
|---|
| 470 | $content = $item['content']['encoded']; |
|---|
| 471 | } |
|---|
| 472 | else if(!empty($item['summary'])) |
|---|
| 473 | { |
|---|
| 474 | $content = $item['summary']; |
|---|
| 475 | } |
|---|
| 476 | $this->rss_sources[$rss_sources_key]['magpie_array']->items[$item_key]['rpr_content'] = $content; |
|---|
| 477 | |
|---|
| 478 | $summary = null; |
|---|
| 479 | if(!empty($item['summary'])) |
|---|
| 480 | { |
|---|
| 481 | $summary = $item['summary']; |
|---|
| 482 | } |
|---|
| 483 | else |
|---|
| 484 | { |
|---|
| 485 | $summary = $content; |
|---|
| 486 | } |
|---|
| 487 | $this->rss_sources[$rss_sources_key]['magpie_array']->items[$item_key]['rpr_summary'] = $summary; |
|---|
| 488 | |
|---|
| 489 | } |
|---|
| 490 | |
|---|
| 491 | //echo "<p>$i items, average_publication_interval (days) = ". $this->rss_sources[$rss_sources_key]['average_publication_interval']/(3600 * 24) . "</p>\n"; |
|---|
| 492 | } // End foreach rss feeds |
|---|
| 493 | |
|---|
| 494 | /* Sort the item date array by adjusted date. */ |
|---|
| 495 | usort($item_date_array, array ("RssPressReview", "_cmp_rpr_adjusted_date")); |
|---|
| 496 | |
|---|
| 497 | /*echo "<pre>"; |
|---|
| 498 | print_r($item_date_array); |
|---|
| 499 | echo "</pre>";*/ |
|---|
| 500 | /* Find the "oldest" adjusted date to display */ |
|---|
| 501 | if (count($item_date_array) < $number_of_items_to_display) |
|---|
| 502 | { |
|---|
| 503 | $number_of_items_to_display = count($item_date_array); |
|---|
| 504 | } |
|---|
| 505 | $min_rpr_adjusted_date_to_display = $item_date_array[$number_of_items_to_display -1]['rpr_adjusted_date']; |
|---|
| 506 | |
|---|
| 507 | if ($debug) |
|---|
| 508 | echo "min_rpr_adjusted_date_to_display: $min_rpr_adjusted_date_to_display<br>\n"; |
|---|
| 509 | /************** Now we actually display the feeds **************/ |
|---|
| 510 | reset($this->rss_sources); |
|---|
| 511 | $rss_info_tmp = null; |
|---|
| 512 | foreach ($this->rss_sources as $rss_sources_key => $rss_source) |
|---|
| 513 | { |
|---|
| 514 | if (!$rss_source['magpie_array']) |
|---|
| 515 | { |
|---|
| 516 | echo _('get_rss_info(): Feed missing'); |
|---|
| 517 | return false; |
|---|
| 518 | } |
|---|
| 519 | else |
|---|
| 520 | { |
|---|
| 521 | unset ($rss_info_tmp); |
|---|
| 522 | $rss_info_tmp['channel'] = $this->rss_sources[$rss_sources_key]['magpie_array']->channel; |
|---|
| 523 | |
|---|
| 524 | $i = 0; |
|---|
| 525 | /* Sort the items by date, so we get the most recent first */ |
|---|
| 526 | if (!uasort($this->rss_sources[$rss_sources_key]['magpie_array']->items, array ("RssPressReview", "_cmp_date_item"))) |
|---|
| 527 | { |
|---|
| 528 | echo _('get_rss_info(): uasort() failed!'); |
|---|
| 529 | return false; |
|---|
| 530 | } |
|---|
| 531 | |
|---|
| 532 | $rss_info_tmp['items'] = array (); |
|---|
| 533 | foreach ($this->rss_sources[$rss_sources_key]['magpie_array']->items as $item_key => $item) |
|---|
| 534 | { |
|---|
| 535 | if ($debug) |
|---|
| 536 | echo "Is item with rpr_adjusted_date: ".$item['rpr_adjusted_date']." after the minimum date: $min_rpr_adjusted_date_to_display?<br>\n"; |
|---|
| 537 | |
|---|
| 538 | if ($item['rpr_adjusted_date'] >= $min_rpr_adjusted_date_to_display) |
|---|
| 539 | { |
|---|
| 540 | if ($debug) |
|---|
| 541 | echo "YES!<br>\n"; |
|---|
| 542 | if (!empty ($item['dc']['creator'])) |
|---|
| 543 | { |
|---|
| 544 | $this->rss_sources[$rss_sources_key]['magpie_array']->items[$item_key]['rpr_author'] = trim($item['dc']['creator']); |
|---|
| 545 | } |
|---|
| 546 | elseif (!empty ($item['author'])) |
|---|
| 547 | { |
|---|
| 548 | $this->rss_sources[$rss_sources_key]['magpie_array']->items[$item_key]['rpr_author'] = trim($item['author']); |
|---|
| 549 | } |
|---|
| 550 | elseif (!empty ($item['author_name'])) |
|---|
| 551 | { |
|---|
| 552 | $this->rss_sources[$rss_sources_key]['magpie_array']->items[$item_key]['rpr_author'] = trim($item['author_name']); |
|---|
| 553 | } |
|---|
| 554 | else |
|---|
| 555 | { |
|---|
| 556 | $this->rss_sources[$rss_sources_key]['magpie_array']->items[$item_key]['rpr_author'] = ''; |
|---|
| 557 | } |
|---|
| 558 | |
|---|
| 559 | $this->rss_sources[$rss_sources_key]['magpie_array']->items[$item_key]['rpr_id'] = "summary_".mt_rand(1, 10000); |
|---|
| 560 | array_push($rss_info_tmp['items'], $this->rss_sources[$rss_sources_key]['magpie_array']->items[$item_key]); |
|---|
| 561 | } |
|---|
| 562 | $i ++; |
|---|
| 563 | } // End foreach items |
|---|
| 564 | |
|---|
| 565 | if ($debug) |
|---|
| 566 | echo count($rss_info_tmp['items'])." items (out of ".count($rss->items).") are after the minimum date in feed $rss_sources_key<br>\n"; |
|---|
| 567 | |
|---|
| 568 | $rss_info[$rss_sources_key] = $rss_info_tmp; |
|---|
| 569 | } |
|---|
| 570 | } // End foreach rss feeds |
|---|
| 571 | /*echo "\n<pre>\n"; |
|---|
| 572 | print_r($rss_info); |
|---|
| 573 | echo "\n</pre>\n"; |
|---|
| 574 | */ |
|---|
| 575 | return $rss_info; |
|---|
| 576 | |
|---|
| 577 | } |
|---|
| 578 | |
|---|
| 579 | function get_rss_header() |
|---|
| 580 | { |
|---|
| 581 | static $done_header = false; |
|---|
| 582 | |
|---|
| 583 | if (!$done_header) |
|---|
| 584 | { |
|---|
| 585 | $done_header = true; |
|---|
| 586 | return ' |
|---|
| 587 | |
|---|
| 588 | <script language="JavaScript" type="text/javascript"> |
|---|
| 589 | function MM_findObj(n, d) { //v4.0 |
|---|
| 590 | var p,i,x; |
|---|
| 591 | if(!d) d=document; |
|---|
| 592 | if((p=n.indexOf("?"))>0&&parent.frames.length) { |
|---|
| 593 | d=parent.frames[n.substring(p+1)].document; |
|---|
| 594 | n=n.substring(0,p); |
|---|
| 595 | } |
|---|
| 596 | if(!(x=d[n])&&d.all) x=d.all[n]; |
|---|
| 597 | for (i=0;!x&&i<d.forms.length;i++) x=d.forms[i][n]; |
|---|
| 598 | for(i=0;!x&&d.layers&&i<d.layers.length;i++) x=MM_findObj(n,d.layers[i].document); |
|---|
| 599 | if(!x && document.getElementById) x=document.getElementById(n); return x; |
|---|
| 600 | } |
|---|
| 601 | |
|---|
| 602 | function changestyle(couche, style) { |
|---|
| 603 | if (!(layer = MM_findObj(couche))) return; |
|---|
| 604 | if(layer.className != "rpr_popup_inner_div_expanded") |
|---|
| 605 | { |
|---|
| 606 | layer.style.visibility = style; |
|---|
| 607 | } |
|---|
| 608 | } |
|---|
| 609 | |
|---|
| 610 | function changeclass(objet, myClass) |
|---|
| 611 | { |
|---|
| 612 | objet.className = myClass; |
|---|
| 613 | } |
|---|
| 614 | |
|---|
| 615 | function toggleItemVisibility(item_id) |
|---|
| 616 | { |
|---|
| 617 | if (!(layer = MM_findObj(item_id))) return; |
|---|
| 618 | if(layer.className != "rpr_popup_inner_div_expanded") |
|---|
| 619 | { |
|---|
| 620 | layer.style.visibility = "visible"; |
|---|
| 621 | layer.className = "rpr_popup_inner_div_expanded"; |
|---|
| 622 | } |
|---|
| 623 | else |
|---|
| 624 | { |
|---|
| 625 | layer.style.visibility = "hidden"; |
|---|
| 626 | layer.className = "rpr_popup_inner_div"; |
|---|
| 627 | } |
|---|
| 628 | } |
|---|
| 629 | </script> |
|---|
| 630 | |
|---|
| 631 | <style type="text/css"> |
|---|
| 632 | |
|---|
| 633 | /*h2 {color: green}*/ |
|---|
| 634 | .rpr_header {margin: 0em 0em 0em 0em; |
|---|
| 635 | padding: 0em 0em 0em 0em;} |
|---|
| 636 | .rpr_title { font-weight: bold; |
|---|
| 637 | font-size: 90%} |
|---|
| 638 | .rpr_title_date { font-weight: lighter; } |
|---|
| 639 | |
|---|
| 640 | .rpr_item_list { |
|---|
| 641 | padding: 0em 1em 0em 1em; |
|---|
| 642 | margin: 0em 1em 0em 1em;} |
|---|
| 643 | .rpr_item { list-style-type: none; |
|---|
| 644 | } |
|---|
| 645 | .rpr_item_title { |
|---|
| 646 | margin: 0em 0em 0em 0em; |
|---|
| 647 | padding: 0em 0em 0em 0em;} |
|---|
| 648 | |
|---|
| 649 | |
|---|
| 650 | .rpr_item_link { } |
|---|
| 651 | .rpr_expand_switch { font-weight: bolder; |
|---|
| 652 | text-decoration: none; |
|---|
| 653 | /*border: 1px solid black*/ } |
|---|
| 654 | /*.rpr_expand_switch:before { content: "+"; }*/ |
|---|
| 655 | |
|---|
| 656 | .rpr_popup_inner_div { |
|---|
| 657 | z-index: 1000; |
|---|
| 658 | display: inline; |
|---|
| 659 | padding: 0.5em; |
|---|
| 660 | border: 2px outset #324C48; |
|---|
| 661 | background-color: #f9f9f9; |
|---|
| 662 | visibility: hidden; |
|---|
| 663 | position: absolute; |
|---|
| 664 | left: 4em; |
|---|
| 665 | top: 1.5em; |
|---|
| 666 | width: 350px; |
|---|
| 667 | -moz-opacity: 0.95; filter: alpha(opacity=95); |
|---|
| 668 | } |
|---|
| 669 | |
|---|
| 670 | .rpr_popup_inner_div_expanded { |
|---|
| 671 | margin: 0.5em 1em 0em 1em; |
|---|
| 672 | padding: 0.5em; |
|---|
| 673 | border: 2px outset #324C48; |
|---|
| 674 | background-color: #f9f9f9; |
|---|
| 675 | } |
|---|
| 676 | .rpr_popup_outer_div { |
|---|
| 677 | z-index: 1000; |
|---|
| 678 | position: relative; |
|---|
| 679 | display: inline; |
|---|
| 680 | } |
|---|
| 681 | |
|---|
| 682 | |
|---|
| 683 | </style> |
|---|
| 684 | |
|---|
| 685 | '; |
|---|
| 686 | |
|---|
| 687 | |
|---|
| 688 | } |
|---|
| 689 | } |
|---|
| 690 | |
|---|
| 691 | /** |
|---|
| 692 | @param $show_empty_sources Should we show the feed information even if no news item has be selected? |
|---|
| 693 | */ |
|---|
| 694 | function get_rss_html($number_of_items_to_display = 20, $last_visit = null, $show_empty_sources = true) |
|---|
| 695 | { |
|---|
| 696 | $rss_result = $this->get_rss_info($number_of_items_to_display, $last_visit); |
|---|
| 697 | |
|---|
| 698 | $html = ''; |
|---|
| 699 | foreach ($rss_result as $feed_id => $feed) |
|---|
| 700 | { |
|---|
| 701 | if (count($feed['items']) > 0 || $show_empty_sources == true) |
|---|
| 702 | { |
|---|
| 703 | $feed_html = ''; |
|---|
| 704 | $dhtml_id = "feed_".md5($feed_id); |
|---|
| 705 | $feed_html .= "<p class='rpr_header'>"._('Source: '); |
|---|
| 706 | $feed_html .= "<span class='rpr_title' onMouseOver=\"changestyle('$dhtml_id','visible');\" onMouseOut=\"changestyle('$dhtml_id','hidden');\">\n"; |
|---|
| 707 | if (!empty ($feed['link'])) |
|---|
| 708 | { |
|---|
| 709 | $feed_html .= "<a class='y' href='".$feed['link']."'>".$feed['channel']['title']."</a>"; |
|---|
| 710 | } |
|---|
| 711 | else |
|---|
| 712 | { |
|---|
| 713 | $feed_html .= $feed['channel']['title']; |
|---|
| 714 | } |
|---|
| 715 | $feed_html .= "</span>\n"; |
|---|
| 716 | $feed_html .= "</p>\n"; |
|---|
| 717 | |
|---|
| 718 | $feed_html .= "<div class='rpr_popup_outer_div'>\n"; |
|---|
| 719 | $feed_html .= "<div id='$dhtml_id' class='rpr_popup_inner_div'>\n"; |
|---|
| 720 | $feed_html .= "<p class='rpr_text'>{$feed['channel']['title']} </p>\n"; |
|---|
| 721 | if(!empty($feed['channel']['description'])) |
|---|
| 722 | { |
|---|
| 723 | $description = strip_tags($feed['channel']['description'], "<p><a><img><b><i>"); |
|---|
| 724 | $feed_html .= "<p class='rpr_text'>{$description}</p>\n"; |
|---|
| 725 | } |
|---|
| 726 | $feed_html .= "<p class='rpr_text'>{$feed_id}</p>\n"; |
|---|
| 727 | $feed_html .= "</div></div>\n"; |
|---|
| 728 | |
|---|
| 729 | $feed_html .= "<ul class='rpr_item_list'>\n"; |
|---|
| 730 | |
|---|
| 731 | foreach ($feed['items'] as $item) |
|---|
| 732 | { |
|---|
| 733 | if ($item['rpr_is_today']) |
|---|
| 734 | { |
|---|
| 735 | $display_date = _("Today"); |
|---|
| 736 | } |
|---|
| 737 | else if ($item['rpr_realphpdate'] != -1) |
|---|
| 738 | { |
|---|
| 739 | setlocale(LC_TIME, "fr_CA"); |
|---|
| 740 | $display_date = strftime("%x", $item['rpr_realphpdate']); |
|---|
| 741 | } |
|---|
| 742 | else |
|---|
| 743 | { |
|---|
| 744 | $display_date = ''; |
|---|
| 745 | //$display_date = "Estimated: ".strftime("%x", $item['rpr_computed_phpdate']); |
|---|
| 746 | } |
|---|
| 747 | |
|---|
| 748 | $dhtml_id = "summary_".mt_rand(1, 10000); |
|---|
| 749 | $feed_html .= "<li class='rpr_item'>\n"; |
|---|
| 750 | $feed_html .= "<p class='rpr_item_title'>\n"; |
|---|
| 751 | $item['rpr_is_today'] ? $switch_content = '-':$switch_content = '+'; |
|---|
| 752 | |
|---|
| 753 | $feed_html .= "<a class='rpr_expand_switch' href='#dummy' onClick=\"toggleItemVisibility('$dhtml_id'); if(this.innerHTML=='+'){this.innerHTML='-';}else{this.innerHTML='+';}\">$switch_content</a> "; |
|---|
| 754 | $feed_html .= "<span class='rpr_title_date'>$display_date</span>"; |
|---|
| 755 | $feed_html .= "<span class='rpr_title' onMouseOver=\"changestyle('$dhtml_id','visible');\" onMouseOut=\"changestyle('$dhtml_id','hidden');\">\n"; |
|---|
| 756 | if ($item['link']) |
|---|
| 757 | { |
|---|
| 758 | $feed_html .= "<a class='rpr_item_link' href='{$item['link']}'>{$item['title']}</a>"; |
|---|
| 759 | } |
|---|
| 760 | else |
|---|
| 761 | { |
|---|
| 762 | $feed_html .= "{$item['title']}"; |
|---|
| 763 | } |
|---|
| 764 | $feed_html .= "</span></p>\n"; |
|---|
| 765 | $feed_html .= "<div class='rpr_popup_outer_div'>\n"; |
|---|
| 766 | $item['rpr_is_today'] ? $class = 'rpr_popup_inner_div_expanded':$class = 'rpr_popup_inner_div'; |
|---|
| 767 | $feed_html .= "<div class='$class' id='$dhtml_id'>\n"; |
|---|
| 768 | $feed_html .= "<p class='rpr_text'>{$item['rpr_author']} ({$feed['channel']['title']}) $display_date</p>\n"; |
|---|
| 769 | $summary = strip_tags($item['rpr_content'], "<br><p><a><img><b><i>"); |
|---|
| 770 | $feed_html .= "<p class='rpr_text'>{$summary}</p></div>\n"; |
|---|
| 771 | $feed_html .= "</div>\n"; |
|---|
| 772 | $feed_html .= "</li>\n"; |
|---|
| 773 | } |
|---|
| 774 | $feed_html .= "</ul>\n"; |
|---|
| 775 | |
|---|
| 776 | $html .= $feed_html; |
|---|
| 777 | } |
|---|
| 778 | } |
|---|
| 779 | return $this->get_rss_header().$html; |
|---|
| 780 | } |
|---|
| 781 | } |
|---|
| 782 | ?> |
|---|
| 783 | |
|---|
| 784 | |
|---|
| 785 | |
|---|
| 786 | |
|---|
| 787 | |
|---|
| 788 | |
|---|
| 789 | |
|---|