options.php 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689
  1. <?php
  2. /**
  3. * options.php
  4. *
  5. * Functions needed to display the options pages.
  6. *
  7. * @copyright &copy; 1999-2006 The SquirrelMail Project Team
  8. * @license http://opensource.org/licenses/gpl-license.php GNU Public License
  9. * @version $Id$
  10. * @package squirrelmail
  11. * @subpackage prefs
  12. */
  13. /**********************************************/
  14. /* Define constants used in the options code. */
  15. /**********************************************/
  16. /* Define constants for the various option types. */
  17. define('SMOPT_TYPE_STRING', 0);
  18. define('SMOPT_TYPE_STRLIST', 1);
  19. define('SMOPT_TYPE_TEXTAREA', 2);
  20. define('SMOPT_TYPE_INTEGER', 3);
  21. define('SMOPT_TYPE_FLOAT', 4);
  22. define('SMOPT_TYPE_BOOLEAN', 5);
  23. define('SMOPT_TYPE_HIDDEN', 6);
  24. define('SMOPT_TYPE_COMMENT', 7);
  25. define('SMOPT_TYPE_FLDRLIST', 8);
  26. /* Define constants for the options refresh levels. */
  27. define('SMOPT_REFRESH_NONE', 0);
  28. define('SMOPT_REFRESH_FOLDERLIST', 1);
  29. define('SMOPT_REFRESH_ALL', 2);
  30. /* Define constants for the options size. */
  31. define('SMOPT_SIZE_TINY', 0);
  32. define('SMOPT_SIZE_SMALL', 1);
  33. define('SMOPT_SIZE_MEDIUM', 2);
  34. define('SMOPT_SIZE_LARGE', 3);
  35. define('SMOPT_SIZE_HUGE', 4);
  36. define('SMOPT_SIZE_NORMAL', 5);
  37. define('SMOPT_SAVE_DEFAULT', 'save_option');
  38. define('SMOPT_SAVE_NOOP', 'save_option_noop');
  39. /**
  40. * SquirrelOption: An option for SquirrelMail.
  41. *
  42. * @package squirrelmail
  43. * @subpackage prefs
  44. */
  45. class SquirrelOption {
  46. /**
  47. * The name of this setting
  48. * @var string
  49. */
  50. var $name;
  51. /**
  52. * The text that prefaces setting on the preferences page
  53. * @var string
  54. */
  55. var $caption;
  56. /**
  57. * The type of INPUT element
  58. *
  59. * See SMOPT_TYPE_* defines
  60. * @var integer
  61. */
  62. var $type;
  63. /**
  64. * Indicates if a link should be shown to refresh part
  65. * or all of the window
  66. *
  67. * See SMOPT_REFRESH_* defines
  68. * @var integer
  69. */
  70. var $refresh_level;
  71. /**
  72. * Specifies the size of certain input items
  73. *
  74. * See SMOPT_SIZE_* defines
  75. * @var integer
  76. */
  77. var $size;
  78. /**
  79. * Text that follows a text input or
  80. * select list input on the preferences page
  81. *
  82. * useful for indicating units, meanings of special values, etc.
  83. * @var string
  84. */
  85. var $trailing_text;
  86. /**
  87. * text displayed to the user
  88. *
  89. * Used with SMOPT_TYPE_COMMENT options
  90. * @var string
  91. */
  92. var $comment;
  93. /**
  94. * additional javascript or other code added to the user input
  95. * @var string
  96. */
  97. var $script;
  98. /**
  99. * script (usually Javascript) that will be placed after (outside of)
  100. * the INPUT tag
  101. * @var string
  102. */
  103. var $post_script;
  104. /**
  105. * The name of the Save Function for this option.
  106. * @var string
  107. */
  108. var $save_function;
  109. /* The various 'values' for this options. */
  110. /**
  111. * default/preselected value for this option
  112. * @var mixed
  113. */
  114. var $value;
  115. /**
  116. * new option value
  117. * @var mixed
  118. */
  119. var $new_value;
  120. /**
  121. * associative array, where each key is an actual input value
  122. * and the corresponding value is what is displayed to the user
  123. * for that list item in the drop-down list
  124. * @var array
  125. */
  126. var $possible_values;
  127. /**
  128. * disables html sanitizing.
  129. *
  130. * WARNING - don't use it, if user input is possible in option
  131. * or use own sanitizing functions. Currently works only with
  132. * SMOPT_TYPE_STRLIST.
  133. * @var bool
  134. */
  135. var $htmlencoded=false;
  136. /**
  137. * Controls folder list limits in SMOPT_TYPE_FLDRLIST widget.
  138. * See $flag argument in sqimap_mailbox_option_list() function.
  139. * @var string
  140. * @since 1.5.1
  141. */
  142. var $folder_filter='noselect';
  143. /**
  144. * Constructor function
  145. * @param string $name
  146. * @param string $caption
  147. * @param integer $type
  148. * @param integer $refresh_level
  149. * @param mixed $initial_value
  150. * @param array $possible_values
  151. * @param bool $htmlencoded
  152. */
  153. function SquirrelOption
  154. ($name, $caption, $type, $refresh_level, $initial_value = '', $possible_values = '', $htmlencoded = false) {
  155. /* Set the basic stuff. */
  156. $this->name = $name;
  157. $this->caption = $caption;
  158. $this->type = $type;
  159. $this->refresh_level = $refresh_level;
  160. $this->possible_values = $possible_values;
  161. $this->htmlencoded = $htmlencoded;
  162. $this->size = SMOPT_SIZE_MEDIUM;
  163. $this->trailing_text = '';
  164. $this->comment = '';
  165. $this->script = '';
  166. $this->post_script = '';
  167. //Check for a current value.
  168. if (isset($GLOBALS[$name])) {
  169. $this->value = $GLOBALS[$name];
  170. } else if (!empty($initial_value)) {
  171. $this->value = $initial_value;
  172. } else {
  173. $this->value = '';
  174. }
  175. /* Check for a new value. */
  176. if ( !sqgetGlobalVar("new_$name", $this->new_value, SQ_POST ) ) {
  177. $this->new_value = '';
  178. }
  179. /* Set the default save function. */
  180. if (($type != SMOPT_TYPE_HIDDEN) && ($type != SMOPT_TYPE_COMMENT)) {
  181. $this->save_function = SMOPT_SAVE_DEFAULT;
  182. } else {
  183. $this->save_function = SMOPT_SAVE_NOOP;
  184. }
  185. }
  186. /**
  187. * Set the value for this option.
  188. * @param mixed $value
  189. */
  190. function setValue($value) {
  191. $this->value = $value;
  192. }
  193. /**
  194. * Set the new value for this option.
  195. * @param mixed $new_value
  196. */
  197. function setNewValue($new_value) {
  198. $this->new_value = $new_value;
  199. }
  200. /**
  201. * Set the size for this option.
  202. * @param integer $size
  203. */
  204. function setSize($size) {
  205. $this->size = $size;
  206. }
  207. /**
  208. * Set the trailing_text for this option.
  209. * @param string $trailing_text
  210. */
  211. function setTrailingText($trailing_text) {
  212. $this->trailing_text = $trailing_text;
  213. }
  214. /**
  215. * Set the comment for this option.
  216. * @param string $comment
  217. */
  218. function setComment($comment) {
  219. $this->comment = $comment;
  220. }
  221. /**
  222. * Set the script for this option.
  223. * @param string $script
  224. */
  225. function setScript($script) {
  226. $this->script = $script;
  227. }
  228. /**
  229. * Set the "post script" for this option.
  230. * @param string $post_script
  231. */
  232. function setPostScript($post_script) {
  233. $this->post_script = $post_script;
  234. }
  235. /**
  236. * Set the save function for this option.
  237. * @param string $save_function
  238. */
  239. function setSaveFunction($save_function) {
  240. $this->save_function = $save_function;
  241. }
  242. /**
  243. * Set the trailing_text for this option.
  244. * @param string $folder_filter
  245. * @since 1.5.1
  246. */
  247. function setFolderFilter($folder_filter) {
  248. $this->folder_filter = $folder_filter;
  249. }
  250. /**
  251. * Creates fields on option pages according to option type
  252. *
  253. * Function that calls other createWidget* functions.
  254. * @return string html formated option field
  255. */
  256. function createHTMLWidget() {
  257. global $color;
  258. // Use new value if available
  259. if (!empty($this->new_value)) {
  260. $tempValue = $this->value;
  261. $this->value = $this->new_value;
  262. }
  263. /* Get the widget for this option type. */
  264. switch ($this->type) {
  265. case SMOPT_TYPE_STRING:
  266. $result = $this->createWidget_String();
  267. break;
  268. case SMOPT_TYPE_STRLIST:
  269. $result = $this->createWidget_StrList();
  270. break;
  271. case SMOPT_TYPE_TEXTAREA:
  272. $result = $this->createWidget_TextArea();
  273. break;
  274. case SMOPT_TYPE_INTEGER:
  275. $result = $this->createWidget_Integer();
  276. break;
  277. case SMOPT_TYPE_FLOAT:
  278. $result = $this->createWidget_Float();
  279. break;
  280. case SMOPT_TYPE_BOOLEAN:
  281. $result = $this->createWidget_Boolean();
  282. break;
  283. case SMOPT_TYPE_HIDDEN:
  284. $result = $this->createWidget_Hidden();
  285. break;
  286. case SMOPT_TYPE_COMMENT:
  287. $result = $this->createWidget_Comment();
  288. break;
  289. case SMOPT_TYPE_FLDRLIST:
  290. $result = $this->createWidget_FolderList();
  291. break;
  292. default:
  293. $result = '<font color="' . $color[2] . '">'
  294. . sprintf(_("Option Type '%s' Not Found"), $this->type)
  295. . '</font>';
  296. }
  297. /* Add the "post script" for this option. */
  298. $result .= $this->post_script;
  299. // put correct value back if need be
  300. if (!empty($this->new_value)) {
  301. $this->value = $tempValue;
  302. }
  303. /* Now, return the created widget. */
  304. return ($result);
  305. }
  306. /**
  307. * Create string field
  308. * @return string html formated option field
  309. */
  310. function createWidget_String() {
  311. switch ($this->size) {
  312. case SMOPT_SIZE_TINY:
  313. $width = 5;
  314. break;
  315. case SMOPT_SIZE_SMALL:
  316. $width = 12;
  317. break;
  318. case SMOPT_SIZE_LARGE:
  319. $width = 38;
  320. break;
  321. case SMOPT_SIZE_HUGE:
  322. $width = 50;
  323. break;
  324. case SMOPT_SIZE_NORMAL:
  325. default:
  326. $width = 25;
  327. }
  328. $result = "<input type=\"text\" name=\"new_$this->name\" value=\"" .
  329. htmlspecialchars($this->value) .
  330. "\" size=\"$width\" $this->script />$this->trailing_text\n";
  331. return ($result);
  332. }
  333. /**
  334. * Create selection box
  335. * @return string html formated selection box
  336. */
  337. function createWidget_StrList() {
  338. /* Begin the select tag. */
  339. $result = "<select name=\"new_$this->name\" $this->script>\n";
  340. /* Add each possible value to the select list. */
  341. foreach ($this->possible_values as $real_value => $disp_value) {
  342. /* Start the next new option string. */
  343. $new_option = '<option value="' .
  344. ($this->htmlencoded ? $real_value : htmlspecialchars($real_value)) . '"';
  345. /* If this value is the current value, select it. */
  346. if ($real_value == $this->value) {
  347. $new_option .= ' selected="selected"';
  348. }
  349. /* Add the display value to our option string. */
  350. $new_option .= '>' . ($this->htmlencoded ? $disp_value : htmlspecialchars($disp_value)) . "</option>\n";
  351. /* And add the new option string to our select tag. */
  352. $result .= $new_option;
  353. }
  354. /* Close the select tag and return our happy result. */
  355. $result .= "</select>$this->trailing_text\n";
  356. return ($result);
  357. }
  358. /**
  359. * Create folder selection box
  360. * @return string html formated selection box
  361. */
  362. function createWidget_FolderList() {
  363. $selected = array(strtolower($this->value));
  364. /* set initial value */
  365. $result = '';
  366. /* Add each possible value to the select list. */
  367. foreach ($this->possible_values as $real_value => $disp_value) {
  368. if ( is_array($disp_value) ) {
  369. /* For folder list, we passed in the array of boxes.. */
  370. $new_option = sqimap_mailbox_option_list(0, $selected, 0, $disp_value, $this->folder_filter);
  371. } else {
  372. /* Start the next new option string. */
  373. $new_option = '<option value="' . htmlspecialchars($real_value) . '"';
  374. /* If this value is the current value, select it. */
  375. if ($real_value == $this->value) {
  376. $new_option .= ' selected="selected"';
  377. }
  378. /* Add the display value to our option string. */
  379. $new_option .= '>' . htmlspecialchars($disp_value) . "</option>\n";
  380. }
  381. /* And add the new option string to our select tag. */
  382. $result .= $new_option;
  383. }
  384. if (empty($result)) {
  385. // string is displayed when interface can't build folder selection box
  386. return _("unavailable");
  387. } else {
  388. /* Begin the select tag. */
  389. $ret = "<select name=\"new_$this->name\" $this->script>\n";
  390. $ret.= $result;
  391. /* Close the select tag and return our happy result. */
  392. $ret.= "</select>\n";
  393. return ($ret);
  394. }
  395. }
  396. /**
  397. * Creates textarea
  398. * @return string html formated textarea field
  399. */
  400. function createWidget_TextArea() {
  401. switch ($this->size) {
  402. case SMOPT_SIZE_TINY: $rows = 3; $cols = 10; break;
  403. case SMOPT_SIZE_SMALL: $rows = 4; $cols = 30; break;
  404. case SMOPT_SIZE_LARGE: $rows = 10; $cols = 60; break;
  405. case SMOPT_SIZE_HUGE: $rows = 20; $cols = 80; break;
  406. case SMOPT_SIZE_NORMAL:
  407. default: $rows = 5; $cols = 50;
  408. }
  409. //FIXME: we need to change $this->script into $this->aExtraAttribs, and anyone who wants to add some javascript or other attributes to an options widget can put them in an array and pass them as extra attributes (key == attrib name, value == attrib value).... for now, this is the only place it is used, and there is no place in the code that text areas get extra attribs or javascript... in fact the only place that was using $this->script is include/options/display.php:200, so that's easy to change.... just have to go through this file and change all the places that use "script"
  410. $this->aExtraAttribs = array();
  411. return addTextArea('new_' . $this->name, $this->value, $cols, $rows, $this->aExtraAttribs);
  412. }
  413. /**
  414. * Creates field for integer
  415. *
  416. * Difference from createWidget_String is visible only when javascript is enabled
  417. * @return string html formated option field
  418. */
  419. function createWidget_Integer() {
  420. // add onChange javascript handler to a regular string widget
  421. // which will strip out all non-numeric chars
  422. if (checkForJavascript())
  423. return preg_replace('/\/>/', ' onChange="origVal=this.value; newVal=\'\'; '
  424. . 'for (i=0;i<origVal.length;i++) { if (origVal.charAt(i)>=\'0\' '
  425. . '&& origVal.charAt(i)<=\'9\') newVal += origVal.charAt(i); } '
  426. . 'this.value=newVal;" />', $this->createWidget_String());
  427. else
  428. return $this->createWidget_String();
  429. }
  430. /**
  431. * Creates field for floating number
  432. * Difference from createWidget_String is visible only when javascript is enabled
  433. * @return string html formated option field
  434. */
  435. function createWidget_Float() {
  436. // add onChange javascript handler to a regular string widget
  437. // which will strip out all non-numeric (period also OK) chars
  438. if (checkForJavascript())
  439. return preg_replace('/\/>/', ' onChange="origVal=this.value; newVal=\'\'; '
  440. . 'for (i=0;i<origVal.length;i++) { if ((origVal.charAt(i)>=\'0\' '
  441. . '&& origVal.charAt(i)<=\'9\') || origVal.charAt(i)==\'.\') '
  442. . 'newVal += origVal.charAt(i); } this.value=newVal;" />'
  443. , $this->createWidget_String());
  444. else
  445. return $this->createWidget_String();
  446. }
  447. /**
  448. * Creates radio field (yes/no)
  449. * @return string html formated radio field
  450. */
  451. function createWidget_Boolean() {
  452. /* Do the whole current value thing. */
  453. if ($this->value != SMPREF_NO) {
  454. $yes_chk = ' checked="checked"';
  455. $no_chk = '';
  456. } else {
  457. $yes_chk = '';
  458. $no_chk = ' checked="checked"';
  459. }
  460. /* Build the yes choice. */
  461. $yes_option = '<input type="radio" id="new_' . $this->name . '_yes" '
  462. . 'name="new_' . $this->name . '" value="' . SMPREF_YES . '"'
  463. . $yes_chk . ' ' . $this->script . ' />&nbsp;'
  464. . '<label for="new_'.$this->name.'_yes">' . _("Yes") . '</label>';
  465. /* Build the no choice. */
  466. $no_option = '<input type="radio" id="new_' . $this->name . '_no" '
  467. . 'name="new_' . $this->name . '" value="' . SMPREF_NO . '"'
  468. . $no_chk . ' ' . $this->script . ' />&nbsp;'
  469. . '<label for="new_'.$this->name.'_no">' . _("No") . '</label>';
  470. /* Build and return the combined "boolean widget". */
  471. $result = "$yes_option&nbsp;&nbsp;&nbsp;&nbsp;$no_option";
  472. return ($result);
  473. }
  474. /**
  475. * Creates hidden field
  476. * @return string html formated hidden input field
  477. */
  478. function createWidget_Hidden() {
  479. $result = '<input type="hidden" name="new_' . $this->name
  480. . '" value="' . htmlspecialchars($this->value)
  481. . '" ' . $this->script . ' />';
  482. return ($result);
  483. }
  484. /**
  485. * Creates comment
  486. * @return string comment
  487. */
  488. function createWidget_Comment() {
  489. $result = $this->comment;
  490. return ($result);
  491. }
  492. /**
  493. *
  494. */
  495. function save() {
  496. $function = $this->save_function;
  497. $function($this);
  498. }
  499. /**
  500. *
  501. */
  502. function changed() {
  503. return ($this->value != $this->new_value);
  504. }
  505. } /* End of SquirrelOption class*/
  506. /**
  507. * Saves option
  508. * @param object $option object that holds option name and new_value
  509. */
  510. function save_option($option) {
  511. if ( !sqgetGlobalVar('username', $username, SQ_SESSION ) ) {
  512. /* Can't save the pref if we don't have the username */
  513. return;
  514. }
  515. global $data_dir;
  516. setPref($data_dir, $username, $option->name, $option->new_value);
  517. }
  518. /**
  519. * save function that does not save
  520. * @param object $option
  521. */
  522. function save_option_noop($option) {
  523. /* Do nothing here... */
  524. }
  525. /**
  526. * Create hidden 'optpage' input field with value set by argument
  527. * @param string $optpage identification of option page
  528. * @return string html formated hidden input field
  529. */
  530. function create_optpage_element($optpage) {
  531. return create_hidden_element('optpage', $optpage);
  532. }
  533. /**
  534. * Create hidden 'optmode' input field with value set by argument
  535. * @param string $optmode
  536. * @return string html formated hidden input field
  537. */
  538. function create_optmode_element($optmode) {
  539. return create_hidden_element('optmode', $optmode);
  540. }
  541. /**
  542. * Create hidden field.
  543. * @param string $name field name
  544. * @param string $value field value
  545. * @return string html formated hidden input field
  546. */
  547. function create_hidden_element($name, $value) {
  548. $result = '<input type="hidden" '
  549. . 'name="' . $name . '" '
  550. . 'value="' . htmlspecialchars($value) . '" />';
  551. return ($result);
  552. }
  553. /**
  554. * @param array $optgrps
  555. * @param array $optvals
  556. * @return array
  557. */
  558. function create_option_groups($optgrps, $optvals) {
  559. /* Build a simple array with which to start. */
  560. $result = array();
  561. /* Create option group for each option group name. */
  562. foreach ($optgrps as $grpkey => $grpname) {
  563. $result[$grpkey] = array();
  564. $result[$grpkey]['name'] = $grpname;
  565. $result[$grpkey]['options'] = array();
  566. }
  567. /* Create a new SquirrelOption for each set of option values. */
  568. foreach ($optvals as $grpkey => $grpopts) {
  569. foreach ($grpopts as $optset) {
  570. /* Create a new option with all values given. */
  571. $next_option = new SquirrelOption(
  572. $optset['name'],
  573. $optset['caption'],
  574. $optset['type'],
  575. (isset($optset['refresh']) ? $optset['refresh'] : SMOPT_REFRESH_NONE),
  576. (isset($optset['initial_value']) ? $optset['initial_value'] : ''),
  577. (isset($optset['posvals']) ? $optset['posvals'] : ''),
  578. (isset($optset['htmlencoded']) ? $optset['htmlencoded'] : false)
  579. );
  580. /* If provided, set the size for this option. */
  581. if (isset($optset['size'])) {
  582. $next_option->setSize($optset['size']);
  583. }
  584. /* If provided, set the trailing_text for this option. */
  585. if (isset($optset['trailing_text'])) {
  586. $next_option->setTrailingText($optset['trailing_text']);
  587. }
  588. /* If provided, set the comment for this option. */
  589. if (isset($optset['comment'])) {
  590. $next_option->setComment($optset['comment']);
  591. }
  592. /* If provided, set the save function for this option. */
  593. if (isset($optset['save'])) {
  594. $next_option->setSaveFunction($optset['save']);
  595. }
  596. /* If provided, set the script for this option. */
  597. if (isset($optset['script'])) {
  598. $next_option->setScript($optset['script']);
  599. }
  600. /* If provided, set the "post script" for this option. */
  601. if (isset($optset['post_script'])) {
  602. $next_option->setPostScript($optset['post_script']);
  603. }
  604. /* If provided, set the folder_filter for this option. */
  605. if (isset($optset['folder_filter'])) {
  606. $next_option->setFolderFilter($optset['folder_filter']);
  607. }
  608. /* Add this option to the option array. */
  609. $result[$grpkey]['options'][] = $next_option;
  610. }
  611. }
  612. /* Return our resulting array. */
  613. return ($result);
  614. }
  615. // vim: et ts=4