197 public function parser($urlRSS, $maxNb = 0, $cachedelay = 60, $cachedir =
'')
201 include_once DOL_DOCUMENT_ROOT.
'/core/lib/files.lib.php';
202 include_once DOL_DOCUMENT_ROOT.
'/core/lib/geturl.lib.php';
209 $this->error =
"ErrorBadUrl";
213 $this->_urlRSS = $urlRSS;
214 $newpathofdestfile = $cachedir.
'/'.
dol_hash($this->_urlRSS, 3);
222 if ($cachedelay > 0 && $cachedir) {
224 if ($filedate >= ($nowgmt - $cachedelay)) {
228 $this->_lastfetchdate = $filedate;
230 dol_syslog(get_class($this).
"::parser cache file ".$newpathofdestfile.
" is not found or older than now - cachedelay (".$nowgmt.
" - ".$cachedelay.
") so we can't use it.");
235 if ($foundintocache) {
236 $str = file_get_contents($newpathofdestfile);
239 $result =
getURLContent($this->_urlRSS,
'GET',
'', 1, array(), array(
'http',
'https'), 0);
241 if (!empty($result[
'content'])) {
242 $str = $result[
'content'];
243 } elseif (!empty($result[
'curl_error_msg'])) {
244 $this->error =
'Error retrieving URL '.$this->_urlRSS.
' - '.$result[
'curl_error_msg'];
248 $this->error =
'Error retrieving URL '.$this->_urlRSS.
' - '.$e->getMessage();
253 if ($str !==
false) {
255 if (!empty($conf->global->EXTERNALRSS_USE_SIMPLEXML)) {
257 libxml_use_internal_errors(
false);
258 $rss = simplexml_load_string($str,
"SimpleXMLElement", LIBXML_NOCDATA|LIBXML_NOCDATA);
260 if (!function_exists(
'xml_parser_create')) {
261 $this->error =
'Function xml_parser_create are not supported by your PHP';
266 $xmlparser = xml_parser_create(
null);
268 if (!is_resource($xmlparser) && !is_object($xmlparser)) {
269 $this->error =
"ErrorFailedToCreateParser";
273 xml_set_object($xmlparser, $this);
274 xml_set_element_handler($xmlparser,
'feed_start_element',
'feed_end_element');
275 xml_set_character_data_handler($xmlparser,
'feed_cdata');
277 $status = xml_parse($xmlparser, $str,
false);
279 xml_parser_free($xmlparser);
291 if (empty($foundintocache) && $cachedir) {
292 dol_syslog(get_class($this).
"::parser cache file ".$newpathofdestfile.
" is saved onto disk.");
296 $fp = fopen($newpathofdestfile,
'w');
302 $this->_lastfetchdate = $nowgmt;
304 print
'Error, failed to open file '.$newpathofdestfile.
' for write';
310 if (empty($rss->_format)) {
311 $rss->_format =
'rss';
312 if (empty($rss->channel)) {
313 $rss->_format =
'atom';
320 if ($rss->_format ==
'rss') {
322 if (!empty($conf->global->EXTERNALRSS_USE_SIMPLEXML)) {
323 if (!empty($rss->channel->language)) {
324 $this->_language =
sanitizeVal((
string) $rss->channel->language);
326 if (!empty($rss->channel->generator)) {
327 $this->_generator =
sanitizeVal((
string) $rss->channel->generator);
329 if (!empty($rss->channel->copyright)) {
330 $this->_copyright =
sanitizeVal((
string) $rss->channel->copyright);
332 if (!empty($rss->channel->lastbuilddate)) {
333 $this->_lastbuilddate =
sanitizeVal((
string) $rss->channel->lastbuilddate);
335 if (!empty($rss->channel->image->url[0])) {
336 $this->_imageurl =
sanitizeVal((
string) $rss->channel->image->url[0]);
338 if (!empty($rss->channel->link)) {
339 $this->_link =
sanitizeVal((
string) $rss->channel->link);
341 if (!empty($rss->channel->title)) {
342 $this->_title =
sanitizeVal((
string) $rss->channel->title);
344 if (!empty($rss->channel->description)) {
345 $this->_description =
sanitizeVal((
string) $rss->channel->description);
349 if (!empty($rss->channel[
'language'])) {
350 $this->_language =
sanitizeVal((
string) $rss->channel[
'language']);
352 if (!empty($rss->channel[
'generator'])) {
353 $this->_generator =
sanitizeVal((
string) $rss->channel[
'generator']);
355 if (!empty($rss->channel[
'copyright'])) {
356 $this->_copyright =
sanitizeVal((
string) $rss->channel[
'copyright']);
358 if (!empty($rss->channel[
'lastbuilddate'])) {
359 $this->_lastbuilddate =
sanitizeVal((
string) $rss->channel[
'lastbuilddate']);
361 if (!empty($rss->image[
'url'])) {
362 $this->_imageurl =
sanitizeVal((
string) $rss->image[
'url']);
364 if (!empty($rss->channel[
'link'])) {
365 $this->_link =
sanitizeVal((
string) $rss->channel[
'link']);
367 if (!empty($rss->channel[
'title'])) {
368 $this->_title =
sanitizeVal((
string) $rss->channel[
'title']);
370 if (!empty($rss->channel[
'description'])) {
371 $this->_description =
sanitizeVal((
string) $rss->channel[
'description']);
375 if (!empty($conf->global->EXTERNALRSS_USE_SIMPLEXML)) {
376 $items = $rss->channel->item;
378 $items = $rss->items;
381 } elseif ($rss->_format ==
'atom') {
383 if (!empty($conf->global->EXTERNALRSS_USE_SIMPLEXML)) {
384 if (!empty($rss->generator)) {
385 $this->_generator =
sanitizeVal((
string) $rss->generator);
387 if (!empty($rss->lastbuilddate)) {
388 $this->_lastbuilddate =
sanitizeVal((
string) $rss->modified);
390 if (!empty($rss->link->href)) {
391 $this->_link =
sanitizeVal((
string) $rss->link->href);
393 if (!empty($rss->title)) {
396 if (!empty($rss->description)) {
397 $this->_description =
sanitizeVal((
string) $rss->description);
401 if (!empty($rss->channel[
'generator'])) {
402 $this->_generator =
sanitizeVal((
string) $rss->channel[
'generator']);
405 if (!empty($rss->channel[
'modified'])) {
406 $this->_lastbuilddate =
sanitizeVal((
string) $rss->channel[
'modified']);
409 if (!empty($rss->channel[
'link'])) {
410 $this->_link =
sanitizeVal((
string) $rss->channel[
'link']);
412 if (!empty($rss->channel[
'title'])) {
413 $this->_title =
sanitizeVal((
string) $rss->channel[
'title']);
417 if (!empty($rss->channel)) {
421 if (!empty($conf->global->EXTERNALRSS_USE_SIMPLEXML)) {
423 $items = $tmprss[
'entry'];
426 $items = $rss->items;
434 if (is_array($items)) {
435 foreach ($items as $item) {
437 if ($rss->_format ==
'rss') {
438 if (!empty($conf->global->EXTERNALRSS_USE_SIMPLEXML)) {
441 $itemDescription =
sanitizeVal((
string) $item->description);
442 $itemPubDate =
sanitizeVal((
string) $item->pubDate);
448 $itemDescription =
sanitizeVal((
string) $item[
'description']);
449 $itemPubDate =
sanitizeVal((
string) $item[
'pubdate']);
451 $itemAuthor =
sanitizeVal((
string) ($item[
'author'] ??
''));
455 $itemCategory = array();
456 if (!empty($item->category) && is_array($item->category)) {
457 foreach ($item->category as $cat) {
458 $itemCategory[] = (string) $cat;
461 } elseif ($rss->_format ==
'atom') {
462 if (!empty($conf->global->EXTERNALRSS_USE_SIMPLEXML)) {
463 $itemLink = (isset($item[
'link']) ?
sanitizeVal((
string) $item[
'link']) :
'');
466 $itemPubDate =
sanitizeVal((
string) $item[
'created']);
468 $itemAuthor =
sanitizeVal((
string) ($item[
'author'] ? $item[
'author'] : $item[
'author_name']));
470 $itemLink = (isset($item[
'link']) ?
sanitizeVal((
string) $item[
'link']) :
'');
473 $itemPubDate =
sanitizeVal((
string) $item[
'created']);
475 $itemAuthor =
sanitizeVal((
string) ($item[
'author'] ? $item[
'author'] : $item[
'author_name']));
477 $itemCategory = array();
479 $itemCategory = array();
482 $itemDescription =
'';
486 print
'ErrorBadFeedFormat';
490 $this->_rssarray[$i] = array(
493 'description'=>$itemDescription,
494 'pubDate'=>$itemPubDate,
495 'category'=>$itemCategory,
497 'author'=>$itemAuthor
511 $this->error =
'ErrorFailedToLoadRSSFile';
530 $el = $element = strtolower($element);
531 $attrs = array_change_key_case($attrs, CASE_LOWER);
535 if (strpos($element,
':')) {
536 list($ns, $el) = explode(
':', $element, 2);
538 if ($ns and $ns !=
'rdf') {
539 $this->current_namespace = $ns;
543 if (empty($this->_format)) {
545 $this->_format =
'rss';
546 $this->feed_version =
'1.0';
547 } elseif ($el ==
'rss') {
548 $this->_format =
'rss';
549 $this->feed_version = $attrs[
'version'];
550 } elseif ($el ==
'feed') {
551 $this->_format =
'atom';
552 $this->feed_version = $attrs[
'version'];
553 $this->inchannel =
true;
558 if ($el ==
'channel') {
559 $this->inchannel =
true;
560 } elseif ($el ==
'item' || $el ==
'entry') {
561 $this->initem =
true;
562 if (isset($attrs[
'rdf:about'])) {
563 $this->current_item[
'about'] = $attrs[
'rdf:about'];
565 } elseif ($this->_format ==
'rss' && $this->current_namespace ==
'' && $el ==
'textinput') {
568 $this->intextinput =
true;
569 } elseif ($this->_format ==
'rss' && $this->current_namespace ==
'' && $el ==
'image') {
570 $this->inimage =
true;
571 } elseif ($this->_format ==
'atom' && in_array($el, $this->_CONTENT_CONSTRUCTS)) {
574 if ($el ==
'content') {
575 $el =
'atom_content';
578 $this->incontent = $el;
579 } elseif ($this->_format ==
'atom' && $this->incontent) {
582 $attrs_str = join(
' ', array_map(
'map_attrs', array_keys($attrs), array_values($attrs)));
586 array_unshift($this->stack, $el);
587 } elseif ($this->_format ==
'atom' && $el ==
'link') {
591 if (isset($attrs[
'rel']) && $attrs[
'rel'] ==
'alternate') {
593 } elseif (!isset($attrs[
'rel'])) {
596 $link_el =
'link_'.$attrs[
'rel'];
599 $this->
append($link_el, $attrs[
'href']);
602 array_unshift($this->stack, $el);
637 $el = strtolower($el);
639 if ($el ==
'item' or $el ==
'entry') {
640 $this->items[] = $this->current_item;
641 $this->current_item = array();
642 $this->initem =
false;
643 } elseif ($this->_format ==
'rss' and $this->current_namespace ==
'' and $el ==
'textinput') {
644 $this->intextinput =
false;
645 } elseif ($this->_format ==
'rss' and $this->current_namespace ==
'' and $el ==
'image') {
646 $this->inimage =
false;
647 } elseif ($this->_format ==
'atom' and in_array($el, $this->_CONTENT_CONSTRUCTS)) {
648 $this->incontent =
false;
649 } elseif ($el ==
'channel' or $el ==
'feed') {
650 $this->inchannel =
false;
651 } elseif ($this->_format ==
'atom' and $this->incontent) {
654 if ($this->stack[0] == $el) {
660 array_shift($this->stack);
662 array_shift($this->stack);
665 $this->current_namespace =
false;
714 if (!empty($this->current_namespace)) {
715 if (!empty($this->initem)) {
716 $this->
concat($this->current_item[$this->current_namespace][$el], $text);
717 } elseif (!empty($this->inchannel)) {
718 $this->
concat($this->channel[$this->current_namespace][$el], $text);
719 } elseif (!empty($this->intextinput)) {
720 $this->
concat($this->textinput[$this->current_namespace][$el], $text);
721 } elseif (!empty($this->inimage)) {
722 $this->
concat($this->image[$this->current_namespace][$el], $text);
725 if (!empty($this->initem)) {
726 $this->
concat($this->current_item[$el], $text);
727 } elseif (!empty($this->intextinput)) {
728 $this->
concat($this->textinput[$el], $text);
729 } elseif (!empty($this->inimage)) {
730 $this->
concat($this->image[$el], $text);
731 } elseif (!empty($this->inchannel)) {
732 $this->
concat($this->channel[$el], $text);