dolibarr  19.0.0-dev
rssparser.class.php
Go to the documentation of this file.
1 <?php
2 /* Copyright (C) 2011-2012 Laurent Destailleur <eldy@users.sourceforge.net>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 3 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see <https://www.gnu.org/licenses/>.
16  */
17 
27 class RssParser
28 {
32  public $db;
33 
37  public $error = '';
38 
39  public $feed_version;
40 
41  private $_format = '';
42  private $_urlRSS;
43  private $_language;
44  private $_generator;
45  private $_copyright;
46  private $_lastbuilddate;
47  private $_imageurl;
48  private $_link;
49  private $_title;
50  private $_description;
51  private $_lastfetchdate; // Last successful fetch
52  private $_rssarray = array();
53 
54  private $current_namespace;
55 
56  private $initem;
57  private $intextinput;
58  private $incontent;
59  private $inimage;
60  private $inchannel;
61 
62  // For parsing with xmlparser
63  public $stack = array(); // parser stack
64  private $_CONTENT_CONSTRUCTS = array('content', 'summary', 'info', 'title', 'tagline', 'copyright');
65 
66 
72  public function __construct($db)
73  {
74  $this->db = $db;
75  }
76 
82  public function getFormat()
83  {
84  return $this->_format;
85  }
86 
92  public function getUrlRss()
93  {
94  return $this->_urlRSS;
95  }
101  public function getLanguage()
102  {
103  return $this->_language;
104  }
110  public function getGenerator()
111  {
112  return $this->_generator;
113  }
119  public function getCopyright()
120  {
121  return $this->_copyright;
122  }
128  public function getLastBuildDate()
129  {
130  return $this->_lastbuilddate;
131  }
137  public function getImageUrl()
138  {
139  return $this->_imageurl;
140  }
146  public function getLink()
147  {
148  return $this->_link;
149  }
155  public function getTitle()
156  {
157  return $this->_title;
158  }
164  public function getDescription()
165  {
166  return $this->_description;
167  }
173  public function getLastFetchDate()
174  {
175  return $this->_lastfetchdate;
176  }
182  public function getItems()
183  {
184  return $this->_rssarray;
185  }
186 
187 
197  public function parser($urlRSS, $maxNb = 0, $cachedelay = 60, $cachedir = '')
198  {
199  global $conf;
200 
201  include_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
202  include_once DOL_DOCUMENT_ROOT.'/core/lib/geturl.lib.php';
203 
204  $rss = '';
205  $str = ''; // This will contain content of feed
206 
207  // Check parameters
208  if (!dol_is_url($urlRSS)) {
209  $this->error = "ErrorBadUrl";
210  return -1;
211  }
212 
213  $this->_urlRSS = $urlRSS;
214  $newpathofdestfile = $cachedir.'/'.dol_hash($this->_urlRSS, 3); // Force md5 hash (does not contain special chars)
215  $newmask = '0644';
216 
217  //dol_syslog("RssPArser::parser parse url=".$urlRSS." => cache file=".$newpathofdestfile);
218  $nowgmt = dol_now();
219 
220  // Search into cache
221  $foundintocache = 0;
222  if ($cachedelay > 0 && $cachedir) {
223  $filedate = dol_filemtime($newpathofdestfile);
224  if ($filedate >= ($nowgmt - $cachedelay)) {
225  //dol_syslog("RssParser::parser cache file ".$newpathofdestfile." is not older than now - cachedelay (".$nowgmt." - ".$cachedelay.") so we use it.");
226  $foundintocache = 1;
227 
228  $this->_lastfetchdate = $filedate;
229  } else {
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.");
231  }
232  }
233 
234  // Load file into $str
235  if ($foundintocache) { // Cache file found and is not too old
236  $str = file_get_contents($newpathofdestfile);
237  } else {
238  try {
239  $result = getURLContent($this->_urlRSS, 'GET', '', 1, array(), array('http', 'https'), 0);
240 
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'];
245  return -1;
246  }
247  } catch (Exception $e) {
248  $this->error = 'Error retrieving URL '.$this->_urlRSS.' - '.$e->getMessage();
249  return -2;
250  }
251  }
252 
253  if ($str !== false) {
254  // Convert $str into xml
255  if (!empty($conf->global->EXTERNALRSS_USE_SIMPLEXML)) {
256  //print 'xx'.LIBXML_NOCDATA;
257  libxml_use_internal_errors(false);
258  $rss = simplexml_load_string($str, "SimpleXMLElement", LIBXML_NOCDATA|LIBXML_NOCDATA);
259  } else {
260  if (!function_exists('xml_parser_create')) {
261  $this->error = 'Function xml_parser_create are not supported by your PHP';
262  return -1;
263  }
264 
265  try {
266  $xmlparser = xml_parser_create(null);
267 
268  if (!is_resource($xmlparser) && !is_object($xmlparser)) {
269  $this->error = "ErrorFailedToCreateParser";
270  return -1;
271  }
272 
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');
276 
277  $status = xml_parse($xmlparser, $str, false);
278 
279  xml_parser_free($xmlparser);
280  $rss = $this;
281  //var_dump($status.' '.$rss->_format);exit;
282  } catch (Exception $e) {
283  $rss = null;
284  }
285  }
286  }
287 
288  // If $rss loaded
289  if ($rss) {
290  // Save file into cache
291  if (empty($foundintocache) && $cachedir) {
292  dol_syslog(get_class($this)."::parser cache file ".$newpathofdestfile." is saved onto disk.");
293  if (!dol_is_dir($cachedir)) {
294  dol_mkdir($cachedir);
295  }
296  $fp = fopen($newpathofdestfile, 'w');
297  if ($fp) {
298  fwrite($fp, $str);
299  fclose($fp);
300  dolChmod($newpathofdestfile);
301 
302  $this->_lastfetchdate = $nowgmt;
303  } else {
304  print 'Error, failed to open file '.$newpathofdestfile.' for write';
305  }
306  }
307 
308  unset($str); // Free memory
309 
310  if (empty($rss->_format)) { // If format not detected automatically
311  $rss->_format = 'rss';
312  if (empty($rss->channel)) {
313  $rss->_format = 'atom';
314  }
315  }
316 
317  $items = array();
318 
319  // Save description entries
320  if ($rss->_format == 'rss') {
321  //var_dump($rss);
322  if (!empty($conf->global->EXTERNALRSS_USE_SIMPLEXML)) {
323  if (!empty($rss->channel->language)) {
324  $this->_language = sanitizeVal((string) $rss->channel->language);
325  }
326  if (!empty($rss->channel->generator)) {
327  $this->_generator = sanitizeVal((string) $rss->channel->generator);
328  }
329  if (!empty($rss->channel->copyright)) {
330  $this->_copyright = sanitizeVal((string) $rss->channel->copyright);
331  }
332  if (!empty($rss->channel->lastbuilddate)) {
333  $this->_lastbuilddate = sanitizeVal((string) $rss->channel->lastbuilddate);
334  }
335  if (!empty($rss->channel->image->url[0])) {
336  $this->_imageurl = sanitizeVal((string) $rss->channel->image->url[0]);
337  }
338  if (!empty($rss->channel->link)) {
339  $this->_link = sanitizeVal((string) $rss->channel->link);
340  }
341  if (!empty($rss->channel->title)) {
342  $this->_title = sanitizeVal((string) $rss->channel->title);
343  }
344  if (!empty($rss->channel->description)) {
345  $this->_description = sanitizeVal((string) $rss->channel->description);
346  }
347  } else {
348  //var_dump($rss->channel);
349  if (!empty($rss->channel['language'])) {
350  $this->_language = sanitizeVal((string) $rss->channel['language']);
351  }
352  if (!empty($rss->channel['generator'])) {
353  $this->_generator = sanitizeVal((string) $rss->channel['generator']);
354  }
355  if (!empty($rss->channel['copyright'])) {
356  $this->_copyright = sanitizeVal((string) $rss->channel['copyright']);
357  }
358  if (!empty($rss->channel['lastbuilddate'])) {
359  $this->_lastbuilddate = sanitizeVal((string) $rss->channel['lastbuilddate']);
360  }
361  if (!empty($rss->image['url'])) {
362  $this->_imageurl = sanitizeVal((string) $rss->image['url']);
363  }
364  if (!empty($rss->channel['link'])) {
365  $this->_link = sanitizeVal((string) $rss->channel['link']);
366  }
367  if (!empty($rss->channel['title'])) {
368  $this->_title = sanitizeVal((string) $rss->channel['title']);
369  }
370  if (!empty($rss->channel['description'])) {
371  $this->_description = sanitizeVal((string) $rss->channel['description']);
372  }
373  }
374 
375  if (!empty($conf->global->EXTERNALRSS_USE_SIMPLEXML)) {
376  $items = $rss->channel->item; // With simplexml
377  } else {
378  $items = $rss->items; // With xmlparse
379  }
380  //var_dump($items);exit;
381  } elseif ($rss->_format == 'atom') {
382  //var_dump($rss);
383  if (!empty($conf->global->EXTERNALRSS_USE_SIMPLEXML)) {
384  if (!empty($rss->generator)) {
385  $this->_generator = sanitizeVal((string) $rss->generator);
386  }
387  if (!empty($rss->lastbuilddate)) {
388  $this->_lastbuilddate = sanitizeVal((string) $rss->modified);
389  }
390  if (!empty($rss->link->href)) {
391  $this->_link = sanitizeVal((string) $rss->link->href);
392  }
393  if (!empty($rss->title)) {
394  $this->_title = sanitizeVal((string) $rss->title);
395  }
396  if (!empty($rss->description)) {
397  $this->_description = sanitizeVal((string) $rss->description);
398  }
399  } else {
400  //if (!empty($rss->channel['rss_language'])) $this->_language = (string) $rss->channel['rss_language'];
401  if (!empty($rss->channel['generator'])) {
402  $this->_generator = sanitizeVal((string) $rss->channel['generator']);
403  }
404  //if (!empty($rss->channel['rss_copyright'])) $this->_copyright = (string) $rss->channel['rss_copyright'];
405  if (!empty($rss->channel['modified'])) {
406  $this->_lastbuilddate = sanitizeVal((string) $rss->channel['modified']);
407  }
408  //if (!empty($rss->image['rss_url'])) $this->_imageurl = (string) $rss->image['rss_url'];
409  if (!empty($rss->channel['link'])) {
410  $this->_link = sanitizeVal((string) $rss->channel['link']);
411  }
412  if (!empty($rss->channel['title'])) {
413  $this->_title = sanitizeVal((string) $rss->channel['title']);
414  }
415  //if (!empty($rss->channel['rss_description'])) $this->_description = (string) $rss->channel['rss_description'];
416 
417  if (!empty($rss->channel)) {
418  $this->_imageurl = sanitizeVal($this->getAtomImageUrl($rss->channel));
419  }
420  }
421  if (!empty($conf->global->EXTERNALRSS_USE_SIMPLEXML)) {
422  $tmprss = xml2php($rss);
423  $items = $tmprss['entry'];
424  } else {
425  // With simplexml
426  $items = $rss->items; // With xmlparse
427  }
428  //var_dump($items);exit;
429  }
430 
431  $i = 0;
432 
433  // Loop on each record
434  if (is_array($items)) {
435  foreach ($items as $item) {
436  //var_dump($item);exit;
437  if ($rss->_format == 'rss') {
438  if (!empty($conf->global->EXTERNALRSS_USE_SIMPLEXML)) {
439  $itemLink = sanitizeVal((string) $item->link);
440  $itemTitle = sanitizeVal((string) $item->title);
441  $itemDescription = sanitizeVal((string) $item->description);
442  $itemPubDate = sanitizeVal((string) $item->pubDate);
443  $itemId = '';
444  $itemAuthor = '';
445  } else {
446  $itemLink = sanitizeVal((string) $item['link']);
447  $itemTitle = sanitizeVal((string) $item['title']);
448  $itemDescription = sanitizeVal((string) $item['description']);
449  $itemPubDate = sanitizeVal((string) $item['pubdate']);
450  $itemId = sanitizeVal((string) $item['guid']);
451  $itemAuthor = sanitizeVal((string) ($item['author'] ?? ''));
452  }
453 
454  // Loop on each category
455  $itemCategory = array();
456  if (!empty($item->category) && is_array($item->category)) {
457  foreach ($item->category as $cat) {
458  $itemCategory[] = (string) $cat;
459  }
460  }
461  } elseif ($rss->_format == 'atom') {
462  if (!empty($conf->global->EXTERNALRSS_USE_SIMPLEXML)) {
463  $itemLink = (isset($item['link']) ? sanitizeVal((string) $item['link']) : '');
464  $itemTitle = sanitizeVal((string) $item['title']);
465  $itemDescription = sanitizeVal($this->getAtomItemDescription($item));
466  $itemPubDate = sanitizeVal((string) $item['created']);
467  $itemId = sanitizeVal((string) $item['id']);
468  $itemAuthor = sanitizeVal((string) ($item['author'] ? $item['author'] : $item['author_name']));
469  } else {
470  $itemLink = (isset($item['link']) ? sanitizeVal((string) $item['link']) : '');
471  $itemTitle = sanitizeVal((string) $item['title']);
472  $itemDescription = sanitizeVal($this->getAtomItemDescription($item));
473  $itemPubDate = sanitizeVal((string) $item['created']);
474  $itemId = sanitizeVal((string) $item['id']);
475  $itemAuthor = sanitizeVal((string) ($item['author'] ? $item['author'] : $item['author_name']));
476  }
477  $itemCategory = array();
478  } else {
479  $itemCategory = array();
480  $itemLink = '';
481  $itemTitle = '';
482  $itemDescription = '';
483  $itemPubDate = '';
484  $itemId = '';
485  $itemAuthor = '';
486  print 'ErrorBadFeedFormat';
487  }
488 
489  // Add record to result array
490  $this->_rssarray[$i] = array(
491  'link'=>$itemLink,
492  'title'=>$itemTitle,
493  'description'=>$itemDescription,
494  'pubDate'=>$itemPubDate,
495  'category'=>$itemCategory,
496  'id'=>$itemId,
497  'author'=>$itemAuthor
498  );
499  //var_dump($this->_rssarray);
500 
501  $i++;
502 
503  if ($i > $maxNb) {
504  break; // We get all records we want
505  }
506  }
507  }
508 
509  return 1;
510  } else {
511  $this->error = 'ErrorFailedToLoadRSSFile';
512  return -1;
513  }
514  }
515 
516 
517 
518  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
527  public function feed_start_element($p, $element, $attrs)
528  {
529  // phpcs:enable
530  $el = $element = strtolower($element);
531  $attrs = array_change_key_case($attrs, CASE_LOWER);
532 
533  // check for a namespace, and split if found
534  $ns = false;
535  if (strpos($element, ':')) {
536  list($ns, $el) = explode(':', $element, 2);
537  }
538  if ($ns and $ns != 'rdf') {
539  $this->current_namespace = $ns;
540  }
541 
542  // if feed type isn't set, then this is first element of feed identify feed from root element
543  if (empty($this->_format)) {
544  if ($el == 'rdf') {
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;
554  }
555  return;
556  }
557 
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'];
564  }
565  } elseif ($this->_format == 'rss' && $this->current_namespace == '' && $el == 'textinput') {
566  // if we're in the default namespace of an RSS feed,
567  // record textinput or image fields
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)) {
572  // handle atom content constructs
573  // avoid clashing w/ RSS mod_content
574  if ($el == 'content') {
575  $el = 'atom_content';
576  }
577 
578  $this->incontent = $el;
579  } elseif ($this->_format == 'atom' && $this->incontent) {
580  // if inside an Atom content construct (e.g. content or summary) field treat tags as text
581  // if tags are inlined, then flatten
582  $attrs_str = join(' ', array_map('map_attrs', array_keys($attrs), array_values($attrs)));
583 
584  $this->append_content("<$element $attrs_str>");
585 
586  array_unshift($this->stack, $el);
587  } elseif ($this->_format == 'atom' && $el == 'link') {
588  // Atom support many links per containging element.
589  // Magpie treats link elements of type rel='alternate'
590  // as being equivalent to RSS's simple link element.
591  if (isset($attrs['rel']) && $attrs['rel'] == 'alternate') {
592  $link_el = 'link';
593  } elseif (!isset($attrs['rel'])) {
594  $link_el = 'link';
595  } else {
596  $link_el = 'link_'.$attrs['rel'];
597  }
598 
599  $this->append($link_el, $attrs['href']);
600  } else {
601  // set stack[0] to current element
602  array_unshift($this->stack, $el);
603  }
604  }
605 
606 
607  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
615  public function feed_cdata($p, $text)
616  {
617  // phpcs:enable
618  if ($this->_format == 'atom' and $this->incontent) {
619  $this->append_content($text);
620  } else {
621  $current_el = join('_', array_reverse($this->stack));
622  $this->append($current_el, $text);
623  }
624  }
625 
626  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
634  public function feed_end_element($p, $el)
635  {
636  // phpcs:enable
637  $el = strtolower($el);
638 
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) {
652  // balance tags properly
653  // note: i don't think this is actually neccessary
654  if ($this->stack[0] == $el) {
655  $this->append_content("</$el>");
656  } else {
657  $this->append_content("<$el />");
658  }
659 
660  array_shift($this->stack);
661  } else {
662  array_shift($this->stack);
663  }
664 
665  $this->current_namespace = false;
666  }
667 
668 
676  public function concat(&$str1, $str2 = "")
677  {
678  if (!isset($str1)) {
679  $str1 = "";
680  }
681  $str1 .= $str2;
682  return $str1;
683  }
684 
685  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
692  public function append_content($text)
693  {
694  // phpcs:enable
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);
699  }
700  }
701 
709  public function append($el, $text)
710  {
711  if (!$el) {
712  return;
713  }
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);
723  }
724  } else {
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);
733  }
734  }
735  }
736 
744  private function getAtomItemDescription(array $item, $maxlength = 500)
745  {
746  $result = "";
747 
748  if (isset($item['summary'])) {
749  $result = $item['summary'];
750  } elseif (isset($item['atom_content'])) {
751  $result = $item['atom_content'];
752  }
753 
754  // remove all HTML elements that can possible break the maximum size of a tooltip,
755  // like headings, image, video etc. and allow only simple style elements
756  $result = strip_tags($result, "<br><p><ul><ol><li>");
757 
758  $result = str_replace("\n", "", $result);
759 
760  if (strlen($result) > $maxlength) {
761  $result = substr($result, 0, $maxlength);
762  $result .= "...";
763  }
764 
765  return $result;
766  }
767 
774  private function getAtomImageUrl(array $feed)
775  {
776  if (isset($feed['icon'])) {
777  return $feed['logo'];
778  }
779 
780  if (isset($feed['icon'])) {
781  return $feed['logo'];
782  }
783 
784  if (isset($feed['webfeeds:logo'])) {
785  return $feed['webfeeds:logo'];
786  }
787 
788  if (isset($feed['webfeeds:icon'])) {
789  return $feed['webfeeds:icon'];
790  }
791 
792  if (isset($feed['webfeeds:wordmark'])) {
793  return $feed['webfeeds:wordmark'];
794  }
795 
796  return "";
797  }
798 }
799 
800 
807 function xml2php($xml)
808 {
809  $fils = 0;
810  $tab = false;
811  $array = array();
812  foreach ($xml->children() as $key => $value) {
813  $child = xml2php($value);
814 
815  //To deal with the attributes
816  foreach ($value->attributes() as $ak => $av) {
817  $child[$ak] = (string) $av;
818  }
819 
820  //Let see if the new child is not in the array
821  if ($tab === false && in_array($key, array_keys($array))) {
822  //If this element is already in the array we will create an indexed array
823  $tmp = $array[$key];
824  $array[$key] = null;
825  $array[$key][] = $tmp;
826  $array[$key][] = $child;
827  $tab = true;
828  } elseif ($tab === true) {
829  //Add an element in an existing array
830  $array[$key][] = $child;
831  } else {
832  //Add a simple element
833  $array[$key] = $child;
834  }
835 
836  $fils++;
837  }
838 
839 
840  if ($fils == 0) {
841  return (string) $xml;
842  }
843 
844  return $array;
845 }
Class to parse RSS files.
feed_start_element($p, $element, $attrs)
Triggered when opened tag is found.
getAtomItemDescription(array $item, $maxlength=500)
Return a description/summary for one item from a ATOM feed.
concat(&$str1, $str2="")
To concat 2 strings with no warning if an operand is not defined.
getImageUrl()
getImageUrl
feed_end_element($p, $el)
Triggered when closed tag is found.
__construct($db)
Constructor.
getLanguage()
getLanguage
getTitle()
getTitle
getLastBuildDate()
getLastBuildDate
getItems()
getItems
getLink()
getLink
getGenerator()
getGenerator
getCopyright()
getCopyright
feed_cdata($p, $text)
Triggered when CDATA is found.
getLastFetchDate()
getLastFetchDate
getUrlRss()
getUrlRss
parser($urlRSS, $maxNb=0, $cachedelay=60, $cachedir='')
Parse rss URL.
append_content($text)
Enter description here ...
append($el, $text)
smart append - field and namespace aware
getDescription()
getDescription
getFormat()
getFormat
getAtomImageUrl(array $feed)
Return a URL to a image of the given ATOM feed.
dol_filemtime($pathoffile)
Return time of a file.
Definition: files.lib.php:599
dol_is_url($url)
Return if path is an URL.
Definition: files.lib.php:507
dol_is_dir($folder)
Test if filename is a directory.
Definition: files.lib.php:453
dolChmod($filepath, $newmask='')
Change mod of a file.
dol_now($mode='auto')
Return date for now.
sanitizeVal($out='', $check='alphanohtml', $filter=null, $options=null)
Return a sanitized or empty value after checking value against a rule.
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).
Definition: geturl.lib.php:41
xml2php($xml)
Function to convert an XML object into an array.
dol_hash($chain, $type='0')
Returns a hash (non reversible encryption) of a string.