39 private $_format =
'';
44 private $_lastbuilddate;
48 private $_description;
49 private $_lastfetchdate;
50 private $_rssarray = array();
52 private $current_namespace;
61 public $stack = array();
62 private $_CONTENT_CONSTRUCTS = array(
'content',
'summary',
'info',
'title',
'tagline',
'copyright');
82 return $this->_format;
92 return $this->_urlRSS;
101 return $this->_language;
110 return $this->_generator;
119 return $this->_copyright;
128 return $this->_lastbuilddate;
137 return $this->_imageurl;
155 return $this->_title;
164 return $this->_description;
173 return $this->_lastfetchdate;
182 return $this->_rssarray;
195 public function parser($urlRSS, $maxNb = 0, $cachedelay = 60, $cachedir =
'')
199 include_once DOL_DOCUMENT_ROOT.
'/core/lib/files.lib.php';
200 include_once DOL_DOCUMENT_ROOT.
'/core/lib/geturl.lib.php';
207 $this->error =
"ErrorBadUrl";
211 $this->_urlRSS = $urlRSS;
212 $newpathofdestfile = $cachedir.
'/'.
dol_hash($this->_urlRSS, 3);
220 if ($cachedelay > 0 && $cachedir) {
222 if ($filedate >= ($nowgmt - $cachedelay)) {
226 $this->_lastfetchdate = $filedate;
228 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.");
233 if ($foundintocache) {
234 $str = file_get_contents($newpathofdestfile);
237 $result =
getURLContent($this->_urlRSS,
'GET',
'', 1, array(), array(
'http',
'https'), 0);
239 if (!empty($result[
'content'])) {
240 $str = $result[
'content'];
241 } elseif (!empty($result[
'curl_error_msg'])) {
242 $this->error =
'Error retrieving URL '.$this->_urlRSS.
' - '.$result[
'curl_error_msg'];
246 $this->error =
'Error retrieving URL '.$this->_urlRSS.
' - '.$e->getMessage();
251 if ($str !==
false) {
253 if (!empty($conf->global->EXTERNALRSS_USE_SIMPLEXML)) {
255 libxml_use_internal_errors(
false);
256 $rss = simplexml_load_string($str,
"SimpleXMLElement", LIBXML_NOCDATA|LIBXML_NOCDATA);
258 if (!function_exists(
'xml_parser_create')) {
259 $this->error =
'Function xml_parser_create are not supported by your PHP';
264 $xmlparser = xml_parser_create(
null);
266 if (!is_resource($xmlparser) && !is_object($xmlparser)) {
267 $this->error =
"ErrorFailedToCreateParser";
271 xml_set_object($xmlparser, $this);
272 xml_set_element_handler($xmlparser,
'feed_start_element',
'feed_end_element');
273 xml_set_character_data_handler($xmlparser,
'feed_cdata');
275 $status = xml_parse($xmlparser, $str,
false);
277 xml_parser_free($xmlparser);
289 if (empty($foundintocache) && $cachedir) {
290 dol_syslog(get_class($this).
"::parser cache file ".$newpathofdestfile.
" is saved onto disk.");
294 $fp = fopen($newpathofdestfile,
'w');
298 if (!empty($conf->global->MAIN_UMASK)) {
299 $newmask = $conf->global->MAIN_UMASK;
301 @chmod($newpathofdestfile, octdec($newmask));
303 $this->_lastfetchdate = $nowgmt;
305 print
'Error, failed to open file '.$newpathofdestfile.
' for write';
311 if (empty($rss->_format)) {
312 $rss->_format =
'rss';
313 if (empty($rss->channel)) {
314 $rss->_format =
'atom';
321 if ($rss->_format ==
'rss') {
323 if (!empty($conf->global->EXTERNALRSS_USE_SIMPLEXML)) {
324 if (!empty($rss->channel->language)) {
325 $this->_language = (string) $rss->channel->language;
327 if (!empty($rss->channel->generator)) {
328 $this->_generator = (string) $rss->channel->generator;
330 if (!empty($rss->channel->copyright)) {
331 $this->_copyright = (string) $rss->channel->copyright;
333 if (!empty($rss->channel->lastbuilddate)) {
334 $this->_lastbuilddate = (string) $rss->channel->lastbuilddate;
336 if (!empty($rss->channel->image->url[0])) {
337 $this->_imageurl = (string) $rss->channel->image->url[0];
339 if (!empty($rss->channel->link)) {
340 $this->_link = (string) $rss->channel->link;
342 if (!empty($rss->channel->title)) {
343 $this->_title = (string) $rss->channel->title;
345 if (!empty($rss->channel->description)) {
346 $this->_description = (string) $rss->channel->description;
350 if (!empty($rss->channel[
'language'])) {
351 $this->_language = (string) $rss->channel[
'language'];
353 if (!empty($rss->channel[
'generator'])) {
354 $this->_generator = (string) $rss->channel[
'generator'];
356 if (!empty($rss->channel[
'copyright'])) {
357 $this->_copyright = (string) $rss->channel[
'copyright'];
359 if (!empty($rss->channel[
'lastbuilddate'])) {
360 $this->_lastbuilddate = (string) $rss->channel[
'lastbuilddate'];
362 if (!empty($rss->image[
'url'])) {
363 $this->_imageurl = (string) $rss->image[
'url'];
365 if (!empty($rss->channel[
'link'])) {
366 $this->_link = (string) $rss->channel[
'link'];
368 if (!empty($rss->channel[
'title'])) {
369 $this->_title = (string) $rss->channel[
'title'];
371 if (!empty($rss->channel[
'description'])) {
372 $this->_description = (string) $rss->channel[
'description'];
376 if (!empty($conf->global->EXTERNALRSS_USE_SIMPLEXML)) {
377 $items = $rss->channel->item;
379 $items = $rss->items;
382 } elseif ($rss->_format ==
'atom') {
384 if (!empty($conf->global->EXTERNALRSS_USE_SIMPLEXML)) {
385 if (!empty($rss->generator)) {
386 $this->_generator = (string) $rss->generator;
388 if (!empty($rss->lastbuilddate)) {
389 $this->_lastbuilddate = (string) $rss->modified;
391 if (!empty($rss->link->href)) {
392 $this->_link = (string) $rss->link->href;
394 if (!empty($rss->title)) {
395 $this->_title = (string) $rss->title;
397 if (!empty($rss->description)) {
398 $this->_description = (string) $rss->description;
402 if (!empty($rss->channel[
'generator'])) {
403 $this->_generator = (string) $rss->channel[
'generator'];
406 if (!empty($rss->channel[
'modified'])) {
407 $this->_lastbuilddate = (string) $rss->channel[
'modified'];
410 if (!empty($rss->channel[
'link'])) {
411 $this->_link = (string) $rss->channel[
'link'];
413 if (!empty($rss->channel[
'title'])) {
414 $this->_title = (string) $rss->channel[
'title'];
418 if (!empty($rss->channel)) {
422 if (!empty($conf->global->EXTERNALRSS_USE_SIMPLEXML)) {
424 $items = $tmprss[
'entry'];
427 $items = $rss->items;
435 if (is_array($items)) {
436 foreach ($items as $item) {
438 if ($rss->_format ==
'rss') {
439 if (!empty($conf->global->EXTERNALRSS_USE_SIMPLEXML)) {
440 $itemLink = (string) $item->link;
441 $itemTitle = (
string) $item->title;
442 $itemDescription = (string) $item->description;
443 $itemPubDate = (
string) $item->pubDate;
447 $itemLink = (string) $item[
'link'];
448 $itemTitle = (string) $item[
'title'];
449 $itemDescription = (string) $item[
'description'];
450 $itemPubDate = (string) $item[
'pubdate'];
451 $itemId = (string) $item[
'guid'];
452 $itemAuthor = (string) $item[
'author'];
456 $itemCategory = array();
457 if (!empty($item->category) && is_array($item->category)) {
458 foreach ($item->category as $cat) {
459 $itemCategory[] = (string) $cat;
462 } elseif ($rss->_format ==
'atom') {
463 if (!empty($conf->global->EXTERNALRSS_USE_SIMPLEXML)) {
464 $itemLink = (isset($item[
'link']) ? (string) $item[
'link'] :
'');
465 $itemTitle = (string) $item[
'title'];
467 $itemPubDate = (string) $item[
'created'];
468 $itemId = (string) $item[
'id'];
469 $itemAuthor = (string) ($item[
'author'] ? $item[
'author'] : $item[
'author_name']);
471 $itemLink = (isset($item[
'link']) ? (string) $item[
'link'] :
'');
472 $itemTitle = (string) $item[
'title'];
474 $itemPubDate = (string) $item[
'created'];
475 $itemId = (string) $item[
'id'];
476 $itemAuthor = (string) ($item[
'author'] ? $item[
'author'] : $item[
'author_name']);
478 $itemCategory = array();
480 $itemCategory = array();
483 $itemDescription =
'';
487 print
'ErrorBadFeedFormat';
491 $this->_rssarray[$i] = array(
494 'description'=>$itemDescription,
495 'pubDate'=>$itemPubDate,
496 'category'=>$itemCategory,
498 'author'=>$itemAuthor
512 $this->error =
'ErrorFailedToLoadRSSFile';
531 $el = $element = strtolower($element);
532 $attrs = array_change_key_case($attrs, CASE_LOWER);
536 if (strpos($element,
':')) {
537 list($ns, $el) = explode(
':', $element, 2);
539 if ($ns and $ns !=
'rdf') {
540 $this->current_namespace = $ns;
544 if (empty($this->_format)) {
546 $this->_format =
'rss';
547 $this->feed_version =
'1.0';
548 } elseif ($el ==
'rss') {
549 $this->_format =
'rss';
550 $this->feed_version = $attrs[
'version'];
551 } elseif ($el ==
'feed') {
552 $this->_format =
'atom';
553 $this->feed_version = $attrs[
'version'];
554 $this->inchannel =
true;
559 if ($el ==
'channel') {
560 $this->inchannel =
true;
561 } elseif ($el ==
'item' || $el ==
'entry') {
562 $this->initem =
true;
563 if (isset($attrs[
'rdf:about'])) {
564 $this->current_item[
'about'] = $attrs[
'rdf:about'];
566 } elseif ($this->_format ==
'rss' && $this->current_namespace ==
'' && $el ==
'textinput') {
569 $this->intextinput =
true;
570 } elseif ($this->_format ==
'rss' && $this->current_namespace ==
'' && $el ==
'image') {
571 $this->inimage =
true;
572 } elseif ($this->_format ==
'atom' && in_array($el, $this->_CONTENT_CONSTRUCTS)) {
575 if ($el ==
'content') {
576 $el =
'atom_content';
579 $this->incontent = $el;
580 } elseif ($this->_format ==
'atom' && $this->incontent) {
583 $attrs_str = join(
' ', array_map(
'map_attrs', array_keys($attrs), array_values($attrs)));
587 array_unshift($this->stack, $el);
588 } elseif ($this->_format ==
'atom' && $el ==
'link') {
592 if (isset($attrs[
'rel']) && $attrs[
'rel'] ==
'alternate') {
594 } elseif (!isset($attrs[
'rel'])) {
597 $link_el =
'link_'.$attrs[
'rel'];
600 $this->
append($link_el, $attrs[
'href']);
603 array_unshift($this->stack, $el);
619 if ($this->_format ==
'atom' and $this->incontent) {
622 $current_el = join(
'_', array_reverse($this->stack));
623 $this->
append($current_el, $text);
638 $el = strtolower($el);
640 if ($el ==
'item' or $el ==
'entry') {
641 $this->items[] = $this->current_item;
642 $this->current_item = array();
643 $this->initem =
false;
644 } elseif ($this->_format ==
'rss' and $this->current_namespace ==
'' and $el ==
'textinput') {
645 $this->intextinput =
false;
646 } elseif ($this->_format ==
'rss' and $this->current_namespace ==
'' and $el ==
'image') {
647 $this->inimage =
false;
648 } elseif ($this->_format ==
'atom' and in_array($el, $this->_CONTENT_CONSTRUCTS)) {
649 $this->incontent =
false;
650 } elseif ($el ==
'channel' or $el ==
'feed') {
651 $this->inchannel =
false;
652 } elseif ($this->_format ==
'atom' and $this->incontent) {
655 if ($this->stack[0] == $el) {
661 array_shift($this->stack);
663 array_shift($this->stack);
666 $this->current_namespace =
false;
677 public function concat(&$str1, $str2 =
"")
695 if (!empty($this->initem)) {
696 $this->
concat($this->current_item[$this->incontent], $text);
697 } elseif (!empty($this->inchannel)) {
698 $this->
concat($this->channel[$this->incontent], $text);
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);
748 if (isset($item[
'summary'])) {
749 $result = $item[
'summary'];
750 } elseif (isset($item[
'atom_content'])) {
751 $result = $item[
'atom_content'];
756 $result = strip_tags($result,
"<br><p><ul><ol><li>");
758 $result = str_replace(
"\n",
"", $result);
760 if (strlen($result) > $maxlength) {
761 $result = substr($result, 0, $maxlength);
776 if (isset($feed[
'icon'])) {
777 return $feed[
'logo'];
780 if (isset($feed[
'icon'])) {
781 return $feed[
'logo'];
784 if (isset($feed[
'webfeeds:logo'])) {
785 return $feed[
'webfeeds:logo'];
788 if (isset($feed[
'webfeeds:icon'])) {
789 return $feed[
'webfeeds:icon'];
792 if (isset($feed[
'webfeeds:wordmark'])) {
793 return $feed[
'webfeeds:wordmark'];
812 foreach ($xml->children() as $key => $value) {
816 foreach ($value->attributes() as $ak => $av) {
817 $child[$ak] = (string) $av;
821 if ($tab ===
false && in_array($key, array_keys($array))) {
825 $array[$key][] = $tmp;
826 $array[$key][] = $child;
828 } elseif ($tab ===
true) {
830 $array[$key][] = $child;
833 $array[$key] = $child;
841 return (
string) $xml;
dol_filemtime($pathoffile)
Return time of a file.
dol_is_url($url)
Return if path is an URL.
dol_is_dir($folder)
Test if filename is a directory.
dol_now($mode='auto')
Return date for now.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.
dol_mkdir($dir, $dataroot='', $newmask='')
Creation of a directory (this can create recursive subdir)
getURLContent($url, $postorget='GET', $param='', $followlocation=1, $addheaders=array(), $allowedschemes=array('http', 'https'), $localurl=0, $ssl_verifypeer=-1)
Function to get a content from an URL (use proxy if proxy defined).
dol_hash($chain, $type='0')
Returns a hash (non reversible encryption) of a string.
$conf db
API class for accounts.