rssparser.class.php 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777
  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 <http://www.gnu.org/licenses/>.
  16. */
  17. /**
  18. * \file htdocs/core/class/rssparser.class.php
  19. * \ingroup core
  20. * \brief File of class to parse RSS feeds
  21. */
  22. /**
  23. * Class to parse RSS files
  24. */
  25. class RssParser
  26. {
  27. var $db;
  28. var $error;
  29. private $_format='';
  30. private $_urlRSS;
  31. private $_language;
  32. private $_generator;
  33. private $_copyright;
  34. private $_lastbuilddate;
  35. private $_imageurl;
  36. private $_link;
  37. private $_title;
  38. private $_description;
  39. private $_lastfetchdate; // Last successful fetch
  40. private $_rssarray=array();
  41. // For parsing with xmlparser
  42. var $stack = array(); // parser stack
  43. var $_CONTENT_CONSTRUCTS = array('content', 'summary', 'info', 'title', 'tagline', 'copyright');
  44. /**
  45. * Constructor
  46. *
  47. * @param DoliDB $db Database handler
  48. */
  49. public function __construct($db)
  50. {
  51. $this->db=$db;
  52. }
  53. /**
  54. * getFormat
  55. *
  56. * @return string
  57. */
  58. public function getFormat()
  59. {
  60. return $this->_format;
  61. }
  62. /**
  63. * getUrlRss
  64. *
  65. * @return string
  66. */
  67. public function getUrlRss()
  68. {
  69. return $this->_urlRSS;
  70. }
  71. /**
  72. * getLanguage
  73. *
  74. * @return string
  75. */
  76. public function getLanguage()
  77. {
  78. return $this->_language;
  79. }
  80. /**
  81. * getGenerator
  82. *
  83. * @return string
  84. */
  85. public function getGenerator()
  86. {
  87. return $this->_generator;
  88. }
  89. /**
  90. * getCopyright
  91. *
  92. * @return string
  93. */
  94. public function getCopyright()
  95. {
  96. return $this->_copyright;
  97. }
  98. /**
  99. * getLastBuildDate
  100. *
  101. * @return string
  102. */
  103. public function getLastBuildDate()
  104. {
  105. return $this->_lastbuilddate;
  106. }
  107. /**
  108. * getImageUrl
  109. *
  110. * @return string
  111. */
  112. public function getImageUrl()
  113. {
  114. return $this->_imageurl;
  115. }
  116. /**
  117. * getLink
  118. *
  119. * @return string
  120. */
  121. public function getLink()
  122. {
  123. return $this->_link;
  124. }
  125. /**
  126. * getTitle
  127. *
  128. * @return string
  129. */
  130. public function getTitle()
  131. {
  132. return $this->_title;
  133. }
  134. /**
  135. * getDescription
  136. *
  137. * @return string
  138. */
  139. public function getDescription()
  140. {
  141. return $this->_description;
  142. }
  143. /**
  144. * getLastFetchDate
  145. *
  146. * @return string
  147. */
  148. public function getLastFetchDate()
  149. {
  150. return $this->_lastfetchdate;
  151. }
  152. /**
  153. * getItems
  154. *
  155. * @return string
  156. */
  157. public function getItems()
  158. {
  159. return $this->_rssarray;
  160. }
  161. /**
  162. * Parse rss URL
  163. *
  164. * @param string $urlRSS Url to parse
  165. * @param int $maxNb Max nb of records to get (0 for no limit)
  166. * @param int $cachedelay 0=No cache, nb of seconds we accept cache files (cachedir must also be defined)
  167. * @param string $cachedir Directory where to save cache file
  168. * @return int <0 if KO, >0 if OK
  169. */
  170. public function parser($urlRSS, $maxNb=0, $cachedelay=60, $cachedir='')
  171. {
  172. global $conf;
  173. include_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
  174. $rss='';
  175. $str=''; // This will contain content of feed
  176. // Check parameters
  177. if (! dol_is_url($urlRSS))
  178. {
  179. $this->error="ErrorBadUrl";
  180. return -1;
  181. }
  182. $this->_urlRSS = $urlRSS;
  183. $newpathofdestfile=$cachedir.'/'.dol_hash($this->_urlRSS);
  184. $newmask='0644';
  185. //dol_syslog("RssPArser::parser parse url=".$urlRSS." => cache file=".$newpathofdestfile);
  186. $nowgmt = dol_now();
  187. // Search into cache
  188. $foundintocache=0;
  189. if ($cachedelay > 0 && $cachedir)
  190. {
  191. $filedate=dol_filemtime($newpathofdestfile);
  192. if ($filedate >= ($nowgmt - $cachedelay))
  193. {
  194. //dol_syslog("RssParser::parser cache file ".$newpathofdestfile." is not older than now - cachedelay (".$nowgmt." - ".$cachedelay.") so we use it.");
  195. $foundintocache=1;
  196. $this->_lastfetchdate=$filedate;
  197. }
  198. else
  199. {
  200. 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.");
  201. }
  202. }
  203. // Load file into $str
  204. if ($foundintocache) // Cache file found and is not too old
  205. {
  206. $str = file_get_contents($newpathofdestfile);
  207. }
  208. else
  209. {
  210. try {
  211. ini_set("user_agent","Dolibarr ERP-CRM RSS reader");
  212. ini_set("max_execution_time", $conf->global->MAIN_USE_RESPONSE_TIMEOUT);
  213. ini_set("default_socket_timeout", $conf->global->MAIN_USE_RESPONSE_TIMEOUT);
  214. $opts = array('http'=>array('method'=>"GET"));
  215. if (! empty($conf->global->MAIN_USE_CONNECT_TIMEOUT)) $opts['http']['timeout']=$conf->global->MAIN_USE_CONNECT_TIMEOUT;
  216. if (! empty($conf->global->MAIN_PROXY_USE)) $opts['http']['proxy']='tcp://'.$conf->global->MAIN_PROXY_HOST.':'.$conf->global->MAIN_PROXY_PORT;
  217. //var_dump($opts);exit;
  218. $context = stream_context_create($opts);
  219. $str = file_get_contents($this->_urlRSS, false, $context);
  220. }
  221. catch (Exception $e) {
  222. print 'Error retrieving URL '.$this->urlRSS.' - '.$e->getMessage();
  223. }
  224. }
  225. if ($str !== false)
  226. {
  227. // Convert $str into xml
  228. if (! empty($conf->global->EXTERNALRSS_USE_SIMPLEXML))
  229. {
  230. //print 'xx'.LIBXML_NOCDATA;
  231. libxml_use_internal_errors(false);
  232. $rss = simplexml_load_string($str, "SimpleXMLElement", LIBXML_NOCDATA);
  233. }
  234. else
  235. {
  236. $xmlparser=xml_parser_create('');
  237. if (!is_resource($xmlparser)) {
  238. $this->error="ErrorFailedToCreateParser"; return -1;
  239. }
  240. xml_set_object($xmlparser, $this);
  241. xml_set_element_handler($xmlparser, 'feed_start_element', 'feed_end_element');
  242. xml_set_character_data_handler($xmlparser, 'feed_cdata');
  243. $status = xml_parse($xmlparser, $str);
  244. xml_parser_free($xmlparser);
  245. $rss=$this;
  246. //var_dump($rss->_format);exit;
  247. }
  248. }
  249. // If $rss loaded
  250. if ($rss)
  251. {
  252. // Save file into cache
  253. if (empty($foundintocache) && $cachedir)
  254. {
  255. dol_syslog(get_class($this)."::parser cache file ".$newpathofdestfile." is saved onto disk.");
  256. if (! dol_is_dir($cachedir)) dol_mkdir($cachedir);
  257. $fp = fopen($newpathofdestfile, 'w');
  258. fwrite($fp, $str);
  259. fclose($fp);
  260. if (! empty($conf->global->MAIN_UMASK)) $newmask=$conf->global->MAIN_UMASK;
  261. @chmod($newpathofdestfile, octdec($newmask));
  262. $this->_lastfetchdate=$nowgmt;
  263. }
  264. unset($str); // Free memory
  265. if (empty($rss->_format)) // If format not detected automatically
  266. {
  267. $rss->_format='rss';
  268. if (empty($rss->channel)) $rss->_format='atom';
  269. }
  270. $items=array();
  271. // Save description entries
  272. if ($rss->_format == 'rss')
  273. {
  274. //var_dump($rss);
  275. if (! empty($conf->global->EXTERNALRSS_USE_SIMPLEXML))
  276. {
  277. if (!empty($rss->channel->language)) $this->_language = (string) $rss->channel->language;
  278. if (!empty($rss->channel->generator)) $this->_generator = (string) $rss->channel->generator;
  279. if (!empty($rss->channel->copyright)) $this->_copyright = (string) $rss->channel->copyright;
  280. if (!empty($rss->channel->lastbuilddate)) $this->_lastbuilddate = (string) $rss->channel->lastbuilddate;
  281. if (!empty($rss->channel->image->url[0])) $this->_imageurl = (string) $rss->channel->image->url[0];
  282. if (!empty($rss->channel->link)) $this->_link = (string) $rss->channel->link;
  283. if (!empty($rss->channel->title)) $this->_title = (string) $rss->channel->title;
  284. if (!empty($rss->channel->description)) $this->_description = (string) $rss->channel->description;
  285. }
  286. else
  287. {
  288. //var_dump($rss->channel);
  289. if (!empty($rss->channel['language'])) $this->_language = (string) $rss->channel['language'];
  290. if (!empty($rss->channel['generator'])) $this->_generator = (string) $rss->channel['generator'];
  291. if (!empty($rss->channel['copyright'])) $this->_copyright = (string) $rss->channel['copyright'];
  292. if (!empty($rss->channel['lastbuilddate'])) $this->_lastbuilddate = (string) $rss->channel['lastbuilddate'];
  293. if (!empty($rss->image['url'])) $this->_imageurl = (string) $rss->image['url'];
  294. if (!empty($rss->channel['link'])) $this->_link = (string) $rss->channel['link'];
  295. if (!empty($rss->channel['title'])) $this->_title = (string) $rss->channel['title'];
  296. if (!empty($rss->channel['description'])) $this->_description = (string) $rss->channel['description'];
  297. }
  298. if (! empty($conf->global->EXTERNALRSS_USE_SIMPLEXML)) $items=$rss->channel->item; // With simplexml
  299. else $items=$rss->items; // With xmlparse
  300. //var_dump($items);exit;
  301. }
  302. else if ($rss->_format == 'atom')
  303. {
  304. //var_dump($rss);
  305. if (! empty($conf->global->EXTERNALRSS_USE_SIMPLEXML))
  306. {
  307. if (!empty($rss->generator)) $this->_generator = (string) $rss->generator;
  308. if (!empty($rss->lastbuilddate)) $this->_lastbuilddate = (string) $rss->modified;
  309. if (!empty($rss->link->href)) $this->_link = (string) $rss->link->href;
  310. if (!empty($rss->title)) $this->_title = (string) $rss->title;
  311. if (!empty($rss->description)) $this->_description = (string) $rss->description;
  312. }
  313. else
  314. {
  315. //if (!empty($rss->channel['rss_language'])) $this->_language = (string) $rss->channel['rss_language'];
  316. if (!empty($rss->channel['generator'])) $this->_generator = (string) $rss->channel['generator'];
  317. //if (!empty($rss->channel['rss_copyright'])) $this->_copyright = (string) $rss->channel['rss_copyright'];
  318. if (!empty($rss->channel['modified'])) $this->_lastbuilddate = (string) $rss->channel['modified'];
  319. //if (!empty($rss->image['rss_url'])) $this->_imageurl = (string) $rss->image['rss_url'];
  320. if (!empty($rss->channel['link'])) $this->_link = (string) $rss->channel['link'];
  321. if (!empty($rss->channel['title'])) $this->_title = (string) $rss->channel['title'];
  322. //if (!empty($rss->channel['rss_description'])) $this->_description = (string) $rss->channel['rss_description'];
  323. }
  324. if (! empty($conf->global->EXTERNALRSS_USE_SIMPLEXML)) {
  325. $tmprss=xml2php($rss); $items=$tmprss['entry'];
  326. } // With simplexml
  327. else $items=$rss->items; // With xmlparse
  328. //var_dump($items);exit;
  329. }
  330. $i = 0;
  331. // Loop on each record
  332. if (is_array($items))
  333. {
  334. foreach($items as $item)
  335. {
  336. //var_dump($item);exit;
  337. if ($rss->_format == 'rss')
  338. {
  339. if (! empty($conf->global->EXTERNALRSS_USE_SIMPLEXML))
  340. {
  341. $itemLink = (string) $item->link;
  342. $itemTitle = (string) $item->title;
  343. $itemDescription = (string) $item->description;
  344. $itemPubDate = (string) $item->pubDate;
  345. $itemId = '';
  346. $itemAuthor = '';
  347. }
  348. else
  349. {
  350. $itemLink = (string) $item['link'];
  351. $itemTitle = (string) $item['title'];
  352. $itemDescription = (string) $item['description'];
  353. $itemPubDate = (string) $item['pubdate'];
  354. $itemId = (string) $item['guid'];
  355. $itemAuthor = (string) $item['author'];
  356. }
  357. // Loop on each category
  358. $itemCategory=array();
  359. if (is_array($item->category))
  360. {
  361. foreach ($item->category as $cat)
  362. {
  363. $itemCategory[] = (string) $cat;
  364. }
  365. }
  366. }
  367. else if ($rss->_format == 'atom')
  368. {
  369. if (! empty($conf->global->EXTERNALRSS_USE_SIMPLEXML))
  370. {
  371. $itemLink = (string) $item['link']['href'];
  372. $itemTitle = (string) $item['title'];
  373. $itemDescription = (string) $item['summary'];
  374. $itemPubDate = (string) $item['created'];
  375. $itemId = (string) $item['id'];
  376. $itemAuthor = (string) ($item['author']?$item['author']:$item['author_name']);
  377. }
  378. else
  379. {
  380. $itemLink = (string) $item['link']['href'];
  381. $itemTitle = (string) $item['title'];
  382. $itemDescription = (string) $item['summary'];
  383. $itemPubDate = (string) $item['created'];
  384. $itemId = (string) $item['id'];
  385. $itemAuthor = (string) ($item['author']?$item['author']:$item['author_name']);
  386. }
  387. }
  388. else print 'ErrorBadFeedFormat';
  389. // Add record to result array
  390. $this->_rssarray[$i] = array(
  391. 'link'=>$itemLink,
  392. 'title'=>$itemTitle,
  393. 'description'=>$itemDescription,
  394. 'pubDate'=>$itemPubDate,
  395. 'category'=>$itemCategory,
  396. 'id'=>$itemId,
  397. 'author'=>$itemAuthor);
  398. //var_dump($this->_rssarray);
  399. $i++;
  400. if ($i > $maxNb) break; // We get all records we want
  401. }
  402. }
  403. return 1;
  404. }
  405. else
  406. {
  407. $this->error='ErrorFailedToLoadRSSFile';
  408. return -1;
  409. }
  410. }
  411. /**
  412. * Triggered when opened tag is found
  413. *
  414. * @param string $p Start
  415. * @param string $element Tag
  416. * @param array &$attrs Attributes of tags
  417. * @return void
  418. */
  419. function feed_start_element($p, $element, &$attrs)
  420. {
  421. $el = $element = strtolower($element);
  422. $attrs = array_change_key_case($attrs, CASE_LOWER);
  423. // check for a namespace, and split if found
  424. $ns = false;
  425. if (strpos($element, ':'))
  426. {
  427. list($ns, $el) = explode(':', $element, 2);
  428. }
  429. if ( $ns and $ns != 'rdf' )
  430. {
  431. $this->current_namespace = $ns;
  432. }
  433. // if feed type isn't set, then this is first element of feed identify feed from root element
  434. if (empty($this->_format))
  435. {
  436. if ( $el == 'rdf' ) {
  437. $this->_format = 'rss';
  438. $this->feed_version = '1.0';
  439. }
  440. elseif ( $el == 'rss' ) {
  441. $this->_format = 'rss';
  442. $this->feed_version = $attrs['version'];
  443. }
  444. elseif ( $el == 'feed' ) {
  445. $this->_format = 'atom';
  446. $this->feed_version = $attrs['version'];
  447. $this->inchannel = true;
  448. }
  449. return;
  450. }
  451. if ( $el == 'channel' )
  452. {
  453. $this->inchannel = true;
  454. }
  455. elseif ($el == 'item' or $el == 'entry' )
  456. {
  457. $this->initem = true;
  458. if ( isset($attrs['rdf:about']) ) {
  459. $this->current_item['about'] = $attrs['rdf:about'];
  460. }
  461. }
  462. // if we're in the default namespace of an RSS feed,
  463. // record textinput or image fields
  464. elseif (
  465. $this->_format == 'rss' and
  466. $this->current_namespace == '' and
  467. $el == 'textinput' )
  468. {
  469. $this->intextinput = true;
  470. }
  471. elseif (
  472. $this->_format == 'rss' and
  473. $this->current_namespace == '' and
  474. $el == 'image' )
  475. {
  476. $this->inimage = true;
  477. }
  478. // handle atom content constructs
  479. elseif ( $this->_format == 'atom' and in_array($el, $this->_CONTENT_CONSTRUCTS) )
  480. {
  481. // avoid clashing w/ RSS mod_content
  482. if ($el == 'content' ) {
  483. $el = 'atom_content';
  484. }
  485. $this->incontent = $el;
  486. }
  487. // if inside an Atom content construct (e.g. content or summary) field treat tags as text
  488. elseif ($this->_format == 'atom' and $this->incontent )
  489. {
  490. // if tags are inlined, then flatten
  491. $attrs_str = join(' ', array_map('map_attrs', array_keys($attrs), array_values($attrs)));
  492. $this->append_content("<$element $attrs_str>");
  493. array_unshift($this->stack, $el);
  494. }
  495. // Atom support many links per containging element.
  496. // Magpie treats link elements of type rel='alternate'
  497. // as being equivalent to RSS's simple link element.
  498. //
  499. elseif ($this->_format == 'atom' and $el == 'link' )
  500. {
  501. if ( isset($attrs['rel']) and $attrs['rel'] == 'alternate' )
  502. {
  503. $link_el = 'link';
  504. }
  505. else {
  506. $link_el = 'link_' . $attrs['rel'];
  507. }
  508. $this->append($link_el, $attrs['href']);
  509. }
  510. // set stack[0] to current element
  511. else {
  512. array_unshift($this->stack, $el);
  513. }
  514. }
  515. /**
  516. * Triggered when CDATA is found
  517. *
  518. * @param string $p P
  519. * @param string $text Tag
  520. * @return void
  521. */
  522. function feed_cdata($p, $text)
  523. {
  524. if ($this->_format == 'atom' and $this->incontent)
  525. {
  526. $this->append_content($text);
  527. }
  528. else
  529. {
  530. $current_el = join('_', array_reverse($this->stack));
  531. $this->append($current_el, $text);
  532. }
  533. }
  534. /**
  535. * Triggered when closed tag is found
  536. *
  537. * @param string $p P
  538. * @param string $el Tag
  539. * @return void
  540. */
  541. function feed_end_element($p, $el)
  542. {
  543. $el = strtolower($el);
  544. if ($el == 'item' or $el == 'entry')
  545. {
  546. $this->items[] = $this->current_item;
  547. $this->current_item = array();
  548. $this->initem = false;
  549. }
  550. elseif ($this->_format == 'rss' and $this->current_namespace == '' and $el == 'textinput' )
  551. {
  552. $this->intextinput = false;
  553. }
  554. elseif ($this->_format == 'rss' and $this->current_namespace == '' and $el == 'image' )
  555. {
  556. $this->inimage = false;
  557. }
  558. elseif ($this->_format == 'atom' and in_array($el, $this->_CONTENT_CONSTRUCTS) )
  559. {
  560. $this->incontent = false;
  561. }
  562. elseif ($el == 'channel' or $el == 'feed' )
  563. {
  564. $this->inchannel = false;
  565. }
  566. elseif ($this->_format == 'atom' and $this->incontent ) {
  567. // balance tags properly
  568. // note: i don't think this is actually neccessary
  569. if ( $this->stack[0] == $el )
  570. {
  571. $this->append_content("</$el>");
  572. }
  573. else {
  574. $this->append_content("<$el />");
  575. }
  576. array_shift($this->stack);
  577. }
  578. else {
  579. array_shift($this->stack);
  580. }
  581. $this->current_namespace = false;
  582. }
  583. /**
  584. * To concat 2 string with no warning if an operand is not defined
  585. *
  586. * @param string &$str1 Str1
  587. * @param string $str2 Str2
  588. * @return string String cancatenated
  589. */
  590. function concat(&$str1, $str2="")
  591. {
  592. if (!isset($str1) ) {
  593. $str1="";
  594. }
  595. $str1 .= $str2;
  596. }
  597. /**
  598. * Enter description here ...
  599. *
  600. * @param string $text Text
  601. * @return void
  602. */
  603. function append_content($text)
  604. {
  605. if ( $this->initem ) {
  606. $this->concat($this->current_item[ $this->incontent ], $text);
  607. }
  608. elseif ( $this->inchannel ) {
  609. $this->concat($this->channel[ $this->incontent ], $text);
  610. }
  611. }
  612. /**
  613. * smart append - field and namespace aware
  614. *
  615. * @param string $el El
  616. * @param string $text Text
  617. * @return void
  618. */
  619. function append($el, $text)
  620. {
  621. if (!$el) {
  622. return;
  623. }
  624. if ( $this->current_namespace )
  625. {
  626. if ( $this->initem ) {
  627. $this->concat($this->current_item[ $this->current_namespace ][ $el ], $text);
  628. }
  629. elseif ($this->inchannel) {
  630. $this->concat($this->channel[ $this->current_namespace][ $el ], $text);
  631. }
  632. elseif ($this->intextinput) {
  633. $this->concat($this->textinput[ $this->current_namespace][ $el ], $text);
  634. }
  635. elseif ($this->inimage) {
  636. $this->concat($this->image[ $this->current_namespace ][ $el ], $text);
  637. }
  638. }
  639. else {
  640. if ( $this->initem ) {
  641. $this->concat($this->current_item[ $el ], $text);
  642. }
  643. elseif ($this->intextinput) {
  644. $this->concat($this->textinput[ $el ], $text);
  645. }
  646. elseif ($this->inimage) {
  647. $this->concat($this->image[ $el ], $text);
  648. }
  649. elseif ($this->inchannel) {
  650. $this->concat($this->channel[ $el ], $text);
  651. }
  652. }
  653. }
  654. }
  655. /**
  656. * Function to convert an XML object into an array
  657. *
  658. * @param SimpleXMLElement $xml Xml
  659. * @return void
  660. */
  661. function xml2php($xml)
  662. {
  663. $fils = 0;
  664. $tab = false;
  665. $array = array();
  666. foreach($xml->children() as $key => $value)
  667. {
  668. $child = xml2php($value);
  669. //To deal with the attributes
  670. foreach($value->attributes() as $ak=>$av)
  671. {
  672. $child[$ak] = (string) $av;
  673. }
  674. //Let see if the new child is not in the array
  675. if($tab==false && in_array($key,array_keys($array)))
  676. {
  677. //If this element is already in the array we will create an indexed array
  678. $tmp = $array[$key];
  679. $array[$key] = NULL;
  680. $array[$key][] = $tmp;
  681. $array[$key][] = $child;
  682. $tab = true;
  683. }
  684. elseif($tab == true)
  685. {
  686. //Add an element in an existing array
  687. $array[$key][] = $child;
  688. }
  689. else
  690. {
  691. //Add a simple element
  692. $array[$key] = $child;
  693. }
  694. $fils++;
  695. }
  696. if($fils==0)
  697. {
  698. return (string) $xml;
  699. }
  700. return $array;
  701. }