Html.php 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679
  1. <?php
  2. /**
  3. * @file
  4. * TeamSpeak 3 PHP Framework
  5. *
  6. * This program is free software: you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation, either version 3 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  18. *
  19. * @package TeamSpeak3
  20. * @author Sven 'ScP' Paulsen
  21. * @copyright Copyright (c) Planet TeamSpeak. All rights reserved.
  22. */
  23. /**
  24. * @class TeamSpeak3_Viewer_Html
  25. * @brief Renders nodes used in HTML-based TeamSpeak 3 viewers.
  26. */
  27. class TeamSpeak3_Viewer_Html implements TeamSpeak3_Viewer_Interface
  28. {
  29. /**
  30. * A pre-defined pattern used to display a node in a TeamSpeak 3 viewer.
  31. *
  32. * @var string
  33. */
  34. protected $pattern = "<table id='%0' class='%1' summary='%2'><tr class='%3'><td class='%4'>%5</td><td class='%6' title='%7'>%8 %9</td><td class='%10'>%11%12</td></tr></table>\n";
  35. /**
  36. * The TeamSpeak3_Node_Abstract object which is currently processed.
  37. *
  38. * @var TeamSpeak3_Node_Abstract
  39. */
  40. protected $currObj = null;
  41. /**
  42. * An array filled with siblings for the TeamSpeak3_Node_Abstract object which is currently
  43. * processed.
  44. *
  45. * @var array
  46. */
  47. protected $currSib = null;
  48. /**
  49. * An internal counter indicating the number of fetched TeamSpeak3_Node_Abstract objects.
  50. *
  51. * @var integer
  52. */
  53. protected $currNum = 0;
  54. /**
  55. * The relative URI path where the images used by the viewer can be found.
  56. *
  57. * @var string
  58. */
  59. protected $iconpath = null;
  60. /**
  61. * The relative URI path where the country flag icons used by the viewer can be found.
  62. *
  63. * @var string
  64. */
  65. protected $flagpath = null;
  66. /**
  67. * The relative path of the file transter client script on the server.
  68. *
  69. * @var string
  70. */
  71. protected $ftclient = null;
  72. /**
  73. * Stores an array of local icon IDs.
  74. *
  75. * @var array
  76. */
  77. protected $cachedIcons = array(100, 200, 300, 400, 500, 600);
  78. /**
  79. * Stores an array of remote icon IDs.
  80. *
  81. * @var array
  82. */
  83. protected $remoteIcons = array();
  84. /**
  85. * The TeamSpeak3_Viewer_Html constructor.
  86. *
  87. * @param string $iconpath
  88. * @param string $flagpath
  89. * @param string $ftclient
  90. * @param string $pattern
  91. * @return void
  92. */
  93. public function __construct($iconpath = "images/viewer/", $flagpath = null, $ftclient = null, $pattern = null)
  94. {
  95. $this->iconpath = $iconpath;
  96. $this->flagpath = $flagpath;
  97. $this->ftclient = $ftclient;
  98. if($pattern)
  99. {
  100. $this->pattern = $pattern;
  101. }
  102. }
  103. /**
  104. * Returns the code needed to display a node in a TeamSpeak 3 viewer.
  105. *
  106. * @param TeamSpeak3_Node_Abstract $node
  107. * @param array $siblings
  108. * @return string
  109. */
  110. public function fetchObject(TeamSpeak3_Node_Abstract $node, array $siblings = array())
  111. {
  112. $this->currObj = $node;
  113. $this->currSib = $siblings;
  114. $args = array(
  115. $this->getContainerIdent(),
  116. $this->getContainerClass(),
  117. $this->getContainerSummary(),
  118. $this->getRowClass(),
  119. $this->getPrefixClass(),
  120. $this->getPrefix(),
  121. $this->getCorpusClass(),
  122. $this->getCorpusTitle(),
  123. $this->getCorpusIcon(),
  124. $this->getCorpusName(),
  125. $this->getSuffixClass(),
  126. $this->getSuffixIcon(),
  127. $this->getSuffixFlag(),
  128. );
  129. return TeamSpeak3_Helper_String::factory($this->pattern)->arg($args);
  130. }
  131. /**
  132. * Returns a unique identifier for the current node which can be used as a HTML id
  133. * property.
  134. *
  135. * @return string
  136. */
  137. protected function getContainerIdent()
  138. {
  139. return $this->currObj->getUniqueId();
  140. }
  141. /**
  142. * Returns a dynamic string for the current container element which can be used as
  143. * a HTML class property.
  144. *
  145. * @return string
  146. */
  147. protected function getContainerClass()
  148. {
  149. return "ts3_viewer " . $this->currObj->getClass(null);
  150. }
  151. /**
  152. * Returns the ID of the current node which will be used as a summary element for
  153. * the container element.
  154. *
  155. * @return integer
  156. */
  157. protected function getContainerSummary()
  158. {
  159. return $this->currObj->getId();
  160. }
  161. /**
  162. * Returns a dynamic string for the current row element which can be used as a HTML
  163. * class property.
  164. *
  165. * @return string
  166. */
  167. protected function getRowClass()
  168. {
  169. return ++$this->currNum%2 ? "row1" : "row2";
  170. }
  171. /**
  172. * Returns a string for the current prefix element which can be used as a HTML class
  173. * property.
  174. *
  175. * @return string
  176. */
  177. protected function getPrefixClass()
  178. {
  179. return "prefix " . $this->currObj->getClass(null);
  180. }
  181. /**
  182. * Returns the HTML img tags to display the prefix of the current node.
  183. *
  184. * @return string
  185. */
  186. protected function getPrefix()
  187. {
  188. $prefix = "";
  189. if(count($this->currSib))
  190. {
  191. $last = array_pop($this->currSib);
  192. foreach($this->currSib as $sibling)
  193. {
  194. $prefix .= ($sibling) ? $this->getImage("tree_line.gif") : $this->getImage("tree_blank.png");
  195. }
  196. $prefix .= ($last) ? $this->getImage("tree_end.gif") : $this->getImage("tree_mid.gif");
  197. }
  198. return $prefix;
  199. }
  200. /**
  201. * Returns a string for the current corpus element which can be used as a HTML class
  202. * property. If the current node is a channel spacer the class string will contain
  203. * additional class names to allow further customization of the content via CSS.
  204. *
  205. * @return string
  206. */
  207. protected function getCorpusClass()
  208. {
  209. $extras = "";
  210. if($this->currObj instanceof TeamSpeak3_Node_Channel && $this->currObj->isSpacer())
  211. {
  212. switch($this->currObj->spacerGetType())
  213. {
  214. case (string) TeamSpeak3::SPACER_SOLIDLINE:
  215. $extras .= " solidline";
  216. break;
  217. case (string) TeamSpeak3::SPACER_DASHLINE:
  218. $extras .= " dashline";
  219. break;
  220. case (string) TeamSpeak3::SPACER_DASHDOTLINE:
  221. $extras .= " dashdotline";
  222. break;
  223. case (string) TeamSpeak3::SPACER_DASHDOTDOTLINE:
  224. $extras .= " dashdotdotline";
  225. break;
  226. case (string) TeamSpeak3::SPACER_DOTLINE:
  227. $extras .= " dotline";
  228. break;
  229. }
  230. switch($this->currObj->spacerGetAlign())
  231. {
  232. case TeamSpeak3::SPACER_ALIGN_CENTER:
  233. $extras .= " center";
  234. break;
  235. case TeamSpeak3::SPACER_ALIGN_RIGHT:
  236. $extras .= " right";
  237. break;
  238. case TeamSpeak3::SPACER_ALIGN_LEFT:
  239. $extras .= " left";
  240. break;
  241. }
  242. }
  243. elseif($this->currObj instanceof TeamSpeak3_Node_Client && $this->currObj->client_is_recording)
  244. {
  245. $extras .= " recording";
  246. }
  247. return "corpus " . $this->currObj->getClass(null) . $extras;
  248. }
  249. /**
  250. * Returns the HTML img tags which can be used to display the various icons for a
  251. * TeamSpeak_Node_Abstract object.
  252. *
  253. * @return string
  254. */
  255. protected function getCorpusTitle()
  256. {
  257. if($this->currObj instanceof TeamSpeak3_Node_Server)
  258. {
  259. return "ID: " . $this->currObj->getId() . " | Clients: " . $this->currObj->clientCount() . "/" . $this->currObj["virtualserver_maxclients"] . " | Uptime: " . TeamSpeak3_Helper_Convert::seconds($this->currObj["virtualserver_uptime"]);
  260. }
  261. elseif($this->currObj instanceof TeamSpeak3_Node_Channel && !$this->currObj->isSpacer())
  262. {
  263. return "ID: " . $this->currObj->getId() . " | Codec: " . TeamSpeak3_Helper_Convert::codec($this->currObj["channel_codec"]) . " | Quality: " . $this->currObj["channel_codec_quality"];
  264. }
  265. elseif($this->currObj instanceof TeamSpeak3_Node_Client)
  266. {
  267. return "ID: " . $this->currObj->getId() . " | Version: " . TeamSpeak3_Helper_Convert::versionShort($this->currObj["client_version"]) . " | Platform: " . $this->currObj["client_platform"];
  268. }
  269. elseif($this->currObj instanceof TeamSpeak3_Node_Servergroup || $this->currObj instanceof TeamSpeak3_Node_Channelgroup)
  270. {
  271. return "ID: " . $this->currObj->getId() . " | Type: " . TeamSpeak3_Helper_Convert::groupType($this->currObj["type"]) . " (" . ($this->currObj["savedb"] ? "Permanent" : "Temporary") . ")";
  272. }
  273. }
  274. /**
  275. * Returns a HTML img tag which can be used to display the status icon for a
  276. * TeamSpeak_Node_Abstract object.
  277. *
  278. * @return string
  279. */
  280. protected function getCorpusIcon()
  281. {
  282. if($this->currObj instanceof TeamSpeak3_Node_Channel && $this->currObj->isSpacer()) return;
  283. return $this->getImage($this->currObj->getIcon() . ".png");
  284. }
  285. /**
  286. * Returns a string for the current corpus element which contains the display name
  287. * for the current TeamSpeak_Node_Abstract object.
  288. *
  289. * @return string
  290. */
  291. protected function getCorpusName()
  292. {
  293. if($this->currObj instanceof TeamSpeak3_Node_Channel && $this->currObj->isSpacer())
  294. {
  295. if($this->currObj->spacerGetType() != TeamSpeak3::SPACER_CUSTOM) return;
  296. $string = $this->currObj["channel_name"]->section("]", 1, 99);
  297. if($this->currObj->spacerGetAlign() == TeamSpeak3::SPACER_ALIGN_REPEAT)
  298. {
  299. $string->resize(30, $string);
  300. }
  301. return htmlspecialchars($string);
  302. }
  303. if($this->currObj instanceof TeamSpeak3_Node_Client)
  304. {
  305. $before = array();
  306. $behind = array();
  307. if(!$this->currObj->client_is_recording)
  308. {
  309. foreach($this->currObj->memberOf() as $group)
  310. {
  311. if($group->getProperty("namemode") == TeamSpeak3::GROUP_NAMEMODE_BEFORE)
  312. {
  313. $before[] = "[" . htmlspecialchars($group["name"]) . "]";
  314. }
  315. elseif($group->getProperty("namemode") == TeamSpeak3::GROUP_NAMEMODE_BEHIND)
  316. {
  317. $behind[] = "[" . htmlspecialchars($group["name"]) . "]";
  318. }
  319. }
  320. }
  321. else
  322. {
  323. $before[] = "***";
  324. $behind[] = "*** [RECORDING]";
  325. }
  326. return implode("", $before) . " " . htmlspecialchars($this->currObj) . " " . implode("", $behind);
  327. }
  328. return htmlspecialchars($this->currObj);
  329. }
  330. /**
  331. * Returns a string for the current suffix element which can be used as a HTML
  332. * class property.
  333. *
  334. * @return string
  335. */
  336. protected function getSuffixClass()
  337. {
  338. return "suffix " . $this->currObj->getClass(null);
  339. }
  340. /**
  341. * Returns the HTML img tags which can be used to display the various icons for a
  342. * TeamSpeak_Node_Abstract object.
  343. *
  344. * @return string
  345. */
  346. protected function getSuffixIcon()
  347. {
  348. if($this->currObj instanceof TeamSpeak3_Node_Server)
  349. {
  350. return $this->getSuffixIconServer();
  351. }
  352. elseif($this->currObj instanceof TeamSpeak3_Node_Channel)
  353. {
  354. return $this->getSuffixIconChannel();
  355. }
  356. elseif($this->currObj instanceof TeamSpeak3_Node_Client)
  357. {
  358. return $this->getSuffixIconClient();
  359. }
  360. }
  361. /**
  362. * Returns the HTML img tags which can be used to display the various icons for a
  363. * TeamSpeak_Node_Server object.
  364. *
  365. * @return string
  366. */
  367. protected function getSuffixIconServer()
  368. {
  369. $html = "";
  370. if($this->currObj["virtualserver_icon_id"])
  371. {
  372. if(!$this->currObj->iconIsLocal("virtualserver_icon_id") && $this->ftclient)
  373. {
  374. if(!isset($this->cacheIcon[$this->currObj["virtualserver_icon_id"]]))
  375. {
  376. $download = $this->currObj->transferInitDownload(rand(0x0000, 0xFFFF), 0, $this->currObj->iconGetName("virtualserver_icon_id"));
  377. if($this->ftclient == "data:image")
  378. {
  379. $download = TeamSpeak3::factory("filetransfer://" . (strstr($download["host"], ":") !== FALSE ? "[" . $download["host"] . "]" : $download["host"]) . ":" . $download["port"])->download($download["ftkey"], $download["size"]);
  380. }
  381. $this->cacheIcon[$this->currObj["virtualserver_icon_id"]] = $download;
  382. }
  383. else
  384. {
  385. $download = $this->cacheIcon[$this->currObj["virtualserver_icon_id"]];
  386. }
  387. if($this->ftclient == "data:image")
  388. {
  389. $html .= $this->getImage("data:" . TeamSpeak3_Helper_Convert::imageMimeType($download) . ";base64," . base64_encode($download), "Server Icon", null, FALSE);
  390. }
  391. else
  392. {
  393. $html .= $this->getImage($this->ftclient . "?ftdata=" . base64_encode(serialize($download)), "Server Icon", null, FALSE);
  394. }
  395. }
  396. elseif(in_array($this->currObj["virtualserver_icon_id"], $this->cachedIcons))
  397. {
  398. $html .= $this->getImage("group_icon_" . $this->currObj["virtualserver_icon_id"] . ".png", "Server Icon");
  399. }
  400. }
  401. return $html;
  402. }
  403. /**
  404. * Returns the HTML img tags which can be used to display the various icons for a
  405. * TeamSpeak_Node_Channel object.
  406. *
  407. * @return string
  408. */
  409. protected function getSuffixIconChannel()
  410. {
  411. if($this->currObj instanceof TeamSpeak3_Node_Channel && $this->currObj->isSpacer()) return;
  412. $html = "";
  413. if($this->currObj["channel_flag_default"])
  414. {
  415. $html .= $this->getImage("channel_flag_default.png", "Default Channel");
  416. }
  417. if($this->currObj["channel_flag_password"])
  418. {
  419. $html .= $this->getImage("channel_flag_password.png", "Password-protected");
  420. }
  421. if($this->currObj["channel_codec"] == TeamSpeak3::CODEC_CELT_MONO || $this->currObj["channel_codec"] == TeamSpeak3::CODEC_OPUS_MUSIC)
  422. {
  423. $html .= $this->getImage("channel_flag_music.png", "Music Codec");
  424. }
  425. if($this->currObj["channel_needed_talk_power"])
  426. {
  427. $html .= $this->getImage("channel_flag_moderated.png", "Moderated");
  428. }
  429. if($this->currObj["channel_icon_id"])
  430. {
  431. if(!$this->currObj->iconIsLocal("channel_icon_id") && $this->ftclient)
  432. {
  433. if(!isset($this->cacheIcon[$this->currObj["channel_icon_id"]]))
  434. {
  435. $download = $this->currObj->getParent()->transferInitDownload(rand(0x0000, 0xFFFF), 0, $this->currObj->iconGetName("channel_icon_id"));
  436. if($this->ftclient == "data:image")
  437. {
  438. $download = TeamSpeak3::factory("filetransfer://" . (strstr($download["host"], ":") !== FALSE ? "[" . $download["host"] . "]" : $download["host"]) . ":" . $download["port"])->download($download["ftkey"], $download["size"]);
  439. }
  440. $this->cacheIcon[$this->currObj["channel_icon_id"]] = $download;
  441. }
  442. else
  443. {
  444. $download = $this->cacheIcon[$this->currObj["channel_icon_id"]];
  445. }
  446. if($this->ftclient == "data:image")
  447. {
  448. $html .= $this->getImage("data:" . TeamSpeak3_Helper_Convert::imageMimeType($download) . ";base64," . base64_encode($download), "Channel Icon", null, FALSE);
  449. }
  450. else
  451. {
  452. $html .= $this->getImage($this->ftclient . "?ftdata=" . base64_encode(serialize($download)), "Channel Icon", null, FALSE);
  453. }
  454. }
  455. elseif(in_array($this->currObj["channel_icon_id"], $this->cachedIcons))
  456. {
  457. $html .= $this->getImage("group_icon_" . $this->currObj["channel_icon_id"] . ".png", "Channel Icon");
  458. }
  459. }
  460. return $html;
  461. }
  462. /**
  463. * Returns the HTML img tags which can be used to display the various icons for a
  464. * TeamSpeak_Node_Client object.
  465. *
  466. * @return string
  467. */
  468. protected function getSuffixIconClient()
  469. {
  470. $html = "";
  471. if($this->currObj["client_is_priority_speaker"])
  472. {
  473. $html .= $this->getImage("client_priority.png", "Priority Speaker");
  474. }
  475. if($this->currObj["client_is_channel_commander"])
  476. {
  477. $html .= $this->getImage("client_cc.png", "Channel Commander");
  478. }
  479. if($this->currObj["client_is_talker"])
  480. {
  481. $html .= $this->getImage("client_talker.png", "Talk Power granted");
  482. }
  483. elseif($cntp = $this->currObj->getParent()->channelGetById($this->currObj["cid"])->channel_needed_talk_power)
  484. {
  485. if($cntp > $this->currObj["client_talk_power"])
  486. {
  487. $html .= $this->getImage("client_mic_muted.png", "Insufficient Talk Power");
  488. }
  489. }
  490. foreach($this->currObj->memberOf() as $group)
  491. {
  492. if(!$group["iconid"]) continue;
  493. $type = ($group instanceof TeamSpeak3_Node_Servergroup) ? "Server Group" : "Channel Group";
  494. if(!$group->iconIsLocal("iconid") && $this->ftclient)
  495. {
  496. if(!isset($this->cacheIcon[$group["iconid"]]))
  497. {
  498. $download = $group->getParent()->transferInitDownload(rand(0x0000, 0xFFFF), 0, $group->iconGetName("iconid"));
  499. if($this->ftclient == "data:image")
  500. {
  501. $download = TeamSpeak3::factory("filetransfer://" . (strstr($download["host"], ":") !== FALSE ? "[" . $download["host"] . "]" : $download["host"]) . ":" . $download["port"])->download($download["ftkey"], $download["size"]);
  502. }
  503. $this->cacheIcon[$group["iconid"]] = $download;
  504. }
  505. else
  506. {
  507. $download = $this->cacheIcon[$group["iconid"]];
  508. }
  509. if($this->ftclient == "data:image")
  510. {
  511. $html .= $this->getImage("data:" . TeamSpeak3_Helper_Convert::imageMimeType($download) . ";base64," . base64_encode($download), $group . " [" . $type . "]", null, FALSE);
  512. }
  513. else
  514. {
  515. $html .= $this->getImage($this->ftclient . "?ftdata=" . base64_encode(serialize($download)), $group . " [" . $type . "]", null, FALSE);
  516. }
  517. }
  518. elseif(in_array($group["iconid"], $this->cachedIcons))
  519. {
  520. $html .= $this->getImage("group_icon_" . $group["iconid"] . ".png", $group . " [" . $type . "]");
  521. }
  522. }
  523. if($this->currObj["client_icon_id"])
  524. {
  525. if(!$this->currObj->iconIsLocal("client_icon_id") && $this->ftclient)
  526. {
  527. if(!isset($this->cacheIcon[$this->currObj["client_icon_id"]]))
  528. {
  529. $download = $this->currObj->getParent()->transferInitDownload(rand(0x0000, 0xFFFF), 0, $this->currObj->iconGetName("client_icon_id"));
  530. if($this->ftclient == "data:image")
  531. {
  532. $download = TeamSpeak3::factory("filetransfer://" . (strstr($download["host"], ":") !== FALSE ? "[" . $download["host"] . "]" : $download["host"]) . ":" . $download["port"])->download($download["ftkey"], $download["size"]);
  533. }
  534. $this->cacheIcon[$this->currObj["client_icon_id"]] = $download;
  535. }
  536. else
  537. {
  538. $download = $this->cacheIcon[$this->currObj["client_icon_id"]];
  539. }
  540. if($this->ftclient == "data:image")
  541. {
  542. $html .= $this->getImage("data:" . TeamSpeak3_Helper_Convert::imageMimeType($download) . ";base64," . base64_encode($download), "Client Icon", null, FALSE);
  543. }
  544. else
  545. {
  546. $html .= $this->getImage($this->ftclient . "?ftdata=" . base64_encode(serialize($download)), "Client Icon", null, FALSE);
  547. }
  548. }
  549. elseif(in_array($this->currObj["client_icon_id"], $this->cachedIcons))
  550. {
  551. $html .= $this->getImage("group_icon_" . $this->currObj["client_icon_id"] . ".png", "Client Icon");
  552. }
  553. }
  554. return $html;
  555. }
  556. /**
  557. * Returns a HTML img tag which can be used to display the country flag for a
  558. * TeamSpeak_Node_Client object.
  559. *
  560. * @return string
  561. */
  562. protected function getSuffixFlag()
  563. {
  564. if(!$this->currObj instanceof TeamSpeak3_Node_Client) return;
  565. if($this->flagpath && $this->currObj["client_country"])
  566. {
  567. return $this->getImage($this->currObj["client_country"]->toLower() . ".png", $this->currObj["client_country"], null, FALSE, TRUE);
  568. }
  569. }
  570. /**
  571. * Returns the code to display a custom HTML img tag.
  572. *
  573. * @param string $name
  574. * @param string $text
  575. * @param string $class
  576. * @param boolean $iconpath
  577. * @param boolean $flagpath
  578. * @return string
  579. */
  580. protected function getImage($name, $text = "", $class = null, $iconpath = TRUE, $flagpath = FALSE)
  581. {
  582. $src = "";
  583. if($iconpath)
  584. {
  585. $src = $this->iconpath;
  586. }
  587. if($flagpath)
  588. {
  589. $src = $this->flagpath;
  590. }
  591. return "<img src='" . $src . $name . "' title='" . $text . "' alt='' align='top' />";
  592. }
  593. }