Source for file options.php

Documentation is available at options.php

  1. <?php
  2. /**
  3. * options.php
  4. *
  5. * Functions needed to display the options pages.
  6. *
  7. * @copyright 1999-2020 The SquirrelMail Project Team
  8. * @license http://opensource.org/licenses/gpl-license.php GNU Public License
  9. * @version $Id: options.php 14840 2020年01月07日 07:42:38Z pdontthink $
  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 ('SMOPT_TYPE_FLDRLIST_MULTI', 9);
  27. define ('SMOPT_TYPE_EDIT_LIST', 10);
  28. define ('SMOPT_TYPE_EDIT_LIST_ASSOCIATIVE', 11);
  29. define ('SMOPT_TYPE_STRLIST_MULTI', 12);
  30. define ('SMOPT_TYPE_BOOLEAN_CHECKBOX', 13);
  31. define ('SMOPT_TYPE_BOOLEAN_RADIO', 14);
  32. define ('SMOPT_TYPE_STRLIST_RADIO', 15);
  33. define ('SMOPT_TYPE_SUBMIT', 16);
  34. define ('SMOPT_TYPE_INFO', 17);
  35. define ('SMOPT_TYPE_PASSWORD', 18);
  36. /* Define constants for the layout scheme for edit lists. */
  37. define ('SMOPT_EDIT_LIST_LAYOUT_LIST', 0);
  38. define ('SMOPT_EDIT_LIST_LAYOUT_SELECT', 1);
  39. /* Define constants for the options refresh levels. */
  40. define ('SMOPT_REFRESH_NONE', 0);
  41. define ('SMOPT_REFRESH_FOLDERLIST', 1);
  42. define ('SMOPT_REFRESH_ALL', 2);
  43. /* Define constants for the options size. */
  44. define ('SMOPT_SIZE_TINY', 0);
  45. define ('SMOPT_SIZE_SMALL', 1);
  46. define ('SMOPT_SIZE_MEDIUM', 2);
  47. define ('SMOPT_SIZE_LARGE', 3);
  48. define ('SMOPT_SIZE_HUGE', 4);
  49. define ('SMOPT_SIZE_NORMAL', 5);
  50. define ('SMOPT_SAVE_DEFAULT', 'save_option');
  51. define ('SMOPT_SAVE_NOOP', 'save_option_noop');
  52. /**
  53. * SquirrelOption: An option for Squirrelmail.
  54. *
  55. * This class is a work in progress. When complete, it will handle
  56. * presentation and saving of Squirrelmail user options in a simple,
  57. * streamline manner. Stay tuned for more stuff.
  58. *
  59. * Also, I'd like to ask that people leave this alone (mostly :) until
  60. * I get it a little further along. That should only be a day or two or
  61. * three. I will remove this message when it is ready for primetime usage.
  62. * @package squirrelmail
  63. */
  64. /* The basic stuff. */
  65. var $name ;
  66. var $caption ;
  67. var $type ;
  68. var $size ;
  69. var $comment ;
  70. var $script ;
  71. var $yes_text ;
  72. var $no_text ;
  73. /* The name of the Save Function for this option. */
  74. /* The various 'values' for this options. */
  75. var $value ;
  76. var $new_value ;
  77. var $htmlencoded=false;
  78. /**
  79. * Constructor (PHP5 style, required in some future version of PHP)
  80. */
  81. function __construct
  82. ($raw_option_array, $name, $caption, $type, $refresh_level, $initial_value = '', $possible_values = '', $htmlencoded = false) {
  83. /* Set the basic stuff. */
  84. $this->raw_option_array = $raw_option_array;
  85. $this->name = $name;
  86. $this->caption = $caption;
  87. $this->caption_wrap = TRUE;
  88. $this->type = $type;
  89. $this->refresh_level = $refresh_level;
  90. $this->possible_values = $possible_values;
  91. $this->htmlencoded = $htmlencoded;
  92. // FIXME: why isn't this set by default to NORMAL?
  93. $this->layout_type = 0;
  94. $this->comment = '';
  95. $this->script = '';
  96. $this->post_script = '';
  97. $this->trailing_text = '';
  98. $this->trailing_text_small = FALSE;
  99. $this->trailing_text_is_html = FALSE;
  100. $this->yes_text = '';
  101. $this->no_text = '';
  102. $this->use_add_widget = TRUE;
  103. $this->use_delete_widget = TRUE;
  104. $this->poss_value_folders = '';
  105. /* Check for a current value. */
  106. if (isset($GLOBALS[$name])) {
  107. $this->value = $GLOBALS[$name];
  108. // TODO: This code should be something more like the following, but who knows what would break if it was changed at this point
  109. // } else if (initial_value !== '') {
  110. } else if (!empty($initial_value)) {
  111. $this->value = $initial_value;
  112. } else {
  113. $this->value = '';
  114. }
  115. /* Check for a new value. */
  116. if ( !sqgetGlobalVar ("new_$name", $this->new_value , SQ_POST ) ) {
  117. $this->new_value = NULL;
  118. }
  119. /* Set the default save function. */
  120. if ($type != SMOPT_TYPE_HIDDEN
  121. && $type != SMOPT_TYPE_INFO
  122. && $type != SMOPT_TYPE_COMMENT ) {
  123. } else {
  124. }
  125. }
  126. /**
  127. * Constructor (PHP4 style, kept for compatibility reasons)
  128. */
  129. function SquirrelOption
  130. ($raw_option_array, $name, $caption, $type, $refresh_level, $initial_value = '', $possible_values = '', $htmlencoded = false) {
  131. self::__construct($raw_option_array, $name, $caption, $type, $refresh_level, $initial_value, $possible_values, $htmlencoded);
  132. }
  133. /** Convenience function that identifies which types of
  134. widgets are stored as (serialized) array values. */
  135. function is_multiple_valued () {
  136. return ($this->type == SMOPT_TYPE_FLDRLIST_MULTI
  137. || $this->type == SMOPT_TYPE_EDIT_LIST
  138. }
  139. /* Set the value for this option. */
  140. function setValue ($value) {
  141. $this->value = $value;
  142. }
  143. /* Set the new value for this option. */
  144. function setNewValue ($new_value) {
  145. $this->new_value = $new_value;
  146. }
  147. /* Set whether the caption is allowed to wrap for this option. */
  148. function setCaptionWrap ($caption_wrap) {
  149. $this->caption_wrap = $caption_wrap;
  150. }
  151. /* Set the size for this option. */
  152. function setSize ($size) {
  153. $this->size = $size;
  154. }
  155. /* Set the trailing text for this option. */
  156. function setTrailingText ($trailing_text) {
  157. $this->trailing_text = $trailing_text;
  158. }
  159. /* Set the trailing text for this option. */
  160. function setTrailingTextSmall ($trailing_text_small) {
  161. $this->trailing_text_small = $trailing_text_small;
  162. }
  163. /* Set the trailing text for this option. */
  164. function setTrailingTextIsHtml ($trailing_text_is_html) {
  165. $this->trailing_text_is_html = $trailing_text_is_html;
  166. }
  167. /* Set the yes text for this option. */
  168. function setYesText ($yes_text) {
  169. $this->yes_text = $yes_text;
  170. }
  171. /* Set the no text for this option. */
  172. function setNoText ($no_text) {
  173. $this->no_text = $no_text;
  174. }
  175. /* Set the "use add widget" value for this option. */
  176. function setUseAddWidget ($use_add_widget) {
  177. $this->use_add_widget = $use_add_widget;
  178. }
  179. /* Set the "use delete widget" value for this option. */
  180. function setUseDeleteWidget ($use_delete_widget) {
  181. $this->use_delete_widget = $use_delete_widget;
  182. }
  183. /* Set the "poss value folders" value for this option.
  184. See the associative edit list widget, which uses this
  185. to offer folder list selection for the values */
  186. function setPossValueFolders ($poss_value_folders) {
  187. $this->poss_value_folders = $poss_value_folders;
  188. }
  189. /* Set the layout type for this option. */
  190. function setLayoutType ($layout_type) {
  191. $this->layout_type = $layout_type;
  192. }
  193. /* Set the comment for this option. */
  194. function setComment ($comment) {
  195. $this->comment = $comment;
  196. }
  197. /* Set the script for this option. */
  198. function setScript ($script) {
  199. $this->script = $script;
  200. }
  201. /* Set the "post script" for this option. */
  202. function setPostScript ($post_script) {
  203. $this->post_script = $post_script;
  204. }
  205. /* Set the save function for this option. */
  206. function setSaveFunction ($save_function) {
  207. $this->save_function = $save_function;
  208. }
  209. function createHTMLWidget () {
  210. global $javascript_on, $color;
  211. // Use new value if available
  212. if (!is_null ($this->new_value )) {
  213. $tempValue = $this->value ;
  214. $this->value = $this->new_value ;
  215. }
  216. /* Get the widget for this option type. */
  217. switch ($this->type ) {
  218. $result = $this->createWidget_String ();
  219. break;
  220. $result = $this->createWidget_String (TRUE);
  221. break;
  222. $result = $this->createWidget_StrList ();
  223. break;
  224. $result = $this->createWidget_TextArea ();
  225. break;
  226. $result = $this->createWidget_Integer ();
  227. break;
  228. $result = $this->createWidget_Float ();
  229. break;
  230. $result = $this->createWidget_Boolean ();
  231. break;
  232. $result = $this->createWidget_Boolean (TRUE);
  233. break;
  234. $result = $this->createWidget_Boolean (FALSE);
  235. break;
  236. $result = $this->createWidget_Hidden ();
  237. break;
  238. $result = $this->createWidget_Comment ();
  239. break;
  240. $result = $this->createWidget_FolderList ();
  241. break;
  242. $result = $this->createWidget_FolderList (TRUE);
  243. break;
  244. $result = $this->createWidget_EditList ();
  245. break;
  246. $result = $this->createWidget_EditListAssociative ();
  247. break;
  248. $result = $this->createWidget_StrList (TRUE);
  249. break;
  250. $result = $this->createWidget_StrList (FALSE, TRUE);
  251. break;
  252. $result = $this->createWidget_Submit ();
  253. break;
  254. $result = $this->createWidget_Info ();
  255. break;
  256. default:
  257. $result = '<font color="' . $color[2] . '">'
  258. . sprintf (_ ("Option Type '%s' Not Found"), $this->type )
  259. . '</font>';
  260. }
  261. /* Add the "post script" for this option. */
  262. $result .= $this->post_script ;
  263. // put correct value back if need be
  264. if (!is_null ($this->new_value )) {
  265. $this->value = $tempValue;
  266. }
  267. /* Now, return the created widget. */
  268. return $result;
  269. }
  270. function createWidget_Info () {
  271. // $result = sm_encode_html_special_chars($this->value) . "\n";
  272. // like COMMENT, allow HTML here
  273. $result = $this->value . "\n";
  274. return $result;
  275. }
  276. /**
  277. * Create text box
  278. *
  279. * @param boolean $password When TRUE, the text in the input
  280. * widget will be obscured (OPTIONAL;
  281. * default = FALSE).
  282. *
  283. * @return string html formated text input
  284. *
  285. */
  286. function createWidget_String ($password=FALSE) {
  287. switch ($this->size ) {
  288. $width = 5;
  289. break;
  290. $width = 12;
  291. break;
  292. $width = 38;
  293. break;
  294. $width = 50;
  295. break;
  296. default:
  297. $width = 25;
  298. }
  299. $result = "<input type=\""
  300. . ($password ? 'password' : 'text')
  301. . "\" name=\"new_$this->name\" value=\""
  302. . "\" size=\"$width\" $this->script /> "
  303. . ($this->trailing_text_small ? '<small>' : '')
  304. . ($this->trailing_text_small ? '</small>' : '')
  305. . "\n";
  306. return $result;
  307. }
  308. /**
  309. * Create selection box or radio group
  310. *
  311. * When $this->htmlencoded is TRUE, the keys and values in
  312. * $this->possible_values are assumed to be display-safe.
  313. * Use with care!
  314. *
  315. * Note that when building radio buttons instead of a select
  316. * widget, if the "size" attribute is SMOPT_SIZE_TINY, the
  317. * radio buttons will be output one after another without
  318. * linebreaks between them. Otherwise, each radio button
  319. * goes on a line of its own.
  320. *
  321. * @param boolean $multiple_select When TRUE, the select widget
  322. * will allow multiple selections
  323. * (OPTIONAL; default is FALSE
  324. * (single select list))
  325. * @param boolean $radio_buttons When TRUE, the widget will
  326. * instead be built as a group
  327. * of radio buttons (and
  328. * $multiple_select will be
  329. * forced to FALSE) (OPTIONAL;
  330. * default is FALSE (select widget))
  331. *
  332. * @return string html formated selection box or radio buttons
  333. *
  334. */
  335. function createWidget_StrList ($multiple_select=FALSE, $radio_buttons=FALSE) {
  336. // radio buttons instead of select widget?
  337. //
  338. if ($radio_buttons) {
  339. $result = '';
  340. foreach ($this->possible_values as $real_value => $disp_value) {
  341. $result .= "\n" . '<input type="radio" name="new_' . $this->name
  342. . '" id="new_' . $this->name . '_'
  343. . ($this->htmlencoded ? $real_value : sm_encode_html_special_chars ($real_value))
  344. . '" value="'
  345. . ($this->htmlencoded ? $real_value : sm_encode_html_special_chars ($real_value))
  346. . '"' . ($real_value == $this->value ? ' checked="checked"' : '')
  347. . ' /> <label for="new_' . $this->name . '_'
  348. . ($this->htmlencoded ? $real_value : sm_encode_html_special_chars ($real_value))
  349. . '">'
  350. . ($this->htmlencoded ? $disp_value : sm_encode_html_special_chars ($disp_value))
  351. . '</label>';
  352. if ($this->size != SMOPT_SIZE_TINY )
  353. $result .= '<br />';
  354. }
  355. return $result;
  356. }
  357. // everything below applies to select widgets
  358. //
  359. switch ($this->size ) {
  360. //FIXME: not sure about these sizes... seems like we could add another on the "large" side...
  361. $height = 3;
  362. break;
  363. $height = 8;
  364. break;
  365. $height = 15;
  366. break;
  367. $height = 25;
  368. break;
  369. default:
  370. $height = 5;
  371. }
  372. // multiple select lists should already have array values
  373. if (is_array ($this->value ))
  374. $selected = $this->value ;
  375. else
  376. $selected = array(strtolower ($this->value ));
  377. /* Begin the select tag. */
  378. $result = '<select name="new_' . $this->name
  379. . ($multiple_select ? '[]" multiple="multiple" size="' . $height . '" ' : '" ')
  380. . $this->script . ">\n";
  381. /* Add each possible value to the select list. */
  382. foreach ($this->possible_values as $real_value => $disp_value) {
  383. /* Start the next new option string. */
  384. $new_option = '<option value="' .
  385. ($this->htmlencoded ? $real_value : sm_encode_html_special_chars ($real_value)) . '"';
  386. // multiple select lists have possibly more than one default selection
  387. if ($multiple_select) {
  388. foreach ($selected as $default) {
  389. if ((string)$default == (string)$real_value) {
  390. $new_option .= ' selected="selected"';
  391. break;
  392. }
  393. }
  394. }
  395. /* If this value is the current value, select it. */
  396. else if ($real_value == $this->value ) {
  397. $new_option .= ' selected="selected"';
  398. }
  399. /* Add the display value to our option string. */
  400. $new_option .= '>' . ($this->htmlencoded ? $disp_value : sm_encode_html_special_chars ($disp_value)) . "</option>\n";
  401. /* And add the new option string to our select tag. */
  402. $result .= $new_option;
  403. }
  404. /* Close the select tag and return our happy result. */
  405. $result .= '</select> '
  406. . ($this->trailing_text_small ? '<small>' : '')
  407. . ($this->trailing_text_small ? '</small>' : '')
  408. . "\n";
  409. return $result;
  410. }
  411. /**
  412. * Create folder selection box
  413. *
  414. * @param boolean $multiple_select When TRUE, the select widget
  415. * will allow multiple selections
  416. * (OPTIONAL; default is FALSE
  417. * (single select list))
  418. *
  419. * @return string html formated selection box
  420. *
  421. */
  422. function createWidget_FolderList ($multiple_select=FALSE) {
  423. switch ($this->size ) {
  424. //FIXME: not sure about these sizes... seems like we could add another on the "large" side...
  425. $height = 3;
  426. break;
  427. $height = 8;
  428. break;
  429. $height = 15;
  430. break;
  431. $height = 25;
  432. break;
  433. default:
  434. $height = 5;
  435. }
  436. // multiple select lists should already have array values
  437. if (is_array ($this->value ))
  438. $selected = $this->value ;
  439. else
  440. $selected = array(strtolower ($this->value ));
  441. /* Begin the select tag. */
  442. $result = '<select name="new_' . $this->name
  443. . ($multiple_select ? '[]" multiple="multiple" size="' . $height . '"' : '"')
  444. . " $this->script>\n";
  445. /* Add each possible value to the select list. */
  446. foreach ($this->possible_values as $real_value => $disp_value) {
  447. if ( is_array ($disp_value) ) {
  448. /* For folder list, we passed in the array of boxes.. */
  449. $selected_lowercase = array();
  450. foreach ($selected as $i => $box)
  451. $selected_lowercase[$i] = strtolower ($box);
  452. $new_option = sqimap_mailbox_option_list (0, $selected_lowercase, 0, $disp_value);
  453. } else {
  454. /* Start the next new option string. */
  455. $new_option = '<option value="' . sm_encode_html_special_chars ($real_value) . '"';
  456. // multiple select lists have possibly more than one default selection
  457. if ($multiple_select) {
  458. foreach ($selected as $default) {
  459. if ((string)$default == (string)$real_value) {
  460. $new_option .= ' selected="selected"';
  461. break;
  462. }
  463. }
  464. }
  465. /* If this value is the current value, select it. */
  466. else if ($real_value == $this->value ) {
  467. $new_option .= ' selected="selected"';
  468. }
  469. /* Add the display value to our option string. */
  470. $new_option .= '>' . sm_encode_html_special_chars ($disp_value) . "</option>\n";
  471. }
  472. /* And add the new option string to our select tag. */
  473. $result .= $new_option;
  474. }
  475. /* Close the select tag and return our happy result. */
  476. $result .= '</select> '
  477. . ($this->trailing_text_small ? '<small>' : '')
  478. . ($this->trailing_text_small ? '</small>' : '')
  479. . "\n";
  480. return $result;
  481. }
  482. function createWidget_TextArea () {
  483. switch ($this->size ) {
  484. case SMOPT_SIZE_TINY : $rows = 3; $cols = 10; break;
  485. case SMOPT_SIZE_SMALL : $rows = 4; $cols = 30; break;
  486. case SMOPT_SIZE_LARGE : $rows = 10; $cols = 60; break;
  487. case SMOPT_SIZE_HUGE : $rows = 20; $cols = 80; break;
  488. default: $rows = 5; $cols = 50;
  489. }
  490. $result = "<textarea name=\"new_$this->name\" rows=\"$rows\" "
  491. . "cols=\"$cols\" $this->script>\n"
  492. . sm_encode_html_special_chars ($this->value ) . "</textarea>\n";
  493. return ($result);
  494. }
  495. function createWidget_Integer () {
  496. global $javascript_on;
  497. // add onChange javascript handler to a regular string widget
  498. // which will strip out all non-numeric chars
  499. if ($javascript_on)
  500. return preg_replace ('/\/>/', ' onChange="origVal=this.value; newVal=\'\'; '
  501. . 'for (i=0;i<origVal.length;i++) { if (origVal.charAt(i)>=\'0\' '
  502. . '&& origVal.charAt(i)<=\'9\') newVal += origVal.charAt(i); } '
  503. . 'this.value=newVal;" />', $this->createWidget_String ());
  504. else
  505. return $this->createWidget_String ();
  506. }
  507. function createWidget_Float () {
  508. global $javascript_on;
  509. // add onChange javascript handler to a regular string widget
  510. // which will strip out all non-numeric (period also OK) chars
  511. if ($javascript_on)
  512. return preg_replace ('/\/>/', ' onChange="origVal=this.value; newVal=\'\'; '
  513. . 'for (i=0;i<origVal.length;i++) { if ((origVal.charAt(i)>=\'0\' '
  514. . '&& origVal.charAt(i)<=\'9\') || origVal.charAt(i)==\'.\') '
  515. . 'newVal += origVal.charAt(i); } this.value=newVal;" />'
  516. , $this->createWidget_String ());
  517. else
  518. return $this->createWidget_String ();
  519. }
  520. /**
  521. * Create boolean widget
  522. *
  523. * When creating Yes/No radio buttons, the "yes_text"
  524. * and "no_text" option attributes are used to override
  525. * the typical "Yes" and "No" text.
  526. *
  527. * @param boolean $checkbox When TRUE, the widget will be
  528. * constructed as a checkbox,
  529. * otherwise it will be a set of
  530. * Yes/No radio buttons (OPTIONAL;
  531. * default is TRUE (checkbox)).
  532. *
  533. * @return string html formated boolean widget
  534. *
  535. */
  536. function createWidget_Boolean ($checkbox=TRUE) {
  537. /* Do the whole current value thing. */
  538. if ($this->value != SMPREF_NO ) {
  539. $yes_chk = ' checked="checked"';
  540. $no_chk = '';
  541. } else {
  542. $yes_chk = '';
  543. $no_chk = ' checked="checked"';
  544. }
  545. // checkbox...
  546. //
  547. if ($checkbox) {
  548. $result = '<input type="checkbox" name="new_' . $this->name
  549. . '" id="new_' . $this->name . '" value="' . SMPREF_YES
  550. . "\" $yes_chk " . $this->script . ' />&nbsp;'
  551. . '<label for="new_' . $this->name . '">'
  552. . ($this->trailing_text_small ? '<small>' : '')
  553. . ($this->trailing_text_small ? '</small>' : '')
  554. . '</label>';
  555. }
  556. // radio buttons...
  557. //
  558. else {
  559. /* Build the yes choice. */
  560. $yes_option = '<input type="radio" name="new_' . $this->name
  561. . '" id="new_' . $this->name . '_yes"'
  562. . ' value="' . SMPREF_YES . "\"$yes_chk $this->script />&nbsp;"
  563. . '<label for="new_' . $this->name . '_yes">' . (!empty($this->yes_text ) ? sm_encode_html_special_chars ($this->yes_text ) : _ ("Yes")) . '</label>';
  564. /* Build the no choice. */
  565. $no_option = '<input type="radio" name="new_' . $this->name
  566. . '" id="new_' . $this->name . '_no"'
  567. . ' value="' . SMPREF_NO . "\"$no_chk $this->script />&nbsp;"
  568. . '<label for="new_' . $this->name . '_no">' . (!empty($this->no_text ) ? sm_encode_html_special_chars ($this->no_text ) : _ ("No")) . '</label>';
  569. /* Build the combined "boolean widget". */
  570. $result = "$yes_option&nbsp;&nbsp;&nbsp;&nbsp;$no_option "
  571. . ($this->trailing_text_small ? '<small>' : '')
  572. . ($this->trailing_text_small ? '</small>' : '');
  573. }
  574. return ($result);
  575. }
  576. function createWidget_Hidden () {
  577. $result = '<input type="hidden" name="new_' . $this->name
  578. . '" value="' . sm_encode_html_special_chars ($this->value )
  579. . '" ' . $this->script . ' />';
  580. return ($result);
  581. }
  582. function createWidget_Comment () {
  583. $result = $this->comment ;
  584. return ($result);
  585. }
  586. /**
  587. * Creates a (non-associative) edit list
  588. *
  589. * Note that multiple layout types are supported for this widget.
  590. * $this->layout_type must be one of the SMOPT_EDIT_LIST_LAYOUT_*
  591. * constants.
  592. *
  593. * @return string html formated list of edit fields and
  594. * their associated controls
  595. */
  596. function createWidget_EditList () {
  597. switch ($this->size ) {
  598. $height = 3;
  599. break;
  600. $height = 8;
  601. break;
  602. $height = 15;
  603. break;
  604. $height = 25;
  605. break;
  606. $height = 40;
  607. break;
  608. default:
  609. $height = 5;
  610. }
  611. // ensure correct format of current value(s)
  612. //
  613. if (empty($this->possible_values )) $this->possible_values = array();
  614. if (!is_array ($this->possible_values )) $this->possible_values = array($this->possible_values );
  615. global $javascript_on, $color;
  616. switch ($this->layout_type ) {
  617. $result = '';
  618. if ($this->use_add_widget )
  619. $result .= _ ("Add") . '&nbsp;<input name="add_' . $this->name
  620. . '" size="38" /><br />'
  621. . (empty($this->trailing_text ) ? ''
  622. : ($this->trailing_text_small ? '<small>' : '')
  623. . ($this->trailing_text_small ? '</small>' : '') . '<br />');
  624. $result .= '<select name="new_' . $this->name
  625. . '[]" multiple="multiple" size="' . $height . '"'
  626. . ($javascript_on ? ' onchange="if (typeof(window.addinput_' . $this->name . ') == \'undefined\') { var f = document.forms.length; var i = 0; var pos = -1; while( pos == -1 && i < f ) { var e = document.forms[i].elements.length; var j = 0; while( pos == -1 && j < e ) { if ( document.forms[i].elements[j].type == \'text\' && document.forms[i].elements[j].name == \'add_' . $this->name . '\' ) { pos = j; i=f-1; j=e-1; } j++; } i++; } if( pos >= 0 ) { window.addinput_' . $this->name . ' = document.forms[i-1].elements[pos]; } } for (x = 0; x < this.length; x++) { if (this.options[x].selected) { window.addinput_' . $this->name . '.value = this.options[x].text; break; } }"' : '')
  627. // NOTE: i=f-1; j=e-1 is in lieu of break 2
  628. . ' ' . $this->script . ">\n";
  629. if (is_array ($this->value ))
  630. $selected = $this->value ;
  631. else
  632. $selected = array($this->value );
  633. // Add each possible value to the select list.
  634. //
  635. foreach ($this->possible_values as $value) {
  636. // Start the next new option string.
  637. //
  638. $result .= '<option value="' . sm_encode_html_special_chars ($value) . '"';
  639. // having a selected item in the edit list doesn't have
  640. // any meaning, but maybe someone will think of a way to
  641. // use it, so we might as well put the code in
  642. //
  643. foreach ($selected as $default) {
  644. if ((string)$default == (string)$value) {
  645. $result .= ' selected="selected"';
  646. break;
  647. }
  648. }
  649. // Add the display value to our option string.
  650. //
  651. $result .= '>' . sm_encode_html_special_chars ($value) . "</option>\n";
  652. }
  653. $result .= '</select>';
  654. if (!empty($this->possible_values ) && $this->use_delete_widget )
  655. $result .= '<br /><input type="checkbox" name="delete_'
  656. . $this->name . '" id="delete_' . $this->name
  657. . '" value="1" />&nbsp;<label for="delete_'
  658. . $this->name . '">' . _ ("Delete Selected")
  659. . '</label>';
  660. break;
  661. $result = '<table width="80%" cellpadding="1" cellspacing="0" border="0" bgcolor="'
  662. . $color[0] . '"><tr><td>';
  663. if ($this->use_add_widget )
  664. $result .= _ ("Add") . '&nbsp;<input name="add_' . $this->name
  665. . '" size="38" /><br />'
  666. . (empty($this->trailing_text ) ? ''
  667. : ($this->trailing_text_small ? '<small>' : '')
  668. . ($this->trailing_text_small ? '</small>' : '') . '<br />');
  669. $result .= '<table width="100%" cellpadding="1" cellspacing="0" border="0" bgcolor="' . $color[5] . '">';
  670. $bgcolor = 4;
  671. if (!isset($color[12]))
  672. $color[12] = '#EAEAEA';
  673. $index = 0;
  674. if (is_array ($this->value ))
  675. $selected = $this->value ;
  676. else
  677. $selected = array($this->value );
  678. foreach ($this->possible_values as $key => $value) {
  679. if ($bgcolor == 4) $bgcolor = 12;
  680. else $bgcolor = 4;
  681. $result .= '<tr bgcolor="' . $color[$bgcolor] . '">'
  682. . '<td width="1%"><input type="checkbox" name="new_'
  683. . $this->name . '[' . ($index++) . ']" id="' . $this->name
  684. . '_list_item_' . $key . '" value="'
  685. // having a selected item in the edit list doesn't have
  686. // any meaning, but maybe someone will think of a way to
  687. // use it, so we might as well put the code in
  688. //
  689. foreach ($selected as $default) {
  690. if ((string)$default == (string)$value) {
  691. $result .= '" checked="checked';
  692. break;
  693. }
  694. }
  695. $result .= '"></td>'
  696. . '<td><label for="' . $this->name . '_list_item_' . $key
  697. . '">' . sm_encode_html_special_chars ($value) . '</label></td>'
  698. . "</tr>\n";
  699. }
  700. $result .= '</table>';
  701. if (!empty($this->possible_values ) && $this->use_delete_widget )
  702. $result .= '<input type="checkbox" name="delete_'
  703. . $this->name . '" id="delete_' . $this->name
  704. . '" value="1" />&nbsp;<label for="delete_' . $this->name . '">'
  705. . _ ("Delete Selected") . '</label>';
  706. $result .= '</td></tr></table>';
  707. break;
  708. default:
  709. $result = '<font color="' . $color[2] . '">'
  710. . sprintf (_ ("Edit List Layout Type '%s' Not Found"), $this->layout_type )
  711. . '</font>';
  712. }
  713. return $result;
  714. }
  715. /**
  716. * Creates an associative edit list
  717. *
  718. * Note that multiple layout types are supported for this widget.
  719. * $this->layout_type must be one of the SMOPT_EDIT_LIST_LAYOUT_*
  720. * constants.
  721. *
  722. * @return string html formated list of edit fields and
  723. * their associated controls
  724. */
  725. switch ($this->size ) {
  726. $height = 3;
  727. break;
  728. $height = 8;
  729. break;
  730. $height = 15;
  731. break;
  732. $height = 25;
  733. break;
  734. $height = 40;
  735. break;
  736. default:
  737. $height = 5;
  738. }
  739. // ensure correct format of current value(s)
  740. //
  741. if (empty($this->possible_values )) $this->possible_values = array();
  742. if (!is_array ($this->possible_values )) $this->possible_values = array($this->possible_values );
  743. global $javascript_on, $color;
  744. switch ($this->layout_type ) {
  745. $result = '';
  746. if ($this->use_add_widget ) {
  747. //FIXME implement poss_key_folders here? probably not worth the trouble, is there a use case?
  748. $result .= _ ("Add") . '&nbsp;<input name="add_' . $this->name
  749. . '_key" size="22" /> ';
  750. // FIXME: shall we allow these "poss value folders" (folder list selection for edit list values) for NON-Associative EDIT_LIST widgets?
  751. if ($this->poss_value_folders ) {
  752. $result .= '<select name="add_' . $this->name . '_value">';
  753. /* Add each possible value to the select list. */
  754. foreach ($this->poss_value_folders as $real_value => $disp_value) {
  755. if ( is_array ($disp_value) ) {
  756. /* For folder list, we passed in the array of boxes.. */
  757. $new_option = sqimap_mailbox_option_list (0, 0, 0, $disp_value);
  758. } else {
  759. /* Start the next new option string. */
  760. $new_option = '<option value="' . sm_encode_html_special_chars ($real_value) . '"';
  761. /* Add the display value to our option string. */
  762. $new_option .= '>' . sm_encode_html_special_chars ($disp_value) . "</option>\n";
  763. }
  764. /* And add the new option string to our select tag. */
  765. $result .= $new_option;
  766. }
  767. /* Close the select tag and return our happy result. */
  768. $result .= '</select>';
  769. }
  770. else
  771. $result .= '<input name="add_' . $this->name
  772. . '_value" size="12" /><br />';
  773. $result .= (empty($this->trailing_text ) ? ''
  774. : ($this->trailing_text_small ? '<small>' : '')
  775. . ($this->trailing_text_small ? '</small>' : '') . '<br />');
  776. }
  777. $result .= '<select name="new_' . $this->name
  778. . '[]" multiple="multiple" size="' . $height . '"'
  779. // FIXME: this can be fooled by having the delimiter " = " in a key value - in general, we may want to use a different delimiter other than " = "
  780. . ($javascript_on ? ' onchange="if (typeof(window.addinput_key_' . $this->name . ') == \'undefined\') { var f = document.forms.length; var i = 0; var pos = -1; while( pos == -1 && i < f ) { var e = document.forms[i].elements.length; var j = 0; while( pos == -1 && j < e ) { if ( document.forms[i].elements[j].type == \'text\' && document.forms[i].elements[j].name == \'add_' . $this->name . '_key\' ) { pos = j; j=e-1; i=f-1; } j++; } i++; } if( pos >= 0 ) { window.addinput_key_' . $this->name . ' = document.forms[i-1].elements[pos]; } } if (typeof(window.addinput_value_' . $this->name . ') == \'undefined\') { var f = document.forms.length; var i = 0; var pos = -1; while( pos == -1 && i < f ) { var e = document.forms[i].elements.length; var j = 0; while( pos == -1 && j < e ) { if ( document.forms[i].elements[j].type == \'text\' && document.forms[i].elements[j].name == \'add_' . $this->name . '_value\' ) { pos = j; j=e-1; i=f-1; } j++; } i++; } if( pos >= 0 ) { window.addinput_value_' . $this->name . ' = document.forms[i-1].elements[pos]; } } for (x = 0; x < this.length; x++) { if (this.options[x].selected) { pos = this.options[x].text.indexOf(\' = \'); if (pos > -1) { window.addinput_key_' . $this->name . '.value = this.options[x].text.substr(0, pos); if (typeof(window.addinput_value_' . $this->name . ') != \'undefined\') window.addinput_value_' . $this->name . '.value = this.options[x].text.substr(pos + 3); } break; } }"' : '')
  781. // NOTE: i=f-1; j=e-1 is in lieu of break 2
  782. . ' ' . $this->script . ">\n";
  783. if (is_array ($this->value ))
  784. $selected = $this->value ;
  785. else
  786. $selected = array($this->value );
  787. // Add each possible value to the select list.
  788. //
  789. foreach ($this->possible_values as $key => $value) {
  790. // Start the next new option string.
  791. //
  792. $result .= '<option value="' . urlencode ($key) . '"';
  793. // having a selected item in the edit list doesn't have
  794. // any meaning, but maybe someone will think of a way to
  795. // use it, so we might as well put the code in
  796. //
  797. foreach ($selected as $default) {
  798. if ((string)$default == (string)$key) {
  799. $result .= ' selected="selected"';
  800. break;
  801. }
  802. }
  803. // Add the display value to our option string.
  804. //
  805. $result .= '>' . sm_encode_html_special_chars ($key) . ' = ';
  806. if ($this->poss_value_folders ) {
  807. foreach ($this->poss_value_folders as $real_value => $disp_value) {
  808. if ( is_array ($disp_value) ) {
  809. foreach ($disp_value as $folder_info) {
  810. if ($value == $folder_info['unformatted']) {
  811. $result .= sm_encode_html_special_chars (str_replace ('&nbsp;', '', $folder_info['formatted']));
  812. break 2;
  813. }
  814. }
  815. }
  816. else
  817. if ($value == $disp_value) {
  818. $result .= sm_encode_html_special_chars ($disp_value);
  819. break;
  820. }
  821. }
  822. }
  823. else
  824. $result .= sm_encode_html_special_chars ($value);
  825. $result .= "</option>\n";
  826. }
  827. $result .= '</select>';
  828. if (!empty($this->possible_values ) && $this->use_delete_widget )
  829. $result .= '<br /><input type="checkbox" name="delete_'
  830. . $this->name . '" id="delete_' . $this->name
  831. . '" value="1" />&nbsp;<label for="delete_'
  832. . $this->name . '">' . _ ("Delete Selected")
  833. . '</label>';
  834. break;
  835. $result = '<table width="80%" cellpadding="1" cellspacing="0" border="0" bgcolor="'
  836. . $color[0] . '"><tr><td>';
  837. if ($this->use_add_widget ) {
  838. //FIXME implement poss_key_folders here? probably not worth the trouble, is there a use case?
  839. $result .= _ ("Add") . '&nbsp;<input name="add_' . $this->name
  840. . '_key" size="22" /> ';
  841. if ($this->poss_value_folders ) {
  842. $result .= '<select name="add_' . $this->name . '_value">';
  843. /* Add each possible value to the select list. */
  844. foreach ($this->poss_value_folders as $real_value => $disp_value) {
  845. if ( is_array ($disp_value) ) {
  846. /* For folder list, we passed in the array of boxes.. */
  847. $new_option = sqimap_mailbox_option_list (0, 0, 0, $disp_value);
  848. } else {
  849. /* Start the next new option string. */
  850. $new_option = '<option value="' . sm_encode_html_special_chars ($real_value) . '"';
  851. /* Add the display value to our option string. */
  852. $new_option .= '>' . sm_encode_html_special_chars ($disp_value) . "</option>\n";
  853. }
  854. /* And add the new option string to our select tag. */
  855. $result .= $new_option;
  856. }
  857. /* Close the select tag and return our happy result. */
  858. $result .= '</select>';
  859. }
  860. else
  861. $result .= '<input name="add_' . $this->name
  862. . '_value" size="12" /><br />';
  863. $result .= (empty($this->trailing_text ) ? ''
  864. : ($this->trailing_text_small ? '<small>' : '')
  865. . ($this->trailing_text_small ? '</small>' : '') . '<br />');
  866. }
  867. $result .= '<table width="100%" cellpadding="1" cellspacing="0" border="0" bgcolor="' . $color[5] . '">';
  868. $bgcolor = 4;
  869. if (!isset($color[12]))
  870. $color[12] = '#EAEAEA';
  871. if (is_array ($this->value ))
  872. $selected = $this->value ;
  873. else
  874. $selected = array($this->value );
  875. foreach ($this->possible_values as $key => $value) {
  876. if ($bgcolor == 4) $bgcolor = 12;
  877. else $bgcolor = 4;
  878. $result .= '<tr bgcolor="' . $color[$bgcolor] . '">'
  879. . '<td width="1%"><input type="checkbox" name="new_'
  880. . $this->name . '[' . urlencode ($key) . ']" id="'
  881. . $this->name . '_list_item_' . urlencode ($key)
  882. . '" value="' . sm_encode_html_special_chars ($value);
  883. // having a selected item in the edit list doesn't have
  884. // any meaning, but maybe someone will think of a way to
  885. // use it, so we might as well put the code in
  886. //
  887. foreach ($selected as $default) {
  888. if ((string)$default == (string)$key) {
  889. $result .= '" checked="checked';
  890. break;
  891. }
  892. }
  893. $result .= '"></td>'
  894. . '<td><label for="' . $this->name . '_list_item_'
  895. . urlencode ($key) . '">'
  896. . sm_encode_html_special_chars ($key) . ' = ';
  897. if ($this->poss_value_folders ) {
  898. foreach ($this->poss_value_folders as $real_value => $disp_value) {
  899. if ( is_array ($disp_value) ) {
  900. foreach ($disp_value as $folder_info) {
  901. if ($value == $folder_info['unformatted']) {
  902. $result .= sm_encode_html_special_chars (str_replace ('&nbsp;', '', $folder_info['formatted']));
  903. break 2;
  904. }
  905. }
  906. }
  907. else
  908. if ($value == $disp_value) {
  909. $result .= sm_encode_html_special_chars ($disp_value);
  910. break;
  911. }
  912. }
  913. }
  914. else
  915. $result .= sm_encode_html_special_chars ($value);
  916. $result .= '</label></td>'
  917. . "</tr>\n";
  918. }
  919. $result .= '</table>';
  920. if (!empty($this->possible_values ) && $this->use_delete_widget )
  921. $result .= '<input type="checkbox" name="delete_'
  922. . $this->name . '" id="delete_' . $this->name
  923. . '" value="1" />&nbsp;<label for="delete_' . $this->name . '">'
  924. . _ ("Delete Selected") . '</label>';
  925. $result .= '</td></tr></table>';
  926. break;
  927. default:
  928. $result = '<font color="' . $color[2] . '">'
  929. . sprintf (_ ("Edit List Layout Type '%s' Not Found"), $this->layout_type )
  930. . '</font>';
  931. }
  932. return $result;
  933. }
  934. /**
  935. * Creates a submit button
  936. *
  937. * @return string html formated submit button widget
  938. *
  939. */
  940. function createWidget_Submit () {
  941. $result = "<input type=\"submit\" name=\"$this->name\" value=\""
  942. . "\" $this->script /> "
  943. . ($this->trailing_text_small ? '<small>' : '')
  944. . ($this->trailing_text_small ? '</small>' : '')
  945. . "\n";
  946. return $result;
  947. }
  948. function save () {
  949. $function = $this->save_function ;
  950. $function($this);
  951. }
  952. function changed () {
  953. // edit lists have a lot going on, so we'll always process them
  954. //
  955. if ($this->type == SMOPT_TYPE_EDIT_LIST
  956. return TRUE;
  957. return ($this->value != $this->new_value );
  958. }
  959. }
  960. function save_option ($option) {
  961. // Can't save the pref if we don't have the username
  962. //
  963. if ( !sqgetGlobalVar ('username', $username, SQ_SESSION ) ) {
  964. return;
  965. }
  966. // if the widget is a selection list, make sure the new
  967. // value is actually in the selection list and is not an
  968. // injection attack
  969. //
  970. if ($option->type == SMOPT_TYPE_STRLIST
  971. && !array_key_exists ($option->new_value , $option->possible_values ))
  972. return;
  973. // all other widgets except TEXTAREAs should never be allowed to have newlines
  974. //
  975. else if ($option->type != SMOPT_TYPE_TEXTAREA )
  976. $option->new_value = str_replace (array("\r", "\n"), '', $option->new_value );
  977. global $data_dir ;
  978. // edit lists: first add new elements to list, then
  979. // remove any selected ones (note that we must add
  980. // before deleting because the javascript that populates
  981. // the "add" textbox when selecting items in the list
  982. // (for deletion))
  983. //
  984. if ($option->type == SMOPT_TYPE_EDIT_LIST ) {
  985. if (empty($option->possible_values )) $option->possible_values = array();
  986. if (!is_array ($option->possible_values )) $option->possible_values = array($option->possible_values );
  987. // add element if given
  988. //
  989. if ((isset($option->use_add_widget ) && $option->use_add_widget )
  990. && sqGetGlobalVar('add_' . $option->name , $new_element, SQ_POST )) {
  991. $new_element = trim ($new_element);
  992. if (!empty($new_element)
  993. && !in_array ($new_element, $option->possible_values ))
  994. $option->possible_values [] = $new_element;
  995. }
  996. // delete selected elements if needed
  997. //
  998. if ((isset($option->use_delete_widget ) && $option->use_delete_widget )
  999. && is_array ($option->new_value )
  1000. && sqGetGlobalVar('delete_' . $option->name , $ignore, SQ_POST ))
  1001. $option->possible_values = array_diff ($option->possible_values , $option->new_value );
  1002. // save full list (stored in "possible_values")
  1003. //
  1004. setPref ($data_dir, $username, $option->name , serialize ($option->possible_values ));
  1005. // associative edit lists are handled similar to
  1006. // non-associative ones
  1007. //
  1008. } else if ($option->type == SMOPT_TYPE_EDIT_LIST_ASSOCIATIVE ) {
  1009. if (empty($option->possible_values )) $option->possible_values = array();
  1010. if (!is_array ($option->possible_values )) $option->possible_values = array($option->possible_values );
  1011. // add element if given
  1012. //
  1013. $new_element_key = '';
  1014. $new_element_value = '';
  1015. $retrieve_key = sqGetGlobalVar('add_' . $option->name . '_key', $new_element_key, SQ_POST );
  1016. $retrieve_value = sqGetGlobalVar('add_' . $option->name . '_value', $new_element_value, SQ_POST );
  1017. if ((isset($option->use_add_widget ) && $option->use_add_widget )
  1018. && ($retrieve_key || $retrieve_value)) {
  1019. $new_element_key = trim ($new_element_key);
  1020. $new_element_value = trim ($new_element_value);
  1021. if ($option->poss_value_folders && empty($new_element_key))
  1022. $new_element_value = '';
  1023. if (!empty($new_element_key) || !empty($new_element_value)) {
  1024. if (empty($new_element_key)) $new_element_key = '0';
  1025. $option->possible_values [$new_element_key] = $new_element_value;
  1026. }
  1027. }
  1028. // delete selected elements if needed
  1029. //
  1030. if ((isset($option->use_delete_widget ) && $option->use_delete_widget )
  1031. && is_array ($option->new_value )
  1032. && sqGetGlobalVar('delete_' . $option->name , $ignore, SQ_POST )) {
  1033. foreach ($option->new_value as $key)
  1034. unset($option->possible_values [urldecode ($key)]);
  1035. }
  1036. else
  1037. $option->possible_values = array_diff ($option->possible_values , $option->new_value );
  1038. }
  1039. // save full list (stored in "possible_values")
  1040. //
  1041. setPref ($data_dir, $username, $option->name , serialize ($option->possible_values ));
  1042. // Certain option types need to be serialized because
  1043. // they are not scalar
  1044. //
  1045. } else if ($option->is_multiple_valued ())
  1046. setPref ($data_dir, $username, $option->name , serialize ($option->new_value ));
  1047. // Checkboxes, when unchecked, don't submit anything in
  1048. // the POST, so set to SMPREF_OFF if not found
  1049. //
  1050. else if (($option->type == SMOPT_TYPE_BOOLEAN
  1051. && empty($option->new_value ))
  1052. setPref ($data_dir, $username, $option->name , SMPREF_OFF );
  1053. // For integer fields, make sure we only have digits...
  1054. // We'll be nice and instead of just converting to an integer,
  1055. // we'll physically remove each non-digit in the string.
  1056. //
  1057. else if ($option->type == SMOPT_TYPE_INTEGER ) {
  1058. $option->new_value = preg_replace ('/[^0-9]/', '', $option->new_value );
  1059. setPref ($data_dir, $username, $option->name , $option->new_value );
  1060. }
  1061. else
  1062. setPref ($data_dir, $username, $option->name , $option->new_value );
  1063. // if a checkbox or multi select is zeroed/cleared out, it
  1064. // needs to have an empty value pushed into its "new_value" slot
  1065. //
  1066. if (($option->type == SMOPT_TYPE_STRLIST_MULTI
  1067. && is_null ($option->new_value ))
  1068. $option->new_value = '';
  1069. }
  1070. function save_option_noop ($option) {
  1071. /* Do nothing here... */
  1072. }
  1073. function create_optpage_element ($optpage) {
  1074. return create_hidden_element ('optpage', $optpage);
  1075. }
  1076. function create_optmode_element ($optmode) {
  1077. return create_hidden_element ('optmode', $optmode);
  1078. }
  1079. function create_hidden_element ($name, $value) {
  1080. $result = '<input type="hidden" '
  1081. . 'name="' . $name . '" '
  1082. . 'value="' . sm_encode_html_special_chars ($value) . '" />';
  1083. return ($result);
  1084. }
  1085. function create_option_groups ($optgrps, $optvals) {
  1086. /* Build a simple array with which to start. */
  1087. $result = array();
  1088. /* Create option group for each option group name. */
  1089. foreach ($optgrps as $grpkey => $grpname) {
  1090. $result[$grpkey] = array();
  1091. $result[$grpkey]['name'] = $grpname;
  1092. $result[$grpkey]['options'] = array();
  1093. }
  1094. /* Create a new SquirrelOption for each set of option values. */
  1095. foreach ($optvals as $grpkey => $grpopts) {
  1096. foreach ($grpopts as $optset) {
  1097. /* Create a new option with all values given. */
  1098. $next_option = new SquirrelOption (
  1099. $optset,
  1100. $optset['name'],
  1101. $optset['caption'],
  1102. $optset['type'],
  1103. (isset($optset['refresh']) ? $optset['refresh'] : SMOPT_REFRESH_NONE ),
  1104. (isset($optset['initial_value']) ? $optset['initial_value'] : ''),
  1105. (isset($optset['posvals']) ? $optset['posvals'] : ''),
  1106. (isset($optset['htmlencoded']) ? $optset['htmlencoded'] : false)
  1107. );
  1108. /* If provided, set if the caption is allowed to wrap for this option. */
  1109. if (isset($optset['caption_wrap'])) {
  1110. $next_option->setCaptionWrap ($optset['caption_wrap']);
  1111. }
  1112. /* If provided, set the size for this option. */
  1113. if (isset($optset['size'])) {
  1114. $next_option->setSize ($optset['size']);
  1115. }
  1116. /* If provided, set the trailing_text for this option. */
  1117. if (isset($optset['trailing_text'])) {
  1118. $next_option->setTrailingText ($optset['trailing_text']);
  1119. }
  1120. /* If provided, set whether the trailing_text should be rendered small for this option. */
  1121. if (isset($optset['trailing_text_small'])) {
  1122. $next_option->setTrailingTextSmall ($optset['trailing_text_small']);
  1123. }
  1124. /* If provided, set whether the trailing_text is HTML (and thus should not be sanitized - CAREFUL!) for this option. */
  1125. if (isset($optset['trailing_text_is_html'])) {
  1126. $next_option->setTrailingTextIsHtml ($optset['trailing_text_is_html']);
  1127. }
  1128. /* If provided, set the yes_text for this option. */
  1129. if (isset($optset['yes_text'])) {
  1130. $next_option->setYesText ($optset['yes_text']);
  1131. }
  1132. /* If provided, set the no_text for this option. */
  1133. if (isset($optset['no_text'])) {
  1134. $next_option->setNoText ($optset['no_text']);
  1135. }
  1136. /* If provided, set the use_add_widget value for this option. */
  1137. if (isset($optset['use_add_widget'])) {
  1138. $next_option->setUseAddWidget ($optset['use_add_widget']);
  1139. }
  1140. /* If provided, set the use_delete_widget value for this option. */
  1141. if (isset($optset['use_delete_widget'])) {
  1142. $next_option->setUseDeleteWidget ($optset['use_delete_widget']);
  1143. }
  1144. /* If provided, set the poss_value_folders value for this option. */
  1145. if (isset($optset['poss_value_folders'])) {
  1146. $next_option->setPossValueFolders ($optset['poss_value_folders']);
  1147. }
  1148. /* If provided, set the layout type for this option. */
  1149. if (isset($optset['layout_type'])) {
  1150. $next_option->setLayoutType ($optset['layout_type']);
  1151. }
  1152. /* If provided, set the comment for this option. */
  1153. if (isset($optset['comment'])) {
  1154. $next_option->setComment ($optset['comment']);
  1155. }
  1156. /* If provided, set the save function for this option. */
  1157. if (isset($optset['save'])) {
  1158. $next_option->setSaveFunction ($optset['save']);
  1159. }
  1160. /* If provided, set the script for this option. */
  1161. if (isset($optset['script'])) {
  1162. $next_option->setScript ($optset['script']);
  1163. }
  1164. /* If provided, set the "post script" for this option. */
  1165. if (isset($optset['post_script'])) {
  1166. $next_option->setPostScript ($optset['post_script']);
  1167. }
  1168. /* Add this option to the option array. */
  1169. $result[$grpkey]['options'][] = $next_option;
  1170. }
  1171. }
  1172. /* Return our resulting array. */
  1173. return ($result);
  1174. }
  1175. function print_option_groups ($option_groups) {
  1176. /* Print each option group. */
  1177. foreach ($option_groups as $next_optgrp) {
  1178. /* If it is not blank, print the name for this option group. */
  1179. if ($next_optgrp['name'] != '') {
  1180. echo html_tag ( 'tr', "\n".
  1181. html_tag ( 'td',
  1182. '<b>' . $next_optgrp['name'] . '</b>' ,
  1183. 'center' ,'', 'valign="middle" colspan="2" nowrap' )
  1184. ) ."\n";
  1185. }
  1186. /* Print each option in this option group. */
  1187. $hidden_options = '';
  1188. foreach ($next_optgrp['options'] as $option) {
  1189. if ($option->type != SMOPT_TYPE_HIDDEN ) {
  1190. // although trailing_text will be a label for the checkbox,
  1191. // make the caption a label too - some widgets won't have
  1192. // trailing_text and having both as labels is perfectly fine
  1193. //
  1194. || $option->type == SMOPT_TYPE_BOOLEAN )
  1195. $option->caption = '<label for="new_' . $option->name . '">'
  1196. . $option->caption . ':</label>';
  1197. else if (!empty($option->caption ))
  1198. $option->caption .= ':';
  1199. // text area trailing text just goes under the caption
  1200. //
  1201. if ($option->type == SMOPT_TYPE_TEXTAREA && !empty($option->trailing_text ))
  1202. //TODO: I guess we should change this to obey trailing_text_small, but that would break existing plugins
  1203. //TODO: What about trailing_text_is_html? Why wasn't this being sanitized with sm_encode_html_special_chars()?????
  1204. $option->caption .= '<br /><small>' . $option->trailing_text . '</small>';
  1205. global $color;
  1206. //$info_bgcolor = 0;
  1207. $info_bgcolor = 4;
  1208. $info_width = 80;
  1209. if ($option->type == SMOPT_TYPE_INFO )
  1210. echo html_tag ('tr', "\n" . html_tag ('td', "\n" . html_tag ('table', "\n" . html_tag ('tr', "\n" . html_tag ('td', "\n" . $option->createHTMLWidget ())), '', $color[$info_bgcolor], 'width="' . $info_width . '%"'), 'center' ,'', 'colspan="2" valign="middle"')) ."\n";
  1211. else
  1212. echo html_tag ( 'tr', "\n".
  1213. html_tag ( 'td', $option->caption , 'right' ,'', 'valign="middle"' . ($option->caption_wrap ? '' : ' style="white-space:nowrap"') ) .
  1214. html_tag ( 'td', $option->createHTMLWidget (), 'left' )
  1215. ) ."\n";
  1216. } else {
  1217. $hidden_options .= $option->createHTMLWidget ();
  1218. }
  1219. }
  1220. /* Print an empty row after this option group. */
  1221. echo html_tag ( 'tr',
  1222. html_tag ( 'td', '&nbsp;' . $hidden_options, 'left', '', 'colspan="2"' )
  1223. ) . "\n";
  1224. }
  1225. }
  1226. function OptionSubmit ( $name ) {
  1227. echo html_tag ( 'tr',
  1228. html_tag ( 'td', '<input type="submit" value="' . _ ("Submit") . '" name="' . $name . '" />&nbsp;&nbsp;&nbsp;&nbsp;', 'right', '', 'colspan="2"' )
  1229. ) . "\n";
  1230. }

Documentation generated on 2020年1月13日 04:25:04 +0100 by phpDocumentor 1.4.3

AltStyle によって変換されたページ (->オリジナル) /