PageRenderTime 38ms CodeModel.GetById 30ms RepoModel.GetById 1ms app.codeStats 0ms

/system/cp/cp.display.php

https://github.com/danboy/Croissierd
PHP | 3140 lines | 2947 code | 82 blank | 111 comment | 40 complexity | a6e7f9362613cb21d07f7151170df47c MD5 | raw file
  1. <?php
  2. /*
  3. =====================================================
  4. ExpressionEngine - by EllisLab
  5. -----------------------------------------------------
  6. http://expressionengine.com/
  7. -----------------------------------------------------
  8. Copyright (c) 2003 - 2010 EllisLab, Inc.
  9. =====================================================
  10. THIS IS COPYRIGHTED SOFTWARE
  11. PLEASE READ THE LICENSE AGREEMENT
  12. http://expressionengine.com/docs/license.html
  13. =====================================================
  14. File: cp.display.php
  15. -----------------------------------------------------
  16. Purpose: This class provides all the HTML dispaly
  17. elements used in the control panel.
  18. =====================================================
  19. */
  20. if ( ! defined('EXT'))
  21. {
  22. exit('Invalid file request');
  23. }
  24. class Display {
  25. var $publish_nav = 'hover'; // The PUBLISH tab drop down menu behavior. Either 'click' or 'hover'
  26. var $sites_nav = 'hover'; // The PUBLISH tab drop down menu behavior. Either 'click' or 'hover'
  27. var $title = ''; // Page title
  28. var $body = ''; // Main content area
  29. var $crumb = ''; // Breadcrumb.
  30. var $rcrumb = ''; // Right side breadcrumb
  31. var $crumbline = FALSE; // Assigns whether to show the line below the breadcrumb
  32. var $show_crumb = TRUE; // Assigns whether to show the breadcrumb
  33. var $crumb_ov = FALSE; // Crumb Override. Will prevent the "M" variable from getting auto-linked
  34. var $refresh = FALSE; // If set to a URL, the header will contain a <meta> refresh
  35. var $ref_rate = 0; // Rate of refresh
  36. var $url_append = ''; // This variable lets us globally append something onto URLs
  37. var $body_props = ''; // Code that can be addded the the <body> tag
  38. var $initial_body = ''; // We can manually add things just after the <body> tag.
  39. var $extra_css = ''; // Additional CSS that we can fetch from a different file. It gets added to the main CSS request.
  40. var $manual_css = ''; // Additional CSS that we can generate manually. It gets added to the main CSS request.
  41. var $extra_header = ''; // Additional headers we can add manually
  42. var $rcrumb_css = 'breadcrumbRight'; // The default CSS used in the right breadcrumb
  43. var $padding_tabs = 'clear'; // on/off/clear - The navigation tabs have an extra cell on the left and right side to provide padding. This determis how it should be displayed. It interacts with this variable, which is placed in the CSS file: {padding_tabs ="clear"}
  44. var $empty_menu = FALSE; // Is the Publish weblog menu empty?
  45. var $view_path = ''; // path to view files, set to the current addon's path
  46. var $cached_vars = array(); // array of cached view variables
  47. /** -------------------------------------
  48. /** Constructor
  49. /** -------------------------------------*/
  50. function Display()
  51. {
  52. global $PREFS;
  53. if ( ! defined('AMP')) define('AMP', '&amp;');
  54. if ( ! defined('BR')) define('BR', '<br />');
  55. if ( ! defined('NL')) define('NL', "\n");
  56. if ( ! defined('NBS')) define('NBS', "&nbsp;");
  57. $this->sites_nav = (in_array($PREFS->ini('sites_tab_behavior'), array('click', 'hover', 'none'))) ? $PREFS->ini('sites_tab_behavior') : $this->sites_nav;
  58. $this->publish_nav = (in_array($PREFS->ini('publish_tab_behavior'), array('click', 'hover', 'none'))) ? $PREFS->ini('publish_tab_behavior') : $this->publish_nav;
  59. // allows views to be loaded with identical syntax to 2.x within view files, e.g. $this->load->view('foo');
  60. $this->load =& $this;
  61. }
  62. /* END */
  63. /** -------------------------------------
  64. /** Allows the use of View files to construct output
  65. /** -------------------------------------*/
  66. function view($view, $vars = array(), $return = FALSE, $path = '')
  67. {
  68. global $DSP, $FNS, $LANG, $LOC, $PREFS, $REGX, $SESS;
  69. // Set the path to the requested file
  70. if ($path == '')
  71. {
  72. $ext = pathinfo($view, PATHINFO_EXTENSION);
  73. $file = ($ext == '') ? $view.EXT : $view;
  74. $path = $this->view_path.$file;
  75. }
  76. else
  77. {
  78. $x = explode('/', $path);
  79. $file = end($x);
  80. }
  81. if ( ! file_exists($path))
  82. {
  83. trigger_error('Unable to load the requested file: '.$file);
  84. return FALSE;
  85. }
  86. /*
  87. * Extract and cache variables
  88. *
  89. * You can either set variables using the dedicated $this->load_vars()
  90. * function or via the second parameter of this function. We'll merge
  91. * the two types and cache them so that views that are embedded within
  92. * other views can have access to these variables.
  93. */
  94. if (is_array($vars))
  95. {
  96. $this->cached_vars = array_merge($this->cached_vars, $vars);
  97. }
  98. extract($this->cached_vars);
  99. /*
  100. * Buffer the output
  101. *
  102. * We buffer the output for two reasons:
  103. * 1. Speed. You get a significant speed boost.
  104. * 2. So that the final rendered template can be
  105. * post-processed by the output class. Why do we
  106. * need post processing? For one thing, in order to
  107. * show the elapsed page load time. Unless we
  108. * can intercept the content right before it's sent to
  109. * the browser and then stop the timer it won't be accurate.
  110. */
  111. ob_start();
  112. // If the PHP installation does not support short tags we'll
  113. // do a little string replacement, changing the short tags
  114. // to standard PHP echo statements.
  115. if ((bool) @ini_get('short_open_tag') === FALSE)
  116. {
  117. echo eval('?>'.preg_replace("/;*\s*\?>/", "; ?>", str_replace('<?=', '<?php echo ', file_get_contents($path))));
  118. }
  119. else
  120. {
  121. include($path); // include() vs include_once() allows for multiple views with the same name
  122. }
  123. // Return the file data if requested
  124. if ($return === TRUE)
  125. {
  126. $buffer = ob_get_contents();
  127. ob_end_clean();
  128. return $buffer;
  129. }
  130. /*
  131. * Flush the buffer... or buff the flusher?
  132. *
  133. * In order to permit views to be nested within
  134. * other views, we need to flush the content back out whenever
  135. * we are beyond the first level of output buffering so that
  136. * it can be seen and included properly by the first included
  137. * template and any subsequent ones. Oy!
  138. *
  139. */
  140. if (ob_get_level() > 1)
  141. {
  142. ob_end_flush();
  143. }
  144. else
  145. {
  146. $buffer = ob_get_contents();
  147. ob_end_clean();
  148. return $buffer;
  149. }
  150. }
  151. /* END */
  152. /** -------------------------------------
  153. /** Set return data
  154. /** -------------------------------------*/
  155. function set_return_data($title = '', $body = '', $crumb = '', $rcrumb = '')
  156. {
  157. $this->title = $title;
  158. $this->body = $body;
  159. $this->crumb = $crumb;
  160. $this->rcrumb = $rcrumb;
  161. }
  162. /* END */
  163. /** -------------------------------------
  164. /** Group Access Verification
  165. /** -------------------------------------*/
  166. function allowed_group($which = '')
  167. {
  168. global $SESS;
  169. if ($which == '')
  170. {
  171. return FALSE;
  172. }
  173. // Super Admins always have access
  174. if ($SESS->userdata['group_id'] == 1)
  175. {
  176. return TRUE;
  177. }
  178. if ( !isset($SESS->userdata[$which]) OR $SESS->userdata[$which] !== 'y')
  179. return FALSE;
  180. else
  181. return TRUE;
  182. }
  183. /* END */
  184. /** -------------------------------------
  185. /** Control panel
  186. /** -------------------------------------*/
  187. function show_full_control_panel()
  188. {
  189. global $OUT, $EXT, $FNS;
  190. // -------------------------------------------
  191. // 'show_full_control_panel_start' hook.
  192. // - Full Control over CP
  193. // - Modify any $DSP class variable (JS, headers, etc.)
  194. // - Override any $DSP method and use their own
  195. //
  196. $edata = $EXT->call_extension('show_full_control_panel_start');
  197. if ($EXT->end_script === TRUE) return;
  198. //
  199. // -------------------------------------------
  200. $out = $this->html_header()
  201. .$this->page_header()
  202. .$this->page_navigation()
  203. .$this->breadcrumb()
  204. .$this->content()
  205. .$this->content_close()
  206. .$this->copyright()
  207. .$this->html_footer();
  208. $out = $FNS->insert_action_ids($out);
  209. // -------------------------------------------
  210. // 'show_full_control_panel_end' hook.
  211. // - Rewrite CP's HTML
  212. // - Find/Replace Stuff, etc.
  213. //
  214. if ($EXT->active_hook('show_full_control_panel_end') === TRUE)
  215. {
  216. $out = $EXT->universal_call_extension('show_full_control_panel_end', $out);
  217. if ($EXT->end_script === TRUE) return;
  218. }
  219. //
  220. // -------------------------------------------
  221. $OUT->build_queue($out);
  222. }
  223. /* END */
  224. /** -------------------------------------
  225. /** Show restricted version of CP
  226. /** -------------------------------------*/
  227. function show_restricted_control_panel()
  228. {
  229. global $IN, $OUT, $SESS, $FNS;
  230. $r = $this->html_header();
  231. // We treat the bookmarklet as a special case
  232. // and show the navigation links in the top right
  233. // side of the page
  234. if ($IN->GBL('BK') AND $SESS->userdata['admin_sess'] == 1)
  235. {
  236. $r .= $this->page_header(0);
  237. }
  238. else
  239. {
  240. $r .= $this->simple_header('helpLinksLeft');
  241. }
  242. $r .= $this->content(TRUE);
  243. $r .= $this->content_close();
  244. $r .= $this->html_footer();
  245. $r = $FNS->insert_action_ids($r);
  246. $OUT->build_queue($r);
  247. }
  248. /* END */
  249. /** -------------------------------------
  250. /** Show "login" version of CP
  251. /** -------------------------------------*/
  252. function show_login_control_panel()
  253. {
  254. global $IN, $OUT, $SESS;
  255. $this->secure_hash();
  256. $r = $this->html_header()
  257. .$this->simple_header()
  258. .$this->body
  259. .$this->copyright()
  260. .$this->html_footer();
  261. $OUT->build_queue($r);
  262. }
  263. /* END */
  264. /** -------------------------------------
  265. /** HTML Header
  266. /** -------------------------------------*/
  267. function html_header($title = '')
  268. {
  269. global $PREFS;
  270. if ($title == '')
  271. $title = $this->title;
  272. $header =
  273. "<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\n".
  274. "<html>\n".
  275. "<head>\n".
  276. "<title>$title | ".APP_NAME."</title>\n\n".
  277. "<meta http-equiv='content-type' content='text/html; charset=".$PREFS->ini('charset')."' >\n".
  278. "<meta http-equiv='expires' content='-1' >\n".
  279. "<meta http-equiv='expires' content='Mon, 01 Jan 1970 23:59:59 GMT' >\n".
  280. "<meta http-equiv='pragma' content='no-cache' >\n";
  281. if ($this->refresh !== FALSE)
  282. {
  283. $header .= "<meta http-equiv=\"refresh\" content=\"".$this->ref_rate."; url=".$this->refresh."\" >\n";
  284. }
  285. // Change CSS on the click so it works like the hover until they unclick?
  286. $tab_behaviors = array(
  287. 'publish_tab_selector' => ($PREFS->ini('publish_tab_behavior') == 'hover') ? 'hover' : 'active',
  288. 'publish_tab_display' => ($PREFS->ini('publish_tab_behavior') == 'none') ? '' : 'display:block; visibility: visible;',
  289. 'publish_tab_ul_display' => ($PREFS->ini('publish_tab_behavior') == 'none') ? '' : 'display:none;',
  290. 'sites_tab_selector' => ($PREFS->ini('sites_tab_behavior') == 'hover') ? 'hover' : 'active',
  291. 'sites_tab_display' => ($PREFS->ini('sites_tab_behavior') == 'none') ? '' : 'display:block; visibility: visible;',
  292. 'sites_tab_ul_display' => ($PREFS->ini('sites_tab_behavior') == 'none') ? '' : 'display:none;'
  293. );
  294. $stylesheet = $this->fetch_stylesheet();
  295. foreach ($tab_behaviors as $key => $val)
  296. {
  297. $stylesheet = str_replace(LD.$key.RD, $val, $stylesheet);
  298. }
  299. $header .=
  300. "<style type='text/css'>\n".
  301. $stylesheet."\n\n".
  302. $this->manual_css.
  303. "</style>\n\n".
  304. $this->_menu_js().
  305. $this->_global_javascript().
  306. $this->extra_header.
  307. "</head>\n\n".
  308. "<body{$this->body_props}>\n".
  309. $this->initial_body."\n";
  310. return $header;
  311. }
  312. /* END */
  313. /** -------------------------------------
  314. /** Fetch CSS Stylesheet
  315. /** -------------------------------------*/
  316. function fetch_stylesheet()
  317. {
  318. global $PREFS, $OUT, $SESS, $LANG;
  319. $cp_theme = (! isset($SESS->userdata['cp_theme']) || $SESS->userdata['cp_theme'] == '') ? $PREFS->ini('cp_theme') : $SESS->userdata['cp_theme'];
  320. $path = ( ! is_dir('./cp_themes/')) ? PATH_CP_THEME : './cp_themes/';
  321. if ( ! $theme = $this->file_open($path.$cp_theme.'/'.$cp_theme.'.css'))
  322. {
  323. if ( ! $theme = $this->file_open($path.'default/default.css'))
  324. {
  325. return '';
  326. }
  327. }
  328. if ($this->extra_css != '')
  329. {
  330. if ($extra = $this->file_open($this->extra_css))
  331. {
  332. $theme .= NL.NL.$extra;
  333. }
  334. }
  335. // Set the value of the "padding tabs" based on
  336. // a variable (that might be) contained in the CSS file
  337. if (preg_match("/\{padding_tabs\s*=\s*['|\"](.+?)['|\"]\}/", $theme, $match))
  338. {
  339. $this->padding_tabs = $match['1'];
  340. $theme = str_replace($match['0'], '', $theme);
  341. }
  342. // Remove comments and spaces from CSS file
  343. $theme = preg_replace("/\/\*.*?\*\//s", '', $theme);
  344. $theme = preg_replace("/\}\s+/s", "}\n", $theme);
  345. // Replace the {path:image_url} variable.
  346. $img_path = $PREFS->ini('theme_folder_url', 1).'cp_themes/'.$cp_theme.'/images/';
  347. $theme = str_replace('{path:image_url}', $img_path, $theme);
  348. return $theme;
  349. }
  350. /* END */
  351. /** -------------------------------------
  352. /** File Opener
  353. /** -------------------------------------*/
  354. function file_open($file)
  355. {
  356. if ( ! $fp = @fopen($file, 'rb'))
  357. {
  358. return FALSE;
  359. }
  360. flock($fp, LOCK_SH);
  361. $f = '';
  362. if (filesize($file) > 0)
  363. {
  364. $f = fread($fp, filesize($file));
  365. }
  366. flock($fp, LOCK_UN);
  367. fclose($fp);
  368. return $f;
  369. }
  370. /* END */
  371. /** -------------------------------------
  372. /** Page Header
  373. /** -------------------------------------*/
  374. function page_header($header = TRUE)
  375. {
  376. global $IN, $LANG, $SESS, $FNS, $PREFS;
  377. $qm = ($PREFS->ini('force_query_string') == 'y') ? '' : '?';
  378. $r = "<div id='topBar'>\n"
  379. .$this->table('', '', '0', '100%')
  380. .$this->tr()
  381. .$this->td('helpLinks')
  382. .$this->div('helpLinksLeft')
  383. .$this->anchor($FNS->fetch_site_index().$qm.'URL=http://expressionengine.com/', APP_NAME.$this->nbs(2).'v '.APP_VER)
  384. .$this->div_c()
  385. .$this->td_c()
  386. .$this->td('helpLinks');
  387. $r .= $this->anchor(BASE.AMP.'C=myaccount'.AMP.'M=quicklinks'.AMP.'id='.$SESS->userdata('member_id'),
  388. "<img src='".PATH_CP_IMG."edit_quicklinks.png' border='0' width='16' height='16' style='vertical-align: bottom;' alt='".$LANG->line('edit_quicklinks')."' />")
  389. .$this->nbs(3);
  390. $r .= $this->fetch_quicklinks();
  391. $doc_path = rtrim($PREFS->ini('doc_url'), '/').'/';
  392. $r .= $this->anchor(BASE, $LANG->line('main_menu')).$this->nbs(3).'|'.$this->nbs(3)
  393. ."<a href='".$doc_path."' target='_blank'>".$LANG->line('user_guide').'</a>'.$this->nbs(3).'|'.$this->nbs(3)
  394. .$this->anchor(BASE.AMP.'C=logout', $LANG->line('logout')).$this->nbs(3).'|'.$this->nbs(3);
  395. $r .= $this->anchor(BASE.AMP.'C=myaccount'.AMP.'M=tab_manager'.$this->generate_quick_tab(), $LANG->line('new_tab'))
  396. .$this->td_c()
  397. .$this->tr_c()
  398. .$this->table_c()
  399. .$this->div_c();
  400. if ($header != 0)
  401. $r .= "<div id='header'></div>\n";
  402. return $r;
  403. }
  404. /* END */
  405. /** -------------------------------------
  406. /** Quicklinks
  407. /** -------------------------------------*/
  408. function fetch_quicklinks()
  409. {
  410. global $SESS, $FNS, $PREFS;
  411. if ( ! isset($SESS->userdata['quick_links']) || $SESS->userdata['quick_links'] == '')
  412. {
  413. return '';
  414. }
  415. $r = '';
  416. foreach (explode("\n", $SESS->userdata['quick_links']) as $row)
  417. {
  418. $x = explode('|', $row);
  419. $title = (isset($x['0'])) ? $x['0'] : '';
  420. $link = (isset($x['1'])) ? $x['1'] : '';
  421. $qm = ($PREFS->ini('force_query_string') == 'y') ? '' : '?';
  422. $r .= $this->anchor($FNS->fetch_site_index().$qm.'URL='.$link, $this->html_attribute_prep($title), '', 1).$this->nbs(3).'|'.$this->nbs(3);
  423. }
  424. return $r;
  425. }
  426. /* END */
  427. /** -------------------------------------
  428. /** Quck Tabs
  429. /** -------------------------------------*/
  430. function fetch_quicktabs()
  431. {
  432. global $SESS, $FNS, $PREFS;
  433. $tabs = array();
  434. if ( ! isset($SESS->userdata['quick_tabs']) || $SESS->userdata['quick_tabs'] == '')
  435. {
  436. return $tabs;
  437. }
  438. foreach (explode("\n", $SESS->userdata['quick_tabs']) as $row)
  439. {
  440. $x = explode('|', $row);
  441. $title = (isset($x['0'])) ? $x['0'] : '';
  442. $link = (isset($x['1'])) ? $x['1'] : '';
  443. $tabs[] = array($title, $link);
  444. }
  445. return $tabs;
  446. }
  447. /* END */
  448. /** -------------------------------------
  449. /** Create the "quick add" link
  450. /** -------------------------------------*/
  451. function generate_quick_tab()
  452. {
  453. global $IN, $SESS;
  454. $link = '';
  455. $linkt = '';
  456. if ($IN->GBL('M') != 'tab_manager' AND $IN->GBL('M') != '')
  457. {
  458. foreach ($_GET as $key => $val)
  459. {
  460. if ($key == 'S')
  461. continue;
  462. $link .= $key.'--'.$val.'/';
  463. }
  464. $link = substr($link, 0, -1);
  465. }
  466. // Does the link already exist as a tab?
  467. // If so, we'll make the link blank so that the
  468. // tab manager won't let the user create another tab.
  469. $show_link = TRUE;
  470. if (isset($SESS->userdata['quick_tabs']) AND $SESS->userdata['quick_tabs'] != '')
  471. {
  472. $newlink = '|'.str_replace('/', '&', str_replace('--', '=', $link)).'|';
  473. if (strpos($SESS->userdata['quick_tabs'], $newlink))
  474. {
  475. $show_link = FALSE;
  476. }
  477. }
  478. // We do not normally allow semicolons in GET variables, so we protect it
  479. // in this rare instance.
  480. $tablink = ($link != '' AND $show_link == TRUE) ? AMP.'link='.$link.AMP.'linkt='.base64_encode($this->title) : '';
  481. return $tablink;
  482. }
  483. /* END */
  484. /** -------------------------------------
  485. /** Simple version of the Header
  486. /** -------------------------------------*/
  487. function simple_header($class ='loginLogo')
  488. {
  489. global $LANG, $PREFS;
  490. return
  491. "<div id='topBar'>\n"
  492. .$this->table('', '', '0', '100%')
  493. .$this->table_qrow('helpLinks', $this->qdiv($class, $this->nbs(2).APP_NAME.$this->nbs(2).'v '.APP_VER))
  494. .$this->table_c()
  495. .$this->div_c()
  496. ."<div id='simpleHeader'></div>\n";
  497. }
  498. /* END */
  499. /** -------------------------------------
  500. /** Equalize Text
  501. /** -------------------------------------*/
  502. // This function lets us "equalize" the text length by adding non-breaking spaces
  503. // before/after each line so that they all match. This enables the
  504. // navigation buttons to have the same length. The function must be passed an
  505. // associative array
  506. function equalize_text($text = array())
  507. {
  508. $longest = 0;
  509. foreach ($text as $val)
  510. {
  511. $val = strlen($val);
  512. if ($val > $longest)
  513. $longest = $val;
  514. }
  515. foreach ($text as $key => $val)
  516. {
  517. $i = $longest - strlen($val);
  518. $i = ceil($i/2);
  519. $val = $this->nbs($i).$val.$this->nbs($i);
  520. $text[$key] = $val;
  521. }
  522. return $text;
  523. }
  524. /* END */
  525. /** -------------------------------------
  526. /** Main control panel navigation
  527. /** -------------------------------------*/
  528. function page_navigation()
  529. {
  530. global $IN, $DB, $SESS, $LANG, $EXT, $PREFS;
  531. /* -------------------------------------------
  532. /* 'cp_display_page_navigation' hook.
  533. /* - Take control of the Control Panel's top navigation
  534. /* - Added 1.5.0
  535. */
  536. $r = $EXT->universal_call_extension('cp_display_page_navigation', $this);
  537. if ($EXT->end_script === TRUE) return $r;
  538. /*
  539. // -------------------------------------------*/
  540. $C = ($IN->GBL('class_override', 'GET') == '') ? $IN->GBL('C') : $IN->GBL('class_override', 'GET') ;
  541. // First we'll gather the navigation menu text in the selected language.
  542. $text = array( 'sites' => $LANG->line('sites'),
  543. 'publish' => $LANG->line('publish'),
  544. 'edit' => $LANG->line('edit'),
  545. 'design' => $LANG->line('design'),
  546. 'communicate' => $LANG->line('communicate'),
  547. 'modules' => $LANG->line('modules'),
  548. 'my_account' => $LANG->line('my_account'),
  549. 'admin' => $LANG->line('admin')
  550. );
  551. if ($PREFS->ini('multiple_sites_enabled') !== 'y')
  552. {
  553. unset($text['sites']);
  554. }
  555. // Fetch the custom tabs if there are any
  556. $quicktabs = $this->fetch_quicktabs();
  557. // Set access flags
  558. $cells = array(
  559. 's_lock' => 'can_access_sites',
  560. 'p_lock' => 'can_access_publish',
  561. 'e_lock' => 'can_access_edit',
  562. 'd_lock' => 'can_access_design',
  563. 'c_lock' => 'can_access_comm',
  564. 'm_lock' => 'can_access_modules',
  565. 'a_lock' => 'can_access_admin'
  566. );
  567. // Dynamically set the table width based on the number
  568. // of tabs that will be shown.
  569. $tab_total = sizeof($text) + count($quicktabs); // Total possible tabs
  570. $width_base = floor(80/$tab_total); // Width of each tab
  571. $width_pad = 98;
  572. foreach ($cells as $key => $val)
  573. {
  574. if ($key == 's_lock' && $PREFS->ini('multiple_sites_enabled') == 'y' && sizeof($SESS->userdata('assigned_sites')) > 0)
  575. {
  576. $$key = 0;
  577. }
  578. elseif ( ! $this->allowed_group($val))
  579. {
  580. $$key = 1;
  581. $width_pad -= $width_base;
  582. $tab_total--;
  583. }
  584. else
  585. {
  586. $$key = 0;
  587. }
  588. }
  589. if ($tab_total < 6)
  590. {
  591. $width = ($tab_total <= 0) ? 0 : ceil($width_pad/$tab_total);
  592. $width_pad = floor(100-$width_pad);
  593. }
  594. else
  595. {
  596. $width = ceil(96/$tab_total);
  597. $width_pad = 0;
  598. }
  599. /*
  600. Does a custom tab need to be highlighted?
  601. Since users can have custom tabs we need to highlight them when the page is
  602. accessed. However, when we do, we need to prevent any of the default tabs
  603. from being highlighted. Say, for example, that someone creates a tab pointing
  604. to the Photo Gallery. When that tab is accessed it needs to be highlighted (obviously)
  605. but we don't want the MODULES tab to also be highlighted or it'll look funny.
  606. Since the Photo Gallery is within the MODULES tab it'll hightlight itself automatically.
  607. So... we'll use a variable called: $highlight_override
  608. When set to TRUE, this variable turns off all default tabs.
  609. The following code blasts thorough the GET variables to see if we have
  610. a custom tab to show. If we do, we'll highlight it, and turn off
  611. all the other tabs.
  612. */
  613. $highlight_override = FALSE;
  614. $tabs = '';
  615. $tabct = 1;
  616. if (count($quicktabs) > 0)
  617. {
  618. foreach ($quicktabs as $val)
  619. {
  620. $gkey = '';
  621. $gval = '';
  622. if (strpos($val['1'], '&'))
  623. {
  624. $x = explode('&', $val['1']);
  625. $i = 1;
  626. foreach ($x as $v)
  627. {
  628. $z = explode('=', $v);
  629. if (isset($_GET[$z['0']]))
  630. {
  631. if ($_GET[$z['0']] != $z['1'])
  632. {
  633. $gkey = '';
  634. $gval = '';
  635. break;
  636. }
  637. elseif (count($x)+1 == count($_GET))
  638. {
  639. $gkey = $z['0'];
  640. $gval = $z['1'];
  641. }
  642. }
  643. }
  644. }
  645. elseif (strpos($val['1'], '='))
  646. {
  647. $z = explode('=', $v);
  648. if (isset($_GET[$z['0']]))
  649. {
  650. $gkey = $z['0'];
  651. $gval = $z['1'];
  652. }
  653. }
  654. $tab_nav_on = FALSE;
  655. if (isset($_GET[$gkey]) AND $_GET[$gkey] == $gval)
  656. {
  657. $highlight_override = TRUE;
  658. $tab_nav_on = TRUE;
  659. }
  660. $linktext = ( ! isset($text[$val['0']])) ? $val['0'] : $text[$val['0']];
  661. $linktext = $this->clean_tab_text($linktext);
  662. $tabid = 'tab'.$tabct;
  663. $tabct ++;
  664. if ($tab_nav_on == TRUE)
  665. {
  666. $js = ' onclick="navjump(\''.BASE.AMP.$val['1'].'\');"';
  667. $tabs .= "<td class='navCell' width='".$width."%' ".$js.">";
  668. $div = $this->qdiv('cpNavOn', $linktext);
  669. }
  670. else
  671. {
  672. $js = ' onclick="navjump(\''.BASE.AMP.$val['1'].'\');" onmouseover="navTabOn(\''.$tabid.'\');" onmouseout="navTabOff(\''.$tabid.'\');" ';
  673. $tabs .= "<td class='navCell' width='".$width."%' ".$js.">";
  674. $div = $this->div('cpNavOff', '', $tabid).$linktext.$this->div_c();
  675. }
  676. $tabs .= $this->anchor(BASE.AMP.$val['1'], $div);
  677. $tabs .= $this->td_c();
  678. }
  679. }
  680. $r = '';
  681. /** -------------------------------------
  682. /** Create Navigation Tabs
  683. /** -------------------------------------*/
  684. // Define which nav item to show based on the group
  685. // permission settings and render the finalized navigaion
  686. $r .= $this->table('', '0', '0', '100%')
  687. .$this->tr();
  688. if ($this->padding_tabs != 'off')
  689. {
  690. $r .= $this->td('navCell');
  691. if ($this->padding_tabs == 'clear')
  692. {
  693. $r .= $this->nbs();
  694. }
  695. else
  696. {
  697. $r .= $this->div('cpNavOff')
  698. .$this->nbs()
  699. .$this->div_c();
  700. }
  701. $r .= $this->td_c().NL.NL;
  702. }
  703. /** -------------------------------------
  704. /** Sites Tab
  705. /** -------------------------------------*/
  706. if ($s_lock == 0 && sizeof($SESS->userdata('assigned_sites')) > 0 && $PREFS->ini('multiple_sites_enabled') == 'y')
  707. {
  708. if ($this->sites_nav == 'click' && sizeof($SESS->userdata['assigned_sites']) > 0)
  709. {
  710. $js = ' onclick="dropdownmenu(\'sitesdropmenu\');return false;"';
  711. }
  712. else
  713. {
  714. $js = ' onclick="navjump(\''.BASE.AMP.'C=admin'.AMP.'M=site_admin'.AMP.'P=sites_list'.'\');"';
  715. }
  716. if ($C == 'sites' AND $highlight_override == FALSE)
  717. {
  718. $div = $this->qdiv('cpNavOn', $this->clean_tab_text($text['sites']));
  719. }
  720. else
  721. {
  722. $div = $this->div('cpNavOff', '', 'sites').$this->clean_tab_text($text['sites']).$this->div_c();
  723. }
  724. $page = '';
  725. foreach ($_GET as $key => $val)
  726. {
  727. // Remove the Session and Update segments
  728. if ($key == 'S' OR $key == 'U' OR strlen($key) > 1 OR stristr($val, 'update_'))
  729. {
  730. continue;
  731. }
  732. $page .= $key.'='.$val.'|';
  733. }
  734. if ($page != '')
  735. {
  736. $page = AMP."page=".str_replace('=', '_', base64_encode($page));
  737. }
  738. if (sizeof($SESS->userdata['assigned_sites']) > 0)
  739. {
  740. $div .= '<ul id="sitesdropmenu">';
  741. foreach($SESS->userdata['assigned_sites'] as $site_id => $site_label)
  742. {
  743. $div .= "<li class='sitesdropmenuinner'><a href='".BASE.AMP."C=sites".AMP."site_id=".$site_id.$page."' title='".$this->html_attribute_prep($site_label)."' onclick='location.href=this.href;'>".$this->html_attribute_prep($site_label)."</a></li>";
  744. }
  745. if ($this->allowed_group('can_admin_sites'))
  746. {
  747. $div .= "<li class='publishdropmenuinner'><a href='".BASE.AMP."C=admin".AMP."M=site_admin".AMP."P=sites_list' title='".$LANG->line('edit_sites')."' onclick='location.href=this.href;'><em>&#187;&nbsp;".$LANG->line('edit_sites')."</em></a></li>";
  748. }
  749. $div .= "</ul>";
  750. }
  751. $r .= "<td class='navCell' width='".$width."%' ".$js.">";
  752. $r .= $this->anchor(BASE.AMP.'C=sites', $div);
  753. $r .= $this->td_c().NL.NL;
  754. $r .= $this->td('navCell');
  755. if ($this->padding_tabs == 'clear')
  756. {
  757. $r .= $this->nbs();
  758. }
  759. else
  760. {
  761. $r .= $this->div('cpNavOff')
  762. .$this->nbs()
  763. .$this->div_c();
  764. }
  765. $r .= $this->td_c().NL.NL;
  766. }
  767. /** -------------------------------------
  768. /** Publish Tab
  769. /** -------------------------------------*/
  770. // Define which nav item to show based on the group
  771. // permission settings and render the finalized navigaion
  772. if ($p_lock == 0)
  773. {
  774. if ($this->publish_nav == 'click' && sizeof($SESS->userdata['assigned_weblogs']) > 0)
  775. {
  776. $js = ' onclick="dropdownmenu(\'publishdropmenu\');return false;"';
  777. }
  778. else
  779. {
  780. $js = ' onclick="navjump(\''.BASE.AMP.'C=publish'.'\');"';
  781. }
  782. $r .= "<td class='navCell' width='".$width."%' ".$js.">";
  783. if ($C == 'publish' AND $highlight_override == FALSE)
  784. {
  785. $div = $this->qdiv('cpNavOn', $this->clean_tab_text($text['publish']));
  786. }
  787. else
  788. {
  789. $div = $this->div('cpNavOff', '', 'publish').$this->clean_tab_text($text['publish']).$this->div_c();
  790. }
  791. if (sizeof($SESS->userdata['assigned_weblogs']) > 0)
  792. {
  793. $div .= '<ul id="publishdropmenu">';
  794. foreach($SESS->userdata['assigned_weblogs'] as $weblog_id => $weblog_label)
  795. {
  796. $div .= "<li class='publishdropmenuinner'><a href='".BASE.AMP."C=publish".AMP."M=entry_form".AMP."weblog_id=".$weblog_id."' title='".$this->html_attribute_prep($weblog_label)."' onclick='location.href=this.href;'>".$this->html_attribute_prep($weblog_label)."</a></li>";
  797. }
  798. if ($this->allowed_group('can_admin_weblogs'))
  799. {
  800. $div .= "<li class='publishdropmenuinner'><a href='".BASE.AMP."C=admin".AMP."M=blog_admin".AMP."P=blog_list' title='".$LANG->line('edit_weblogs')."' onclick='location.href=this.href;'><em>&#187;&nbsp;".$LANG->line('edit_weblogs')."</em></a></li>";
  801. }
  802. $div .= "</ul>";
  803. }
  804. $r .= $this->anchor(BASE.AMP.'C=publish', $div);
  805. $r .= $this->td_c().NL.NL;
  806. }
  807. /** -------------------------------------
  808. /** Edit Tab
  809. /** -------------------------------------*/
  810. if ($e_lock == 0)
  811. {
  812. if ($C == 'edit' AND $highlight_override == FALSE)
  813. {
  814. $js = ' onclick="navjump(\''.BASE.AMP.'C=edit'.'\');"';
  815. $r .= "<td class='navCell' width='".$width."%' ".$js.">";
  816. $div = $this->qdiv('cpNavOn', $this->clean_tab_text($text['edit']));
  817. }
  818. else
  819. {
  820. $js = ' onclick="navjump(\''.BASE.AMP.'C=edit'.'\');" onmouseover="navTabOn(\'edit\');" onmouseout="navTabOff(\'edit\');" ';
  821. $r .= "<td class='navCell' width='".$width."%' ".$js.">";
  822. $div = $this->div('cpNavOff', '', 'edit').$this->clean_tab_text($text['edit']).$this->div_c();
  823. }
  824. $r .= $this->anchor(BASE.AMP.'C=edit', $div);
  825. $r .= $this->td_c().NL.NL;
  826. }
  827. /** -------------------------------------
  828. /** Custom Tabs
  829. /** -------------------------------------*/
  830. $r .= $tabs;
  831. if ($d_lock == 0)
  832. {
  833. if ($C == 'templates' AND $highlight_override == FALSE)
  834. {
  835. $js = ' onclick="navjump(\''.BASE.AMP.'C=templates'.'\');"';
  836. $r .= "<td class='navCell' width='".$width."%' ".$js.">";
  837. $div = $this->qdiv('cpNavOn', $this->clean_tab_text($text['design']));
  838. }
  839. else
  840. {
  841. $js = ' onclick="navjump(\''.BASE.AMP.'C=templates'.'\');" onmouseover="navTabOn(\'design\');" onmouseout="navTabOff(\'design\');" ';
  842. $r .= "<td class='navCell' width='".$width."%' ".$js.">";
  843. $div = $this->div('cpNavOff', '', 'design').$this->clean_tab_text($text['design']).$this->div_c();
  844. }
  845. $r .= $this->anchor(BASE.AMP.'C=templates', $div);
  846. $r .= $this->td_c();
  847. }
  848. if ($c_lock == 0)
  849. {
  850. if ($C == 'communicate' AND $highlight_override == FALSE)
  851. {
  852. $js = ' onclick="navjump(\''.BASE.AMP.'C=communicate'.'\');"';
  853. $r .= "<td class='navCell' width='".$width."%' ".$js.">";
  854. $div = $this->qdiv('cpNavOn', $this->clean_tab_text($text['communicate']));
  855. }
  856. else
  857. {
  858. $js = ' onclick="navjump(\''.BASE.AMP.'C=communicate'.'\');" onmouseover="navTabOn(\'communicate\');" onmouseout="navTabOff(\'communicate\');" ';
  859. $r .= "<td class='navCell' width='".$width."%' ".$js.">";
  860. $div = $this->div('cpNavOff', '', 'communicate').$this->clean_tab_text($text['communicate']).$this->div_c();
  861. }
  862. $r .= $this->anchor(BASE.AMP.'C=communicate', $div);
  863. $r .= $this->td_c();
  864. }
  865. if ($m_lock == 0)
  866. {
  867. if ($C == 'modules' AND $highlight_override == FALSE)
  868. {
  869. $js = ' onclick="navjump(\''.BASE.AMP.'C=modules'.'\');"';
  870. $r .= "<td class='navCell' width='".$width."%' ".$js.">";
  871. $div = $this->qdiv('cpNavOn', $this->clean_tab_text($text['modules']));
  872. }
  873. else
  874. {
  875. $js = ' onclick="navjump(\''.BASE.AMP.'C=modules'.'\');" onmouseover="navTabOn(\'modules\');" onmouseout="navTabOff(\'modules\');" ';
  876. $r .= "<td class='navCell' width='".$width."%' ".$js.">";
  877. $div = $this->div('cpNavOff', '', 'modules').$this->clean_tab_text($text['modules']).$this->div_c();
  878. }
  879. $r .= $this->anchor(BASE.AMP.'C=modules', $div);
  880. $r .= $this->td_c();
  881. }
  882. // We only want the "MY ACCOUNT" tab highlighted if
  883. // the profile being viewed belongs to the logged in user
  884. $tab = $this->div('cpNavOff');
  885. if ($C == 'myaccount')
  886. {
  887. $id = ( ! $IN->GBL('id', 'GP')) ? $SESS->userdata('member_id') : $IN->GBL('id', 'GP');
  888. if ($id != $SESS->userdata('member_id'))
  889. {
  890. $tab = $this->div('cpNavOff');
  891. }
  892. else
  893. {
  894. if ($highlight_override == FALSE)
  895. $tab = $this->div('cpNavOn');
  896. }
  897. }
  898. if ($C == 'myaccount' AND $highlight_override == FALSE)
  899. {
  900. $js = ' onclick="navjump(\''.BASE.AMP.'C=myaccount'.'\');"';
  901. $r .= "<td class='navCell' width='".$width."%' ".$js.">";
  902. $div = $this->qdiv('cpNavOn', $this->clean_tab_text($text['my_account']));
  903. }
  904. else
  905. {
  906. $js = ' onclick="navjump(\''.BASE.AMP.'C=myaccount'.'\');" onmouseover="navTabOn(\'my_account\');" onmouseout="navTabOff(\'my_account\');" ';
  907. $r .= "<td class='navCell' width='".$width."%' ".$js.">";
  908. $div = $this->div('cpNavOff', '', 'my_account').$this->clean_tab_text($text['my_account']).$this->div_c();
  909. }
  910. $r .= $this->anchor(BASE.AMP.'C=myaccount', $div);
  911. $r .= $this->td_c();
  912. if ($a_lock == 0)
  913. {
  914. if ($C == 'admin' AND $highlight_override == FALSE)
  915. {
  916. $js = ' onclick="navjump(\''.BASE.AMP.'C=admin'.'\');"';
  917. $r .= "<td class='navCell' width='".$width."%' ".$js.">";
  918. $div = $this->qdiv('cpNavOn', $this->clean_tab_text($text['admin']));
  919. }
  920. else
  921. {
  922. $js = ' onclick="navjump(\''.BASE.AMP.'C=admin'.'\');" onmouseover="navTabOn(\'admin\');" onmouseout="navTabOff(\'admin\');" ';
  923. $r .= "<td class='navCell' width='".$width."%' ".$js.">";
  924. $div = $this->div('cpNavOff', '', 'admin').$this->clean_tab_text($text['admin']).$this->div_c();
  925. }
  926. $r .= $this->anchor(BASE.AMP.'C=admin', $div);
  927. $r .= $this->td_c();
  928. }
  929. if ($this->padding_tabs != 'off')
  930. {
  931. $r .= $this->td('navCell', (($width_pad <= 2) ? '': $width_pad.'%'));
  932. if ($this->padding_tabs == 'clear')
  933. {
  934. $r .= $this->nbs();
  935. }
  936. else
  937. {
  938. $r .= $this->div('cpNavOff')
  939. .$this->nbs()
  940. .$this->div_c();
  941. }
  942. $r .= $this->td_c();
  943. }
  944. $r .= $this->tr_c().
  945. $this->table_c().
  946. $this->nl(2);
  947. return $r;
  948. }
  949. /* END */
  950. /** -------------------------------------
  951. /** This keeps the quick tab text OK
  952. /** -------------------------------------*/
  953. function clean_tab_text($str = '')
  954. {
  955. if ($str == '')
  956. return '';
  957. $str = str_replace(' ', NBS, $str);
  958. $str = str_replace('"', '&quot;', $str);
  959. $str = str_replace("'", "&#39;", $str);
  960. return $str;
  961. }
  962. /* END */
  963. /** -------------------------------------
  964. /** Content
  965. /** -------------------------------------*/
  966. function content($padding = FALSE)
  967. {
  968. $this->secure_hash();
  969. if ($padding === TRUE)
  970. {
  971. $this->body = $this->qdiv('itemWrapperTop', $this->body);
  972. }
  973. if ($this->crumbline == FALSE)
  974. {
  975. return NL."<div id='contentNB'>".$this->nl(2).$this->body.$this->nl(2);
  976. }
  977. else
  978. {
  979. return NL."<div id='content'>".$this->nl(2).$this->body.$this->nl(2);
  980. }
  981. }
  982. /* END */
  983. /** -------------------------------------
  984. /** Secure Hash
  985. /** -------------------------------------*/
  986. function secure_hash($str = '')
  987. {
  988. global $IN, $FNS, $DB, $PREFS;
  989. $check = ($str != '') ? $str : $this->body;
  990. if ($PREFS->ini('secure_forms') == 'y' && preg_match_all("/<form.*?>/", $check, $matches)) // <?php fixex BBEdit display bug
  991. {
  992. $sql = "INSERT INTO exp_security_hashes (date, ip_address, hash) VALUES ";
  993. for($i=0, $s=sizeof($matches['0']); $i < $s; ++$i)
  994. {
  995. $hash = $FNS->random('encrypt');
  996. $sql .= "(UNIX_TIMESTAMP(), '".$IN->IP."', '".$hash."'),";
  997. $check = str_replace($matches['0'][$i], $matches['0'][$i].NL.$this->input_hidden('XID', $hash), $check);
  998. }
  999. $check = str_replace('{XID_SECURE_HASH}', $hash, $check);
  1000. $DB->query(substr($sql,0,-1));
  1001. }
  1002. if ($str != '')
  1003. {
  1004. return $check;
  1005. }
  1006. else
  1007. {
  1008. $this->body = $check;
  1009. }
  1010. }
  1011. /* END */
  1012. /** -------------------------------------
  1013. /** Crumb Builder
  1014. /** -------------------------------------*/
  1015. // This function lets us build crumbs. It can receive either a string or an array.
  1016. // If you pass it an array the key must be the name of the crumb and the value
  1017. // must be the URL where the crumb points. If the value is blank only the text will appear.
  1018. // EXAMPLE:
  1019. /*
  1020. $crumbs = array(
  1021. 'Forum' => BASE.AMP.'C=modules'.AMP.'M=forum',
  1022. 'Forum Manager => BASE.AMP.'C=modules'.AMP.'M=forum'.AMP.'P=forum_manager',
  1023. 'Categories' => ''
  1024. );
  1025. $DSP->crumb = $DSP->build_crumb($crumbs);
  1026. The above would produce:
  1027. <a href="bla...">Forum</a> > <a href="bla..">Forum Manager</a> > Cateogories
  1028. */
  1029. function build_crumb($crumbs = '')
  1030. {
  1031. if ($crumbs == '')
  1032. {
  1033. return '';
  1034. }
  1035. if ( ! is_array($crumbs))
  1036. {
  1037. return $this->crumb_item($crumbs);
  1038. }
  1039. if (count($crumbs) == 0)
  1040. return '';
  1041. $str = '';
  1042. foreach ($crumbs as $key => $val)
  1043. {
  1044. if ($val == '')
  1045. {
  1046. $str .= $this->crumb_item($key);
  1047. }
  1048. else
  1049. {
  1050. $str .= $this->crumb_item($this->anchor($val, $key));
  1051. }
  1052. }
  1053. return $str;
  1054. }
  1055. /* END */
  1056. /** -------------------------------------
  1057. /** Breadcrumb
  1058. /** -------------------------------------*/
  1059. function breadcrumb()
  1060. {
  1061. global $IN, $PREFS, $SESS, $LANG;
  1062. if ($this->show_crumb == FALSE)
  1063. {
  1064. return;
  1065. }
  1066. if ($PREFS->ini('multiple_sites_enabled') == 'y')
  1067. {
  1068. if ($C = $IN->GBL('C'))
  1069. {
  1070. $link = $this->anchor(BASE, $this->html_attribute_prep($PREFS->ini('site_name')));
  1071. }
  1072. else
  1073. {
  1074. $link = $this->anchor(BASE, $this->html_attribute_prep($PREFS->ini('site_name'))).$this->nbs(2)."&#8250;".$this->nbs(2).$LANG->line('main_menu');
  1075. }
  1076. }
  1077. else
  1078. {
  1079. $C = $IN->GBL('C');
  1080. $link = $this->anchor(BASE, $LANG->line('main_menu'));
  1081. }
  1082. if ($IN->GBL('class_override', 'GET') != '')
  1083. {
  1084. $C = $IN->GBL('class_override', 'GET') ;
  1085. }
  1086. // If the "M" variable exists in the GET query string, turn
  1087. // the variable into the next segment of the breadcrumb
  1088. if ($IN->GBL('M') AND $this->crumb_ov == FALSE)
  1089. {
  1090. // The $special variable let's us add additional data to the query string
  1091. // There are a few occasions where this is necessary
  1092. $special = '';
  1093. if ($IN->GBL('weblog_id', 'POST'))
  1094. {
  1095. $special = AMP.'weblog_id='.$IN->GBL('weblog_id');
  1096. }
  1097. // Build the link
  1098. $name = ($C == 'templates') ? $LANG->line('design') : $LANG->line($C);
  1099. if (empty($name))
  1100. {
  1101. $name = ucfirst($C);
  1102. }
  1103. if ($C == 'myaccount')
  1104. {
  1105. if ($id = $IN->GBL('id', 'GP'))
  1106. {
  1107. if ($id != $SESS->userdata('member_id'))
  1108. {
  1109. $name = $LANG->line('user_account');
  1110. $special = AMP.'id='.$id;
  1111. }
  1112. else
  1113. {
  1114. $name = $LANG->line('my_account');
  1115. }
  1116. }
  1117. }
  1118. $link .= $this->nbs(2)."&#8250;".$this->nbs(2).$this->anchor(BASE.AMP.'C='.$C.$special, $name);
  1119. }
  1120. // $this->crumb indicates the page being currently viewed.
  1121. // It does not need to be a link.
  1122. if ($this->crumb != '')
  1123. {
  1124. $link .= $this->nbs(2)."&#8250;".$this->nbs(2).$this->crumb;
  1125. }
  1126. // This is the right side of the breadcrumb area.
  1127. $data = ($this->rcrumb == '') ? "&nbsp;" : $this->rcrumb;
  1128. if ($data == 'OFF')
  1129. {
  1130. $link = '&nbsp;';
  1131. $data = '&nbsp;';
  1132. }
  1133. // Define the breadcrump CSS. On all but the PUBLISH page we use the
  1134. // version of the breadcrumb that has a bottom border
  1135. if ($this->crumbline == TRUE)
  1136. {
  1137. $ret = "<div id='breadcrumb'>";
  1138. }
  1139. else
  1140. {
  1141. $ret = "<div id='breadcrumbNoLine'>";
  1142. }
  1143. $ret .= $this->table('', '0', '0', '100%');
  1144. $ret .= $this->tr();
  1145. $ret .= $this->table_qcell('crumbPad', $this->span('crumblinks').$link.$this->span_c());
  1146. $ret .= $this->table_qcell($this->rcrumb_css, $data, '270px', 'bottom', 'right');
  1147. $ret .= $this->tr_c();
  1148. $ret .= $this->table_c();
  1149. $ret .= $this->div_c();
  1150. return $ret;
  1151. }
  1152. /* END */
  1153. /** ---------------------------------------
  1154. /** Right Side Crumb
  1155. /** ---------------------------------------*/
  1156. function right_crumb($title, $url = '', $extra = '', $pop = FALSE)
  1157. {
  1158. if ($title == '')
  1159. {
  1160. return;
  1161. }
  1162. $nj = '';
  1163. if ($url != '')
  1164. {
  1165. if ($pop === FALSE)
  1166. {
  1167. $nj = ' onclick="navjump(\''.$url.'\');this.blur();" ';
  1168. }
  1169. else
  1170. {
  1171. $nj = " onclick=\"window.open('{$url}', '_blank');return false;\" ";
  1172. }
  1173. }
  1174. $js = $nj.$extra.' onmouseover="navCrumbOn();" onmouseout="navCrumbOff();" ';
  1175. if ($url != '')
  1176. {
  1177. $this->rcrumb = $this->anchor($url, '<span class="crumblinksR" id="rcrumb" '.$js.'>'.$title.'</span>');
  1178. }
  1179. else
  1180. {
  1181. $this->rcrumb = $this->anchor('javascript:nullo();', '<span class="crumblinksR" id="rcrumb" '.$js.'>'.$title.'</span>');
  1182. }
  1183. }
  1184. /* END */
  1185. /** ---------------------------------------
  1186. /** Adds "breadcrum" formatting to an item
  1187. /** ---------------------------------------*/
  1188. function crumb_item($item)
  1189. {
  1190. return $this->nbs(2)."&#8250;".$this->nbs(2).$item;
  1191. }
  1192. /** -------------------------------------
  1193. /** Required field indicator
  1194. /** -------------------------------------*/
  1195. function required($blurb = '')
  1196. {
  1197. global $LANG;
  1198. if ($blurb == 1)
  1199. {
  1200. $blurb = "<span class='default'>".$this->nbs(2).$LANG->line('required_fields').'</span>';
  1201. }
  1202. elseif($blurb != '')
  1203. {
  1204. $blurb = "<span class='default'>".$this->nbs(2).$blurb.'</span>';
  1205. }
  1206. return "<span class='alert'>*</span>".$blurb.NL;
  1207. }
  1208. /* END */
  1209. /** -------------------------------------
  1210. /** Content closing </div> tag
  1211. /** -------------------------------------*/
  1212. function content_close()
  1213. {
  1214. return "</div>".NL;
  1215. }
  1216. /* END */
  1217. /** -------------------------------------
  1218. /** Copyright
  1219. /** -------------------------------------*/
  1220. function copyright()
  1221. {
  1222. global $LANG, $PREFS, $FNS, $DB;
  1223. $qm = ($PREFS->ini('force_query_string') == 'y') ? '' : '?';
  1224. $logo = '<img src="'.PATH_CP_IMG.'ee_logo_sm.gif" border="0" width="20" height="12" alt="ExpressionEngine" />';
  1225. $core = '';
  1226. $buyit = '';
  1227. if ( ! file_exists(PATH_MOD.'member/mod.member'.EXT))
  1228. {
  1229. $qm = ($PREFS->ini('force_query_string') == 'y') ? '' : '?';
  1230. $core = ' Core';
  1231. $buyit = 'Love EE Core? Consider '.$this->anchor($FNS->fetch_site_index().$qm.'URL=http://expressionengine.com/', 'buying').' a personal license!<br />';
  1232. }
  1233. $extra = '';
  1234. if (function_exists('memory_get_usage') && ($usage = memory_get_usage()) != '')
  1235. {
  1236. //$extra = ' &nbsp; '.number_format($usage/1024).' KB of Memory';
  1237. }
  1238. return
  1239. "<div class='copyright'>". $logo.$this->nl(2).$this->br().$this->nl().
  1240. $this->anchor($FNS->fetch_site_index().$qm.'URL=http://expressionengine.com/', APP_NAME.$core." ".APP_VER)." - &#169; ".$LANG->line('copyright')." 2003 - 2010 - EllisLab, Inc.".BR.NL.
  1241. $buyit.
  1242. str_replace("%x", "{cp:elapsed_time}", $LANG->line('page_rendered')).$this->nbs(3).
  1243. str_replace("%x", $DB->q_count, $LANG->line('queries_executed')).$extra.$this->br().
  1244. $LANG->line('build').$this->nbs(2).APP_BUILD.$this->nl(2).
  1245. "</div>".NL;
  1246. }
  1247. /* END */
  1248. /** -------------------------------------
  1249. /** HTML Footer
  1250. /** -------------------------------------*/
  1251. function html_footer()
  1252. {
  1253. return NL.'</body>'.NL.'</html>';
  1254. }
  1255. /* END */
  1256. /** -------------------------------------
  1257. /** Error Message
  1258. /** -------------------------------------*/
  1259. function error_message($message = "", $n = 1)
  1260. {
  1261. global $LANG;
  1262. $this->title = $LANG->line('error');
  1263. if (is_array($message))
  1264. {
  1265. $message = implode(BR, $message);
  1266. }
  1267. $this->crumbline = FALSE;
  1268. $this->body = $this->qdiv('alertHeadingCenter', $LANG->line('error'))
  1269. .$this->div('box')
  1270. .$this->div('defaultCenter')
  1271. .$this->qdiv('defaultBold', $message);
  1272. if ($n != 0)
  1273. $this->body .= BR.$this->nl(2)."<a href='javascript:history.go(-".$n.")' style='text-transform:uppercase;'>&#171; <b>".$LANG->line('back')."</b></a>";
  1274. $this->body .= BR.BR.$this->div_c().$this->div_c();
  1275. }
  1276. /* END */
  1277. /** -------------------------------------
  1278. /** Unauthorized access message
  1279. /** -------------------------------------*/
  1280. function no_access_message($message = '')
  1281. {
  1282. global $LANG;
  1283. $this->title = $LANG->line('unauthorized');
  1284. $msg = ($message == '') ? $LANG->line('unauthorized_access') : $message;
  1285. $this->body = $this->qdiv('highlight', BR.$msg);
  1286. }
  1287. /* END */
  1288. /** -------------------------------------
  1289. /** Global Javascript
  1290. /** -------------------------------------*/
  1291. function _global_javascript()
  1292. {
  1293. ob_start();
  1294. ?>
  1295. <script type="text/javascript">
  1296. <!--
  1297. var browser = "Unknown";
  1298. var version = "Unknown";
  1299. var OS = "Unknown";
  1300. var info = navigator.userAgent.toLowerCase();
  1301. var browsers = new Array();
  1302. browsers['safari'] = "Safari";
  1303. browsers['omniweb'] = "OmniWeb";
  1304. browsers['opera'] = "Opera";
  1305. browsers['webtv'] = "WebTV";
  1306. browsers['icab'] = "iCab";
  1307. browsers['konqueror'] = "Konqueror";
  1308. browsers['msie'] = "IE";
  1309. browsers['mozilla'] = "Mozilla";
  1310. for (b in browsers)
  1311. {
  1312. pos = info.indexOf(b) + 1;
  1313. if (pos != false)
  1314. {
  1315. browser = browsers[b];
  1316. version = info.charAt(pos + b.length);
  1317. break;
  1318. }
  1319. }
  1320. var systems = new Array();
  1321. systems['linux'] = "Linux";
  1322. systems['x11'] = "Unix";
  1323. systems['mac'] = "Mac";
  1324. systems['win'] = "Win";
  1325. for (s in systems)
  1326. {
  1327. pos = info.indexOf(s) + 1;
  1328. if (pos != false)
  1329. {
  1330. OS = systems[s];
  1331. break;
  1332. }
  1333. }
  1334. function navCrumbOn()
  1335. {
  1336. if (document.getElementById('rcrumb').className == 'crumblinksR')
  1337. {
  1338. document.getElementById('rcrumb').className = 'crumblinksRHover';
  1339. }
  1340. }
  1341. function navCrumbOff()
  1342. {
  1343. if (document.getElementById('rcrumb').className == 'crumblinksRHover')
  1344. {
  1345. document.getElementById('rcrumb').className = 'crumblinksR';
  1346. }
  1347. }
  1348. function navTabOn(link, idoff, idhover)
  1349. {
  1350. if ( ! idoff)
  1351. idoff = 'cpNavOff';
  1352. if ( ! idhover)
  1353. idhover = 'cpNavHover';
  1354. if (document.getElementById(link))
  1355. {
  1356. if (document.getElementById(link).className == idoff)
  1357. {
  1358. document.getElementById(link).className = idhover;
  1359. }
  1360. }
  1361. }
  1362. function navTabOff(link, idoff, idhover)
  1363. {
  1364. if ( ! idoff)
  1365. idoff = 'cpNavOff';
  1366. if ( ! idhover)
  1367. idhover = 'cpNavHover';
  1368. if (document.getElementById(link).className == idhover)
  1369. {
  1370. document.getElementById(link).className = idoff;
  1371. }
  1372. }
  1373. function navjump(where, pop)
  1374. {
  1375. if (browser != 'IE')
  1376. return false;
  1377. if (pop == 'true')
  1378. {
  1379. window.open(where, '_blank');
  1380. }
  1381. else
  1382. {
  1383. window.location=where;
  1384. }
  1385. }
  1386. //-->
  1387. </script>
  1388. <!--[if lt IE 7]>
  1389. <script language="JavaScript">
  1390. /*
  1391. /* Fix for PNG alpha transparency for Internet Explorer
  1392. /* Solution courtesy Bob Osola
  1393. /* http://homepage.ntlworld.com/bobosola/index.htm
  1394. */
  1395. function correctPNG() // correctly handle PNG transparency in Win IE 5.5 & 6.
  1396. {
  1397. var arVersion = navigator.appVersion.split("MSIE")
  1398. var version = parseFloat(arVersion[1])
  1399. if ((version >= 5.5) && (document.body.filters))
  1400. {
  1401. for(var i=0; i<document.images.length; i++)
  1402. {
  1403. var img = document.images[i]
  1404. var imgName = img.src.toUpperCase()
  1405. if (imgName.substring(imgName.length-3, imgName.length) == "PNG")
  1406. {
  1407. var imgID = (img.id) ? "id='" + img.id + "' " : ""
  1408. var imgClass = (img.className) ? "class='" + img.className + "' " : ""
  1409. var imgTitle = (img.title) ? "title='" + img.title + "' " : "title='" + img.alt + "' "
  1410. var imgStyle = "display:inline-block;" + img.style.cssText
  1411. if (img.align == "left") imgStyle = "float:left;" + imgStyle
  1412. if (img.align == "right") imgStyle = "float:right;" + imgStyle
  1413. if (img.parentElement.href) imgStyle = "cursor:hand;" + imgStyle
  1414. var strNewHTML = "<span " + imgID + imgClass + imgTitle
  1415. + " style=\"" + "width:" + img.width + "px; height:" + img.height + "px;" + imgStyle + ";"
  1416. + "filter:progid:DXImageTransform.Microsoft.AlphaImageLoader"
  1417. + "(src=\'" + img.src + "\', sizingMethod='scale');\"></span>"
  1418. img.outerHTML = strNewHTML
  1419. i = i-1
  1420. }
  1421. }
  1422. }
  1423. }
  1424. window.attachEvent("onload", correctPNG);
  1425. </script>
  1426. <![endif]-->
  1427. <?php
  1428. $out = ob_get_contents();
  1429. ob_end_clean();
  1430. return $out;
  1431. }
  1432. /* END */
  1433. /** -------------------------------------
  1434. /** Place-holder menu JS
  1435. /** -------------------------------------*/
  1436. function _menu_js()
  1437. {
  1438. ob_start();
  1439. ?>
  1440. <script type="text/javascript">
  1441. <!--
  1442. var menu = new Array();
  1443. function dropdownmenu(el)
  1444. {
  1445. if (document.getElementById(el).style.visibility == 'visible')
  1446. {
  1447. document.getElementById(el).style.display = 'none';
  1448. document.getElementById(el).style.visibility = 'hidden';
  1449. }
  1450. else
  1451. {
  1452. document.getElementById(el).style.display = 'block';
  1453. document.getElementById(el).style.visibility = 'visible';
  1454. }
  1455. }
  1456. function delayhidemenu(){
  1457. return false;
  1458. }
  1459. //-->
  1460. </script>
  1461. <?php
  1462. $out = ob_get_contents();
  1463. ob_end_clean();
  1464. return $out;
  1465. }
  1466. /* END */
  1467. /** -------------------------------------
  1468. /** Paginate
  1469. /** -------------------------------------*/
  1470. function pager($base_url = '', $total_count = '', $per_page = '', $cur_page = '', $qstr_var = '')
  1471. {
  1472. global $LANG;
  1473. // Instantiate the "paginate" class.
  1474. if ( ! class_exists('Paginate'))
  1475. {
  1476. require PATH_CORE.'core.paginate'.EXT;
  1477. }
  1478. $PGR = new Paginate();
  1479. $PGR->base_url = $base_url;
  1480. $PGR->total_count = $total_count;
  1481. $PGR->per_page = $per_page;
  1482. $PGR->cur_page = $cur_page;
  1483. $PGR->qstr_var = $qstr_var;
  1484. return $PGR->show_links();
  1485. }
  1486. /* END */
  1487. /** -------------------------------------
  1488. /** Delete Confirmation Wrapper
  1489. /** -------------------------------------*/
  1490. // Creates a standardized confirmation message used whenever
  1491. // something needs to be deleted. The prototype for this form is:
  1492. /*
  1493. $r = $DSP->delete_confirmation(
  1494. array(
  1495. 'url' => 'C=modules'.AMP.'P=delete_module_confirm',
  1496. 'heading' => 'delete_module_heading',
  1497. 'message' => 'delete_module_message,
  1498. 'item' => $module_name,
  1499. 'extra' => '',
  1500. 'hidden' => array('module_id' => $module_id)
  1501. )
  1502. );
  1503. */
  1504. function delete_confirmation($data = array())
  1505. {
  1506. global $LANG;
  1507. $vals = array('url', 'heading', 'message', 'item', 'hidden', 'extra');
  1508. foreach ($vals as $val)
  1509. {
  1510. if ( ! isset($data[$val]))
  1511. {
  1512. $data[$val] = '';
  1513. }
  1514. }
  1515. $r = $this->form_open(array('action' => $data['url']));
  1516. if (is_array($data['hidden']))
  1517. {
  1518. foreach ($data['hidden'] as $key => $val)
  1519. {
  1520. $r .= $this->input_hidden($key, $val);
  1521. }
  1522. }
  1523. $this->crumbline = FALSE;
  1524. $r .= $this->qdiv('alertHeading', $LANG->line($data['heading']))
  1525. .$this->div('box')
  1526. .$this->qdiv('itemWrapper', '<b>'.$LANG->line($data['message']).'</b>')
  1527. .$this->qdiv('itemWrapper', $this->qdiv('highlight_alt', $data['item']));
  1528. if ($data['extra'] != '')
  1529. {
  1530. $r .= $this->qdiv('itemWrapper', '<b>'.$LANG->line($data['extra']).'</b>');
  1531. }
  1532. $r .= $this->qdiv('itemWrapper', $this->qdiv('alert', $LANG->line('action_can_not_be_undone')))
  1533. .$this->qdiv('itemWrapperTop', $this->input_submit($LANG->line('delete')))
  1534. .$this->div_c()
  1535. .$this->form_close();
  1536. return $r;
  1537. }
  1538. /* END */
  1539. /** -------------------------------------
  1540. /** Div
  1541. /** -------------------------------------*/
  1542. function div($style='default', $align = '', $id = '', $name = '', $extra='')
  1543. {
  1544. if ($align != '')
  1545. $align = " align='{$align}'";
  1546. if ($id != '')
  1547. $id = " id='{$id}' ";
  1548. if ($name != '')
  1549. $name = " name='{$name}' ";
  1550. $extra = ' '.trim($extra);
  1551. return NL."<div class='{$style}'{$id}{$name}{$align}{$extra}>".NL;
  1552. }
  1553. /* END */
  1554. /** -------------------------------------
  1555. /** Div close
  1556. /** -------------------------------------*/
  1557. function div_c()
  1558. {
  1559. return NL."</div>".NL;
  1560. }
  1561. /* END */
  1562. /** -------------------------------------
  1563. /** Quick div
  1564. /** -------------------------------------*/
  1565. function qdiv($style='', $data = '', $id = '', $extra = '')
  1566. {
  1567. if ($style == '')
  1568. $style = 'default';
  1569. if ($id != '')
  1570. $id = " id='{$id}' ";
  1571. $extra = ' '.trim($extra);
  1572. return NL."<div class='{$style}'{$id}{$extra}>".$data.'</div>'.NL;
  1573. }
  1574. /* END */
  1575. /** -------------------------------------
  1576. /** Span
  1577. /** -------------------------------------*/
  1578. function span($style='default', $extra = '')
  1579. {
  1580. if ($extra != '')
  1581. $extra = ' '.$extra;
  1582. return "<span class='{$style}'{$extra}>".NL;
  1583. }
  1584. /* END */
  1585. /** -------------------------------------
  1586. /** Span close
  1587. /** -------------------------------------*/
  1588. function span_c($style='default')
  1589. {
  1590. return NL."</span>".NL;
  1591. }
  1592. /* END */
  1593. /** -------------------------------------
  1594. /** Quick span
  1595. /** -------------------------------------*/
  1596. function qspan($style='', $data = '', $id = '', $extra = '')
  1597. {
  1598. if ($style == '')
  1599. $style = 'default';
  1600. if ($id != '')
  1601. $id = " name = '{$id}' id='{$id}' ";
  1602. if ($extra != '')
  1603. $extra = ' '.$extra;
  1604. return NL."<span class='{$style}'{$id}{$extra}>".$data.'</span>'.NL;
  1605. }
  1606. /* END */
  1607. /** -------------------------------------
  1608. /** Heading
  1609. /** -------------------------------------*/
  1610. function heading($data = '', $h = '1')
  1611. {
  1612. return NL."<h".$h.">".$data."</h".$h.">".NL;
  1613. }
  1614. /* END */
  1615. /** -------------------------------------------
  1616. /** Anchor Tag
  1617. /** -------------------------------------------*/
  1618. function anchor($url, $name = "", $extra = '', $pop = FALSE)
  1619. {
  1620. if ($name == "" || $url == "")
  1621. return false;
  1622. if ($pop != FALSE)
  1623. {
  1624. $pop = " target=\"_blank\"";
  1625. }
  1626. $url .= $this->url_append;
  1627. return "<a href='{$url}' ".$extra.$pop.">$name</a>";
  1628. }
  1629. /* END */
  1630. /** -------------------------------------------
  1631. /** Anchor - pop-up version
  1632. /** -------------------------------------------*/
  1633. function anchorpop($url, $name, $width='500', $height='480')
  1634. {
  1635. return "<a href='javascript:nullo();' onclick=\"window.open('{$url}', '_blank', 'width={$width},height={$height},scrollbars=yes,status=yes,screenx=0,screeny=0,resizable=yes'); return false;\">$name</a>";
  1636. }
  1637. /* END */
  1638. /** -------------------------------------------
  1639. /** Anchor - pop-up version - full page
  1640. /** -------------------------------------------*/
  1641. function pagepop($url, $name)
  1642. {
  1643. return "<a href='#' onclick=\"window.open('{$url}', '_blank');return false;\">$name</a>";
  1644. }
  1645. /* END */
  1646. /** -------------------------------------------
  1647. /** Mailto Tag
  1648. /** -------------------------------------------*/
  1649. function mailto($email, $name = "")
  1650. {
  1651. if ($name == "") $name = $email;
  1652. return "<a href='mailto:{$email}'>$name</a>";
  1653. }
  1654. /* END */
  1655. /** -------------------------------------------
  1656. /** <br /> Tags
  1657. /** -------------------------------------------*/
  1658. function br($num = 1)
  1659. {
  1660. return str_repeat("<br />\n", $num);
  1661. }
  1662. /* END */
  1663. /** -------------------------------------------
  1664. /** "quick" <br /> tag with <div>
  1665. /** -------------------------------------------*/
  1666. function qbr($num = 1)
  1667. {
  1668. return NL.'<div>'.str_repeat("<br />\n", $num).'</div>'.NL;
  1669. }
  1670. /* END */
  1671. /** -------------------------------------------
  1672. /** Item group
  1673. /** -------------------------------------------*/
  1674. function itemgroup($top = '', $bottom = '')
  1675. {
  1676. return $this->div('itemWrapper').
  1677. $this->qdiv('itemTitle', $top).
  1678. $bottom.
  1679. $this->div_c();
  1680. }
  1681. /* END */
  1682. /** -------------------------------------------
  1683. /** Newline characters
  1684. /** -------------------------------------------*/
  1685. function nl($num = 1)
  1686. {
  1687. return str_repeat("\n", $num);
  1688. }
  1689. /* END */
  1690. /** -------------------------------------------
  1691. /** &nbsp; entity
  1692. /** -------------------------------------------*/
  1693. function nbs($num = 1)
  1694. {
  1695. return str_repeat("&nbsp;", $num);
  1696. }
  1697. /* END */
  1698. /** -------------------------------------------
  1699. /** Table open
  1700. /** -------------------------------------------*/
  1701. function table_open($props = array())
  1702. {
  1703. $str = '';
  1704. foreach ($props as $key => $val)
  1705. {
  1706. if ($key == 'width')
  1707. {
  1708. $str .= " style='width:{$val};' ";
  1709. }
  1710. else
  1711. {
  1712. $str .= " {$key}='{$val}' ";
  1713. }
  1714. }
  1715. $required = array('cellspacing' => '0', 'cellpadding' => '0', 'border' => '0');
  1716. foreach ($required as $key => $val)
  1717. {
  1718. if ( ! isset($props[$key]))
  1719. {
  1720. $str .= " {$key}='{$val}' ";
  1721. }
  1722. }
  1723. return "<table{$str}>".NL;
  1724. }
  1725. /* END */
  1726. /** -------------------------------------------
  1727. /** Table Row
  1728. /** -------------------------------------------*/
  1729. function table_row($array = array())
  1730. {
  1731. $params = '';
  1732. $content = '';
  1733. $end_row = FALSE;
  1734. $str = "<tr>".NL;
  1735. foreach($array as $key => $val)
  1736. {
  1737. if (is_array($val))
  1738. {
  1739. $params = '';
  1740. $content = '';
  1741. foreach($val as $k => $v)
  1742. {
  1743. if ($k == 'width')
  1744. {
  1745. $params .= " style='width:{$v};'";
  1746. }
  1747. else
  1748. {
  1749. if ($k == 'text')
  1750. {
  1751. $content = $v;
  1752. }
  1753. else
  1754. {
  1755. $params .= " {$k}='{$v}'";
  1756. }
  1757. }
  1758. }
  1759. $str .= "<td".$params.">";
  1760. $str .= $content;
  1761. $str .= "</td>".NL;
  1762. }
  1763. else
  1764. {
  1765. $end_row = TRUE;
  1766. if ($key == 'width')
  1767. {
  1768. $params .= " style='width:{$val};'";
  1769. }
  1770. else
  1771. {
  1772. if ($key == 'text')
  1773. {
  1774. $content .= $val;
  1775. }
  1776. else
  1777. {
  1778. $params .= " {$key}='{$val}'";
  1779. }
  1780. }
  1781. }
  1782. }
  1783. if ($end_row == TRUE)
  1784. {
  1785. $str .= "<td".$params.">";
  1786. $str .= $content;
  1787. $str .= "</td>".NL;
  1788. }
  1789. $str .= "</tr>".NL;
  1790. return $str;
  1791. }
  1792. /* END */
  1793. /** -------------------------------------------
  1794. /** Table close
  1795. /** -------------------------------------------*/
  1796. function table_close($padding = FALSE)
  1797. {
  1798. $r = '</table>'.NL;
  1799. if ($padding !== FALSE)
  1800. {
  1801. $r .= $this->qdiv('defaultSmall', $padding);
  1802. }
  1803. return $r;
  1804. }
  1805. /* END */
  1806. /** -------------------------------------------
  1807. /** Form declaration - new version
  1808. /** -------------------------------------------*/
  1809. /* EXAMPLE:
  1810. The first parameter is an array containing the "action" and any other items that
  1811. are desired in the form opening. The second optional parameter is an array of hidden fields
  1812. $r = $DSP->form_open(
  1813. array(
  1814. 'action' => 'C=modules'.AMP.'M=forum',
  1815. 'method' => 'post',
  1816. 'name' => 'entryform',
  1817. 'id' => 'entryform'
  1818. ),
  1819. array(
  1820. 'member_id' => $mod_forum_id,
  1821. 'status' => $status
  1822. )
  1823. );
  1824. The above code will produce:
  1825. <form action="C=modules&M=forum" method="post" name="entryform" id="entryform" />
  1826. <input type="hidden" name="member_id" value="23" />
  1827. <input type="hidden" name="status" value="open" />
  1828. Notes:
  1829. The method in the first parameter is not required. It ommited it'll be set to "post".
  1830. If the first parameter does not contain an array it is assumed that it contains
  1831. the "action" and will be treated as such.
  1832. */
  1833. function form_open($data = '', $hidden = array())
  1834. {
  1835. global $REGX;
  1836. if ( ! is_array($data))
  1837. {
  1838. $data = array('action' => $data);
  1839. }
  1840. if ( ! isset($data['action']))
  1841. {
  1842. $data['action'] = '';
  1843. }
  1844. if ( ! isset($data['method']))
  1845. {
  1846. $data['method'] = 'post';
  1847. }
  1848. $str = '';
  1849. foreach ($data as $key => $val)
  1850. {
  1851. if ($key == 'action')
  1852. {
  1853. $str .= " {$key}='".BASE.AMP.$val.$this->url_append."'";
  1854. }
  1855. else
  1856. {
  1857. $str .= " {$key}='{$val}'";
  1858. }
  1859. }
  1860. $form = NL."<form{$str}>".NL;
  1861. if (count($hidden > 0))
  1862. {
  1863. foreach ($hidden as $key => $val)
  1864. {
  1865. $form .= "<div class='hidden'><input type='hidden' name='{$key}' value='".$REGX->form_prep($val)."' /></div>".NL;
  1866. }
  1867. }
  1868. return $form;
  1869. }
  1870. /* END */
  1871. /** -----------------------------------
  1872. /** Form close
  1873. /** -----------------------------------*/
  1874. function form_close()
  1875. {
  1876. return "</form>".NL;
  1877. }
  1878. /* END */
  1879. /** -------------------------------------------
  1880. /** Input - hidden
  1881. /** -------------------------------------------*/
  1882. function input_hidden($name, $value = '')
  1883. {
  1884. global $REGX;
  1885. if ( ! is_array($name))
  1886. {
  1887. return "<div class='hidden'><input type='hidden' name='{$name}' value='".$REGX->form_prep($value)."' /></div>".NL;
  1888. }
  1889. $form = '';
  1890. foreach ($name as $key => $val)
  1891. {
  1892. $form .= "<div class='hidden'><input type='hidden' name='{$key}' value='".$REGX->form_prep($val)."' /></div>".NL;
  1893. }
  1894. return $form;
  1895. }
  1896. /* END */
  1897. /** -------------------------------------------
  1898. /** Input - text
  1899. /** -------------------------------------------*/
  1900. function input_text($name, $value='', $size = '90', $maxl = '100', $style='input', $width='100%', $extra = '', $convert = FALSE, $text_direction = 'ltr')
  1901. {
  1902. global $REGX;
  1903. $text_direction = ($text_direction == 'rtl') ? " dir='rtl' " : " dir='ltr' ";
  1904. $value = ($convert == FALSE) ? $REGX->form_prep($value) : $REGX->form_prep($REGX->entities_to_ascii($value, FALSE));
  1905. $id = (stristr($extra, 'id=')) ? '' : "id='".str_replace(array('[',']'), '', $name)."'";
  1906. return "<input {$text_direction} style='width:{$width}' type='text' name='{$name}' {$id} value='".$value."' size='{$size}' maxlength='{$maxl}' class='{$style}' $extra />".NL;
  1907. }
  1908. /* END */
  1909. /** -------------------------------------------
  1910. /** Input - password
  1911. /** -------------------------------------------*/
  1912. function input_pass($name, $value='', $size = '20', $maxl = '100', $style='input', $width='100%', $text_direction = 'ltr')
  1913. {
  1914. $text_direction = ($text_direction == 'rtl') ? " dir='rtl' " : " dir='ltr' ";
  1915. $id = "id='".str_replace(array('[',']'), '', $name)."'";
  1916. return "<input {$text_direction} style='width:{$width}' type='password' name='{$name}' {$id} value='{$value}' size='{$size}' maxlength='{$maxl}' class='{$style}' />".NL;
  1917. }
  1918. /* END */
  1919. /** -------------------------------------------
  1920. /** Input - textarea
  1921. /** -------------------------------------------*/
  1922. function input_textarea($name, $value='', $rows = '20', $style='textarea', $width='100%', $extra = '', $convert = FALSE, $text_direction = 'ltr')
  1923. {
  1924. global $REGX;
  1925. $text_direction = ($text_direction == 'rtl') ? " dir='rtl' " : " dir='ltr' ";
  1926. $value = ($convert == FALSE) ? $REGX->form_prep($value) : $REGX->form_prep($REGX->entities_to_ascii($value, FALSE));
  1927. $id = (stristr($extra, 'id=')) ? '' : "id='".str_replace(array('[',']'), '', $name)."'";
  1928. return "<textarea {$text_direction} style='width:{$width};' name='{$name}' {$id} cols='90' rows='{$rows}' class='{$style}' $extra>".$value."</textarea>".NL;
  1929. }
  1930. /* END */
  1931. /** -------------------------------------------
  1932. /** Input - pulldown - header
  1933. /** -------------------------------------------*/
  1934. function input_select_header($name, $multi = '', $size=3, $width='', $extra='')
  1935. {
  1936. if ($multi != '')
  1937. $multi = " size='".$size."' multiple='multiple'";
  1938. if ($multi == '')
  1939. {
  1940. $class = 'select';
  1941. }
  1942. else
  1943. {
  1944. $class = 'multiselect';
  1945. if ($width == '')
  1946. {
  1947. $width = '45%';
  1948. }
  1949. }
  1950. if ($width != '')
  1951. {
  1952. $width = "style='width:".$width."'";
  1953. }
  1954. $extra = ($extra != '') ? ' '.trim($extra) : '';
  1955. return NL."<select name='{$name}' class='{$class}'{$multi} {$width}{$extra}>".NL;
  1956. }
  1957. /* END */
  1958. /** -------------------------------------------
  1959. /** Input - pulldown
  1960. /** -------------------------------------------*/
  1961. function input_select_option($value, $item, $selected = '', $extra='')
  1962. {
  1963. global $REGX;
  1964. $selected = ($selected != '') ? " selected='selected'" : '';
  1965. $extra = ($extra != '') ? " ".trim($extra)." " : '';
  1966. return "<option value='".$value."'".$selected.$extra.">".$item."</option>".NL;
  1967. }
  1968. /* END */
  1969. /** -------------------------------------------
  1970. /** Input - pulldown - footer
  1971. /** -------------------------------------------*/
  1972. function input_select_footer()
  1973. {
  1974. return "</select>".NL;
  1975. }
  1976. /* END */
  1977. /** -------------------------------------------
  1978. /** Input - checkbox
  1979. /** -------------------------------------------*/
  1980. function input_checkbox($name, $value='', $checked = '', $extra = '')
  1981. {
  1982. $checked = ($checked == '' || $checked == 'n') ? '' : "checked='checked'";
  1983. return "<input class='checkbox' type='checkbox' name='{$name}' value='{$value}' {$checked}{$extra} />".NL;
  1984. }
  1985. /* END */
  1986. /** -------------------------------------------
  1987. /** Input - radio buttons
  1988. /** -------------------------------------------*/
  1989. function input_radio($name, $value='', $checked = 0, $extra = '')
  1990. {
  1991. $checked = ($checked == 0) ? '' : "checked='checked'";
  1992. return "<input class='radio' type='radio' name='{$name}' value='{$value}' {$checked}{$extra} />".NL;
  1993. }
  1994. /* END */
  1995. /** -------------------------------------------
  1996. /** Input - submit
  1997. /** -------------------------------------------*/
  1998. function input_submit($value='', $name = '', $extra='')
  1999. {
  2000. global $LANG;
  2001. $value = ($value == '') ? $LANG->line('submit') : $value;
  2002. $name = ($name == '') ? '' : "name='".$name."'";
  2003. if ($extra != '')
  2004. $extra = ' '.$extra.' ';
  2005. return NL."<input $name type='submit' class='submit' value='{$value}' {$extra} />".NL;
  2006. }
  2007. /* END */
  2008. /** -------------------------------------------
  2009. /** Magic Checkboxes for Rows
  2010. /** -------------------------------------------*/
  2011. function magic_checkboxes()
  2012. {
  2013. ob_start();
  2014. ?>
  2015. <script type="text/javascript">
  2016. <!--
  2017. var lastChecked = '';
  2018. function magic_check()
  2019. {
  2020. var listTable = document.getElementById('target').getElementsByTagName("table")[0];
  2021. var listTRs = listTable.getElementsByTagName("tr");
  2022. for (var j = 0; j < listTRs.length; j++)
  2023. {
  2024. var elements = listTRs[j].getElementsByTagName("td");
  2025. for ( var i = 0; i < elements.length; i++ )
  2026. {
  2027. elements[i].onclick = function (e) {
  2028. e = (e) ? e : ((window.event) ? window.event : "")
  2029. var element = e.target || e.srcElement;
  2030. var tag = element.tagName ? element.tagName.toLowerCase() : null;
  2031. // Last chance
  2032. if (tag == null)
  2033. {
  2034. element = element.parentNode;
  2035. tag = element.tagName ? element.tagName.toLowerCase() : null;
  2036. }
  2037. if (tag != 'a' && tag != null)
  2038. {
  2039. while (element.tagName.toLowerCase() != 'tr')
  2040. {
  2041. element = element.parentNode;
  2042. if (element.tagName.toLowerCase() == 'a') return;
  2043. }
  2044. var theTDs = element.getElementsByTagName("td");
  2045. var theInputs = element.getElementsByTagName("input");
  2046. var entryID = false;
  2047. var toggleFlag = false;
  2048. for ( var k = 0; k < theInputs.length; k++ )
  2049. {
  2050. if (theInputs[k].type == "checkbox")
  2051. {
  2052. if (theInputs[k].name == 'toggleflag')
  2053. {
  2054. toggleFlag = true;
  2055. }
  2056. else
  2057. {
  2058. entryID = theInputs[k].id;
  2059. }
  2060. break;
  2061. }
  2062. }
  2063. if (entryID == false && toggleFlag == false) return;
  2064. // Select All Checkbox
  2065. if (toggleFlag == true)
  2066. {
  2067. if (tag != 'input')
  2068. {
  2069. return;
  2070. }
  2071. var listTable = document.getElementById('target').getElementsByTagName("table")[0];
  2072. var listTRs = listTable.getElementsByTagName("tr");
  2073. for (var j = 1; j < listTRs.length; j++)
  2074. {
  2075. var elements = listTRs[j].getElementsByTagName("td");
  2076. for ( var t = 0; t < elements.length; t++ )
  2077. {
  2078. if (theInputs[k].checked == true)
  2079. {
  2080. elements[t].className = (elements[t].className == 'tableCellOne') ? 'tableCellTwoHover' : 'tableCellOneHover';
  2081. }
  2082. else
  2083. {
  2084. elements[t].className = (elements[t].className == 'tableCellOneHover') ? 'tableCellOne' : 'tableCellTwo';
  2085. }
  2086. }
  2087. }
  2088. }
  2089. else
  2090. {
  2091. if (tag != 'input')
  2092. {
  2093. document.getElementById(entryID).checked = (document.getElementById(entryID).checked ? false : true);
  2094. }
  2095. // Unselect any selected text on screen
  2096. // Safari does not have this ability, which sucks
  2097. // so I just did a focus();
  2098. if (document.getSelection) { window.getSelection().removeAllRanges(); }
  2099. else if (document.selection) { document.selection.empty(); }
  2100. else { document.getElementById(entryID).focus(); }
  2101. for ( var t = 0; t < theTDs.length; t++ )
  2102. {
  2103. if (document.getElementById(entryID).checked == true)
  2104. {
  2105. theTDs[t].className = (theTDs[t].className == 'tableCellOne') ? 'tableCellTwoHover' : 'tableCellOneHover';
  2106. }
  2107. else
  2108. {
  2109. theTDs[t].className = (theTDs[t].className == 'tableCellOneHover') ? 'tableCellOne' : 'tableCellTwo';
  2110. }
  2111. }
  2112. if (e.shiftKey && lastChecked != '')
  2113. {
  2114. shift_magic_check(document.getElementById(entryID).checked, lastChecked, element);
  2115. }
  2116. lastChecked = element;
  2117. }
  2118. }
  2119. }
  2120. }
  2121. }
  2122. }
  2123. function shift_magic_check(whatSet, lastChecked, current)
  2124. {
  2125. var outerElement = current.parentNode;
  2126. var outerTag = outerElement.tagName ? outerElement.tagName.toLowerCase() : null;
  2127. if (outerTag == null)
  2128. {
  2129. outerElement = outerElement.parentNode;
  2130. outerTag = outerElement.tagName ? outerElement.tagName.toLowerCase() : null;
  2131. }
  2132. if (outerTag != null)
  2133. {
  2134. while (outerElement.tagName.toLowerCase() != 'table')
  2135. {
  2136. outerElement = outerElement.parentNode;
  2137. }
  2138. var listTRs = outerElement.getElementsByTagName("tr");
  2139. var start = false;
  2140. for (var j = 1; j < listTRs.length; j++)
  2141. {
  2142. if (start == false && listTRs[j] != lastChecked && listTRs[j] != current)
  2143. {
  2144. continue;
  2145. }
  2146. var listTDs = listTRs[j].getElementsByTagName("td");
  2147. var listInputs = listTRs[j].getElementsByTagName("input");
  2148. var entryID = false;
  2149. for ( var k = 0; k < listInputs.length; k++ )
  2150. {
  2151. if (listInputs[k].type == "checkbox")
  2152. {
  2153. entryID = listInputs[k].id;
  2154. }
  2155. }
  2156. if (entryID == false || entryID == '') return;
  2157. document.getElementById(entryID).checked = whatSet;
  2158. for ( var t = 0; t < listTDs.length; t++ )
  2159. {
  2160. if (whatSet == true)
  2161. {
  2162. listTDs[t].className = (listTDs[t].className == 'tableCellOne') ? 'tableCellTwoHover' : 'tableCellOneHover';
  2163. }
  2164. else
  2165. {
  2166. listTDs[t].className = (listTDs[t].className == 'tableCellOneHover') ? 'tableCellOne' : 'tableCellTwo';
  2167. }
  2168. }
  2169. if (listTRs[j] == lastChecked || listTRs[j] == current)
  2170. {
  2171. if (start == true) break;
  2172. if (start == false) start = true;
  2173. }
  2174. }
  2175. }
  2176. }
  2177. //-->
  2178. </script>
  2179. <?php
  2180. $buffer = ob_get_contents();
  2181. ob_end_clean();
  2182. return $buffer;
  2183. }
  2184. /* END */
  2185. /** -------------------------------------------
  2186. /** JavaScript checkbox toggle code
  2187. /** -------------------------------------------*/
  2188. // This lets us check/uncheck all checkboxes in a series
  2189. function toggle()
  2190. {
  2191. ob_start();
  2192. ?>
  2193. <script type="text/javascript">
  2194. <!--
  2195. function toggle(thebutton)
  2196. {
  2197. if (thebutton.checked)
  2198. {
  2199. val = true;
  2200. }
  2201. else
  2202. {
  2203. val = false;
  2204. }
  2205. var len = document.target.elements.length;
  2206. for (var i = 0; i < len; i++)
  2207. {
  2208. var button = document.target.elements[i];
  2209. var name_array = button.name.split("[");
  2210. if (name_array[0] == "toggle")
  2211. {
  2212. button.checked = val;
  2213. }
  2214. }
  2215. document.target.toggleflag.checked = val;
  2216. }
  2217. //-->
  2218. </script>
  2219. <?php
  2220. $buffer = ob_get_contents();
  2221. ob_end_clean();
  2222. return $buffer;
  2223. }
  2224. /* END */
  2225. // DEPRECATED DISPLAY FUNCTIONS
  2226. // ------------------------------------------------------------------------
  2227. // ------------------------------------------------------------------------
  2228. // At present we're still using these so they have to stay here.
  2229. // Once we've gone throgh the entire control panel and replaced these
  2230. // function calls with the new versions we can kill them.
  2231. function table($style='', $cellspacing='0', $cellpadding='0', $width='100%', $border='0', $align='')
  2232. {
  2233. $style = ($style != '') ? " class='{$style}' " : '';
  2234. $width = ($width != '') ? " style='width:{$width};' " : '';
  2235. $align = ($align != '') ? " align='{$align}' " : '';
  2236. if ($border == '') $border = 0;
  2237. if ($cellspacing == '') $cellspacing = 0;
  2238. if ($cellpadding == '') $cellpadding = 0;
  2239. return NL."<table border='{$border}' cellspacing='{$cellspacing}' cellpadding='{$cellpadding}'{$width}{$style}{$align}>".NL;
  2240. }
  2241. /* END */
  2242. /** -------------------------------------------
  2243. /** Table "quick" row
  2244. /** -------------------------------------------*/
  2245. function table_qrow($style='', $data = '', $auto_width = FALSE)
  2246. {
  2247. $width = '';
  2248. $style = ($style != '') ? " class='{$style}' " : '';
  2249. if (is_array($data))
  2250. {
  2251. if ($auto_width != FALSE AND count($data) > 1)
  2252. {
  2253. $width = floor(100/count($data)).'%';
  2254. }
  2255. $width = ($width != '') ? " style='width:{$width};' " : '';
  2256. $r = "<tr>";
  2257. foreach($data as $val)
  2258. {
  2259. $r .= "<td".$style.$width.">".
  2260. $val.
  2261. '</td>'.NL;
  2262. }
  2263. $r .= "</tr>".NL;
  2264. return $r;
  2265. }
  2266. else
  2267. {
  2268. return
  2269. "<tr>".
  2270. "<td".$style.$width.">".
  2271. $data.
  2272. '</td>'.NL.
  2273. "</tr>".NL;
  2274. }
  2275. }
  2276. /* END */
  2277. /** -------------------------------------------
  2278. /** Table "quick" cell
  2279. /** -------------------------------------------*/
  2280. function table_qcell($style = '', $data = '', $width = '', $valign = '', $align = '')
  2281. {
  2282. if (is_array($data))
  2283. {
  2284. $r = '';
  2285. foreach($data as $val)
  2286. {
  2287. $r .= $this->td($style, $width, '', '', $valign, $align).
  2288. $val.
  2289. $this->td_c();
  2290. }
  2291. return $r;
  2292. }
  2293. else
  2294. {
  2295. return
  2296. $this->td($style, $width, '', '', $valign, $align).
  2297. $data.
  2298. $this->td_c();
  2299. }
  2300. }
  2301. /* END */
  2302. /** -------------------------------------------
  2303. /** Table row start
  2304. /** -------------------------------------------*/
  2305. function tr($style='')
  2306. {
  2307. return "<tr>";
  2308. }
  2309. /* END */
  2310. /** -------------------------------------------
  2311. /** Table data cell
  2312. /** -------------------------------------------*/
  2313. function td($style='', $width='', $colspan='', $rowspan='', $valign = '', $align = '')
  2314. {
  2315. if ($style == '')
  2316. $style = 'default';
  2317. if ($style != 'none')
  2318. {
  2319. $style = " class='".$style."' ";
  2320. }
  2321. $width = ($width != '') ? " style='width:{$width};'" : '';
  2322. $colspan = ($colspan != '') ? " colspan='{$colspan}'" : '';
  2323. $rowspan = ($rowspan != '') ? " rowspan='{$rowspan}'" : '';
  2324. $valign = ($valign != '') ? " valign='{$valign}'" : '';
  2325. $align = ($align != '') ? " align='{$align}'" : '';
  2326. return $this->nl()."<td ".$style.$width.$colspan.$rowspan.$valign.$align.">".$this->nl();
  2327. }
  2328. /* END */
  2329. /** -------------------------------------------
  2330. /** Table cell close
  2331. /** -------------------------------------------*/
  2332. function td_c()
  2333. {
  2334. return $this->nl().'</td>';
  2335. }
  2336. /* END */
  2337. /** -------------------------------------------
  2338. /** Table row close
  2339. /** -------------------------------------------*/
  2340. function tr_c()
  2341. {
  2342. return $this->nl().'</tr>'.$this->nl();
  2343. }
  2344. /* END */
  2345. /** -------------------------------------------
  2346. /** Table close
  2347. /** -------------------------------------------*/
  2348. function table_c()
  2349. {
  2350. return '</table>'.$this->nl(2);
  2351. }
  2352. /* END */
  2353. /** -------------------------------------------
  2354. /** Form declaration -- old version
  2355. /** -------------------------------------------*/
  2356. function form($action, $name = '', $method = 'post', $extras = '')
  2357. {
  2358. if ($name != '')
  2359. $name = " name='{$name}' id='{$name}' ";
  2360. if ($method != '')
  2361. $method = 'post';
  2362. return $this->nl()."<form method='{$method}' ".$name." action='".BASE.AMP.$action.$this->url_append."' $extras>".$this->nl();
  2363. }
  2364. /* END */
  2365. /** -------------------------------------------
  2366. /** Form close
  2367. /** -------------------------------------------*/
  2368. function form_c()
  2369. {
  2370. return "</form>".NL;
  2371. }
  2372. // END DEPRECATED DISPLAY FUNCTIONS
  2373. // ------------------------------------------------------------------------
  2374. // ------------------------------------------------------------------------
  2375. /* -------------------------------------
  2376. /* Validate Weblog and Member Custom Fields
  2377. /*
  2378. /* Yes this method doesn't strictly have anything to do with
  2379. /* displaying anything, but here it will be available for use
  2380. /* in the control panel by anyone who needs it.
  2381. /* -------------------------------------*/
  2382. function invalid_custom_field_names()
  2383. {
  2384. $weblog_vars = array(
  2385. 'aol_im', 'author', 'author_id', 'avatar_image_height',
  2386. 'avatar_image_width', 'avatar_url', 'bday_d', 'bday_m',
  2387. 'bday_y', 'bio', 'comment_auto_path',
  2388. 'comment_entry_id_auto_path', 'comment_tb_total',
  2389. 'comment_total', 'comment_url_title_path', 'count',
  2390. 'edit_date', 'email', 'entry_date', 'entry_id',
  2391. 'entry_id_path', 'expiration_date', 'forum_topic_id',
  2392. 'gmt_edit_date', 'gmt_entry_date', 'icq', 'interests',
  2393. 'ip_address', 'location', 'member_search_path', 'month',
  2394. 'msn_im', 'occupation', 'permalink', 'photo_image_height',
  2395. 'photo_image_width', 'photo_url', 'profile_path',
  2396. 'recent_comment_date', 'relative_date', 'relative_url',
  2397. 'screen_name', 'signature', 'signature_image_height',
  2398. 'signature_image_url', 'signature_image_width', 'status',
  2399. 'switch', 'title', 'title_permalink', 'total_results',
  2400. 'trackback_total', 'trimmed_url', 'url',
  2401. 'url_as_email_as_link', 'url_or_email', 'url_or_email_as_author',
  2402. 'url_title', 'url_title_path', 'username', 'weblog',
  2403. 'weblog_id', 'yahoo_im', 'year'
  2404. );
  2405. $global_vars = array(
  2406. 'app_version', 'captcha', 'charset', 'current_time',
  2407. 'debug_mode', 'elapsed_time', 'email', 'embed', 'encode',
  2408. 'group_description', 'group_id', 'gzip_mode', 'hits',
  2409. 'homepage', 'ip_address', 'ip_hostname', 'lang', 'location',
  2410. 'member_group', 'member_id', 'member_profile_link', 'path',
  2411. 'private_messages', 'screen_name', 'site_index', 'site_name',
  2412. 'site_url', 'stylesheet', 'total_comments', 'total_entries',
  2413. 'total_forum_posts', 'total_forum_topics', 'total_queries',
  2414. 'username', 'webmaster_email', 'version'
  2415. );
  2416. $orderby_vars = array(
  2417. 'comment_total', 'date', 'edit_date', 'expiration_date',
  2418. 'most_recent_comment', 'random', 'screen_name', 'title',
  2419. 'url_title', 'username', 'view_count_four', 'view_count_one',
  2420. 'view_count_three', 'view_count_two'
  2421. );
  2422. return array_unique(array_merge($weblog_vars, $global_vars, $orderby_vars));
  2423. }
  2424. /* END */
  2425. /** -----------------------------------------------------------
  2426. /** Prepares text for use as an HTML attribute
  2427. /** -----------------------------------------------------------*/
  2428. // Prevents user-defined labels from breaking out of crucial HTML markup
  2429. //-----------------------------------------------------------
  2430. function html_attribute_prep($label, $quotes = ENT_QUOTES)
  2431. {
  2432. global $PREFS;
  2433. // to prevent a PHP warning, we need to check that their system charset is one
  2434. // that is accepted by htmlspecialchars(). Unlike the native function, however,
  2435. // we default to UTF-8 instead of ISO-8859-1 if it's not an available charset.
  2436. $charset = (in_array(strtoupper($PREFS->ini('charset')),
  2437. array(
  2438. 'ISO-8859-1', 'ISO8859-1',
  2439. 'ISO-8859-15', 'ISO8859-15',
  2440. 'UTF-8',
  2441. 'CP866', 'IBM866', '866',
  2442. 'CP1251', 'WINDOWS-1251', 'WIN-1251', '1251',
  2443. 'CP1252', 'WINDOWS-1252', '1252',
  2444. 'KOI8-R', 'KOI8-RU', 'KOI8R',
  2445. 'BIG5', '950',
  2446. 'GB2312', '936',
  2447. 'BIG5-HKSCS',
  2448. 'SHIFT_JIS', 'SJIS', '932',
  2449. 'EUC-JP', 'EUCJP'
  2450. )
  2451. )) ? $PREFS->ini('charset') : 'UTF-8';
  2452. return htmlspecialchars($label, $quotes, $charset);
  2453. }
  2454. /* END */
  2455. }
  2456. // END CLASS
  2457. ?>