Source for file addressbook.php

Documentation is available at addressbook.php

  1. <?php
  2. /**
  3. * addressbook.php
  4. *
  5. * Manage personal address book.
  6. *
  7. * @copyright 1999-2020 The SquirrelMail Project Team
  8. * @license http://opensource.org/licenses/gpl-license.php GNU Public License
  9. * @version $Id: addressbook.php 14840 2020年01月07日 07:42:38Z pdontthink $
  10. * @package squirrelmail
  11. * @subpackage addressbook
  12. */
  13. /** This is the addressbook page */
  14. define ('PAGE_NAME', 'addressbook');
  15. /**
  16. * Path for SquirrelMail required files.
  17. * @ignore
  18. */
  19. define ('SM_PATH','../');
  20. /** SquirrelMail required files. */
  21. require_once(SM_PATH . 'include/validate.php');
  22. require_once(SM_PATH . 'functions/global.php');
  23. require_once(SM_PATH . 'functions/display_messages.php');
  24. require_once(SM_PATH . 'functions/addressbook.php');
  25. require_once(SM_PATH . 'functions/strings.php');
  26. require_once(SM_PATH . 'functions/html.php');
  27. require_once(SM_PATH . 'functions/forms.php');
  28. /** lets get the global vars we may need */
  29. if (!sqgetGlobalVar ('smtoken',$submitted_token, SQ_POST )) {
  30. $submitted_token = '';
  31. }
  32. sqgetGlobalVar ('key', $key, SQ_COOKIE );
  33. sqgetGlobalVar ('username', $username, SQ_SESSION );
  34. sqgetGlobalVar ('onetimepad',$onetimepad, SQ_SESSION );
  35. sqgetGlobalVar ('base_uri', $base_uri, SQ_SESSION );
  36. sqgetGlobalVar ('delimiter', $delimiter, SQ_SESSION );
  37. /* From the address form */
  38. sqgetGlobalVar ('addaddr', $addaddr, SQ_POST );
  39. sqgetGlobalVar ('editaddr', $editaddr, SQ_POST );
  40. sqgetGlobalVar ('deladdr', $deladdr, SQ_POST );
  41. sqgetGlobalVar ('compose_to', $compose_to, SQ_POST );
  42. sqgetGlobalVar ('sel', $sel, SQ_POST );
  43. // renumber $sel array
  44. if (!empty($sel)) $sel = array_merge ($sel, array());
  45. sqgetGlobalVar ('oldnick', $oldnick, SQ_POST );
  46. sqgetGlobalVar ('backend', $backend, SQ_POST );
  47. sqgetGlobalVar ('doedit', $doedit, SQ_POST );
  48. /* Get sorting order */
  49. $abook_sort_order = get_abook_sort ();
  50. /**
  51. * Make an input field
  52. * @param string $label
  53. * @param string $field
  54. * @param string $name
  55. * @param string $size
  56. * @param array $values
  57. * @param string $add
  58. */
  59. function addressbook_inp_field ($label, $field, $name, $size, $values, $add) {
  60. global $color;
  61. $value = ( isset($values[$field]) ? $values[$field] : '');
  62. $td_str = addInput ($name.'['.$field.']', $value, $size)
  63. . $add ;
  64. return html_tag ( 'tr' ,
  65. html_tag ( 'td', $label . ':', 'right', $color[4]) .
  66. html_tag ( 'td', $td_str, 'left', $color[4])
  67. )
  68. . "\n";
  69. }
  70. /**
  71. * Output form to add and modify address data
  72. */
  73. function address_form ($name, $submittext, $values = array()) {
  74. global $color, $squirrelmail_language;
  75. if ($squirrelmail_language == 'ja_JP') {
  76. echo html_tag ( 'table',
  77. addressbook_inp_field (_ ("Nickname"), 'nickname', $name, 15, $values,
  78. ' <small>' . _ ("Must be unique") . '</small>') .
  79. addressbook_inp_field (_ ("E-mail address"), 'email', $name, 45, $values, '') .
  80. addressbook_inp_field (_ ("Last name"), 'lastname', $name, 45, $values, '') .
  81. addressbook_inp_field (_ ("First name"), 'firstname', $name, 45, $values, '') .
  82. addressbook_inp_field (_ ("Additional info"), 'label', $name, 45, $values, '') .
  83. html_tag ( 'tr',
  84. html_tag ( 'td',
  85. addSubmit ($submittext, $name.'[SUBMIT]'),
  86. 'center', $color[4], 'colspan="2"')
  87. )
  88. , 'center', '', 'border="0" cellpadding="1" width="90%"') ."\n";
  89. } else {
  90. echo html_tag ( 'table',
  91. addressbook_inp_field (_ ("Nickname"), 'nickname', $name, 15, $values,
  92. ' <small>' . _ ("Must be unique") . '</small>') .
  93. addressbook_inp_field (_ ("E-mail address"), 'email', $name, 45, $values, '') .
  94. addressbook_inp_field (_ ("First name"), 'firstname', $name, 45, $values, '') .
  95. addressbook_inp_field (_ ("Last name"), 'lastname', $name, 45, $values, '') .
  96. addressbook_inp_field (_ ("Additional info"), 'label', $name, 45, $values, '') .
  97. html_tag ( 'tr',
  98. html_tag ( 'td',
  99. addSubmit ($submittext, $name.'[SUBMIT]') ,
  100. 'center', $color[4], 'colspan="2"')
  101. )
  102. , 'center', '', 'border="0" cellpadding="1" width="90%"') ."\n";
  103. }
  104. }
  105. /**
  106. * Provides list of writeable backends.
  107. * Works only when address is added ($name='addaddr')
  108. * @param string $name name of form
  109. * @return string html formated backend field (select or hidden)
  110. */
  111. function list_writable_backends ($name) {
  112. global $color, $abook;
  113. if ( $name != 'addaddr' ) { return; }
  114. $writeable_abook = 1;
  115. if ( $abook->numbackends > 1 ) {
  116. $backends = $abook->get_backend_list();
  117. $writeable_abooks=array();
  118. while (list($undef,$v) = each ($backends)) {
  119. if ($v->writeable) {
  120. // add each backend to array
  121. $writeable_abooks[$v->bnum]=$v->sname;
  122. // save backend number
  123. $writeable_abook=$v->bnum;
  124. }
  125. }
  126. if (count ($writeable_abooks)>1) {
  127. // we have more than one writeable backend
  128. $ret=addSelect ('backend',$writeable_abooks,null,true);
  129. return html_tag ( 'tr',
  130. html_tag ( 'td', _ ("Add to:"),'right', $color[4] ) .
  131. html_tag ( 'td', $ret, 'left', $color[4] )) . "\n";
  132. }
  133. }
  134. // Only one backend exists or is writeable.
  135. return html_tag ( 'tr',
  136. html_tag ( 'td',
  137. addHidden ('backend', $writeable_abook),
  138. 'center', $color[4], 'colspan="2"')) . "\n";
  139. }
  140. // Create page header before addressbook_init in order to
  141. // display error messages correctly, unless we might be
  142. // redirecting the browser to the compose page.
  143. //
  144. if ((empty($compose_to)) || sizeof ($sel) < 1)
  145. displayPageHeader ($color, 'None');
  146. /* Open addressbook, with error messages on but without LDAP (the *
  147. * second "true"). Don't need LDAP here anyway */
  148. $abook = addressbook_init (true, true);
  149. if($abook->localbackend == 0) {
  150. _ ("No personal address book is defined. Contact administrator."),
  151. $color);
  152. exit();
  153. }
  154. $defdata = array();
  155. $formerror = '';
  156. $abortform = false;
  157. $showaddrlist = true;
  158. $defselected = array();
  159. $form_url = 'addressbook.php';
  160. /* Handle user's actions */
  161. if(sqgetGlobalVar ('REQUEST_METHOD', $req_method, SQ_SERVER ) && $req_method == 'POST') {
  162. // first, validate security token
  163. sm_validate_security_token ($submitted_token, -1, TRUE);
  164. /**************************************************
  165. * Add new address *
  166. **************************************************/
  167. if (isset($addaddr)) {
  168. if (isset($backend)) {
  169. $r = $abook->add($addaddr, $backend);
  170. } else {
  171. $r = $abook->add($addaddr, $abook->localbackend);
  172. }
  173. /* Handle error messages */
  174. if (!$r) {
  175. /* Remove backend name from error string */
  176. $errstr = $abook->error;
  177. $errstr = preg_replace ('/^\[.*\] */', '', $errstr);
  178. $formerror = $errstr;
  179. $showaddrlist = false;
  180. $defdata = $addaddr;
  181. }
  182. } else {
  183. /************************************************
  184. * Delete address(es) *
  185. ************************************************/
  186. if ((!empty($deladdr)) && sizeof ($sel) > 0) {
  187. $orig_sel = $sel;
  188. sort ($sel);
  189. /* The selected addresses are identidied by "backend:nickname". *
  190. * Sort the list and process one backend at the time */
  191. $prevback = -1;
  192. $subsel = array();
  193. $delfailed = false;
  194. for ($i = 0 ; (($i < sizeof ($sel)) && !$delfailed) ; $i++) {
  195. list($sbackend, $snick) = explode (':', $sel[$i], 2);
  196. /* When we get to a new backend, process addresses in *
  197. * previous one. */
  198. if ($prevback != $sbackend && $prevback != -1) {
  199. $r = $abook->remove($subsel, $prevback);
  200. if (!$r) {
  201. $formerror = $abook->error;
  202. $i = sizeof ($sel);
  203. $delfailed = true;
  204. break;
  205. }
  206. $subsel = array();
  207. }
  208. /* Queue for processing */
  209. array_push ($subsel, $snick);
  210. $prevback = $sbackend;
  211. }
  212. if (!$delfailed) {
  213. $r = $abook->remove($subsel, $prevback);
  214. if (!$r) { /* Handle errors */
  215. $formerror = $abook->error;
  216. $delfailed = true;
  217. }
  218. }
  219. if ($delfailed) {
  220. $showaddrlist = true;
  221. $defselected = $orig_sel;
  222. }
  223. /************************************************
  224. * Compose to selected address(es) *
  225. ************************************************/
  226. } else if ((!empty($compose_to)) && sizeof ($sel) > 0) {
  227. $orig_sel = $sel;
  228. sort ($sel);
  229. // The selected addresses are identidied by "backend:nickname"
  230. $lookup_failed = false;
  231. $send_to = '';
  232. for ($i = 0 ; (($i < sizeof ($sel)) && !$lookup_failed) ; $i++) {
  233. list($sbackend, $snick) = explode (':', $sel[$i], 2);
  234. $data = $abook->lookup($snick, $sbackend);
  235. if (!$data) {
  236. $formerror = $abook->error;
  237. $lookup_failed = true;
  238. break;
  239. } else {
  240. $addr = $abook->full_address($data);
  241. if (!empty($addr))
  242. $send_to .= $addr . ', ';
  243. }
  244. }
  245. if ($lookup_failed || empty($send_to)) {
  246. $showaddrlist = true;
  247. $defselected = $sel;
  248. // we skipped the page header above for this functionality, so add it here
  249. displayPageHeader ($color, 'None');
  250. }
  251. // send off to compose screen
  252. else {
  253. $send_to = trim ($send_to, ', ');
  254. header ('Location: ' . $base_uri . 'src/compose.php?send_to=' . rawurlencode ($send_to));
  255. exit;
  256. }
  257. } else {
  258. /***********************************************
  259. * Update/modify address *
  260. ***********************************************/
  261. if (!empty($editaddr)) {
  262. /* Stage one: Copy data into form */
  263. if (isset($sel) && sizeof ($sel) > 0) {
  264. if(sizeof ($sel) > 1) {
  265. $formerror = _ ("You can only edit one address at the time");
  266. $showaddrlist = true;
  267. $defselected = $sel;
  268. } else {
  269. $abortform = true;
  270. list($ebackend, $enick) = explode (':', $sel[0], 2);
  271. $olddata = $abook->lookup($enick, $ebackend);
  272. /* Display the "new address" form */
  273. echo addForm ($form_url, 'post', '', '', '', '', TRUE).
  274. html_tag ( 'table',
  275. html_tag ( 'tr',
  276. html_tag ( 'td',
  277. "\n". '<strong>' . _ ("Update address") . '</strong>' ."\n",
  278. 'center', $color[0] )
  279. ),
  280. 'center', '', 'width="100%" ' );
  281. address_form ("editaddr", _ ("Update address"), $olddata);
  282. echo addHidden ('oldnick', $olddata['nickname']).
  283. addHidden ('backend', $olddata['backend']).
  284. addHidden ('doedit', '1').
  285. '</form>';
  286. }
  287. } elseif ($doedit == 1) {
  288. /* Stage two: Write new data */
  289. $newdata = $editaddr;
  290. $r = $abook->modify($oldnick, $newdata, $backend);
  291. /* Handle error messages */
  292. if (!$r) {
  293. /* Display error */
  294. echo html_tag ( 'table',
  295. html_tag ( 'tr',
  296. html_tag ( 'td',
  297. "\n". '<strong><font color="' . $color[2] .
  298. '">' . _ ("ERROR") . ': ' . sm_encode_html_special_chars ($abook->error) . '</font></strong>' ."\n",
  299. 'center' )
  300. ),
  301. 'center', '', 'width="100%"' );
  302. /* Display the "new address" form again */
  303. echo addForm ($form_url, 'post', '', '', '', '', TRUE).
  304. html_tag ( 'table',
  305. html_tag ( 'tr',
  306. html_tag ( 'td',
  307. "\n". '<strong>' . _ ("Update address") . '</strong>' ."\n",
  308. 'center', $color[0] )
  309. ),
  310. 'center', '', 'width="100%"' );
  311. address_form ("editaddr", _ ("Update address"), $newdata);
  312. echo
  313. addHidden ('oldnick', $oldnick).
  314. addHidden ('backend', $backend).
  315. addHidden ('doedit', '1').
  316. "\n" . '</form>';
  317. $abortform = true;
  318. }
  319. } else {
  320. /**
  321. * $editaddr is set, but $sel (address selection in address listing)
  322. * and $doedit (address edit form) are not set.
  323. * Assume that user clicked on "Edit address" without selecting any address.
  324. */
  325. $formerror = _ ("Please select address that you want to edit");
  326. $showaddrlist = true;
  327. } /* end of edit stage detection */
  328. } /* !empty($editaddr) - Update/modify address */
  329. } /* (!empty($deladdr)) && sizeof($sel) > 0 - Delete address(es)
  330. or (!empty($compose_to)) && sizeof($sel) > 0 - Compose to address(es) */
  331. } /* !empty($addaddr['nickname']) - Add new address */
  332. // Some times we end output before forms are printed
  333. if($abortform) {
  334. echo "</body></html>\n";
  335. exit();
  336. }
  337. }
  338. /* =================================================================== *
  339. * The following is only executed on a GET request, or on a POST when *
  340. * a user is added, or when "delete" or "modify" was successful. *
  341. * =================================================================== */
  342. /* Display error messages */
  343. if (!empty($formerror)) {
  344. echo html_tag ( 'table',
  345. html_tag ( 'tr',
  346. html_tag ( 'td',
  347. "\n". '<br /><strong><font color="' . $color[2] .
  348. '">' . _ ("ERROR") . ': ' . sm_encode_html_special_chars ($formerror) . '</font></strong>' ."\n",
  349. 'center' )
  350. ),
  351. 'center', '', 'width="100%"' );
  352. }
  353. /* Display the address management part */
  354. if ($showaddrlist) {
  355. /* Get and sort address list */
  356. $alist = $abook->list_addr();
  357. if(!is_array ($alist)) {
  358. $abook->error = sm_encode_html_special_chars ($abook->error);
  359. plain_error_message ($abook->error, $color);
  360. exit;
  361. }
  362. usort ($alist,'alistcmp');
  363. // filter listing as needed
  364. $hook_return = do_hook_function ('abook_list_filter', $alist);
  365. if (!empty($hook_return)) $alist = $hook_return;
  366. $prevbackend = -1;
  367. $headerprinted = false;
  368. $compose_to_in_new_window_javascript = ' onclick="var send_to = \'\'; var f = document.forms.length; var i = 0; var grab_next_hidden = \'\'; while (i < f) { var e = document.forms[i].elements.length; var j = 0; while (j < e) { if (document.forms[i].elements[j].type == \'checkbox\' && document.forms[i].elements[j].checked) { var pos = document.forms[i].elements[j].value.indexOf(\':\'); if (pos >= 1) { grab_next_hidden = document.forms[i].elements[j].value; } } else if (document.forms[i].elements[j].type == \'hidden\' && grab_next_hidden == document.forms[i].elements[j].name) { if (send_to != \'\') { send_to += \', \'; } send_to += document.forms[i].elements[j].value; } j++; } i++; } if (send_to != \'\') { comp_in_new(\''. $base_uri . 'src/compose.php?send_to=\' + send_to); } return false;"';
  369. echo html_tag ( 'div', '<a href="#AddAddress">' . _ ("Add address") . '</a>', 'center' ) . "\n";
  370. /* List addresses */
  371. if (count ($alist) > 0) {
  372. echo addForm ($form_url, 'post', 'address_book_form', '', '', '', TRUE);
  373. if ($abook->add_extra_field) {
  374. $abook_fields = 6;
  375. } else {
  376. $abook_fields = 5;
  377. }
  378. $count = 0;
  379. while(list($undef,$row) = each ($alist)) {
  380. /* New table header for each backend */
  381. if($prevbackend != $row['backend']) {
  382. if($prevbackend < 0) {
  383. echo html_tag ( 'table',
  384. html_tag ( 'tr',
  385. html_tag ( 'td',
  386. addSubmit (_ ("Edit selected"), 'editaddr').
  387. addSubmit (_ ("Delete selected"), 'deladdr').
  388. addSubmit (_ ("Compose to selected"), 'compose_to',
  389. ($javascript_on && $compose_new_win ? $compose_to_in_new_window_javascript : '')),
  390. 'center', '', "colspan=\"$abook_fields\"" )
  391. ) .
  392. html_tag ( 'tr',
  393. html_tag ( 'td', '&nbsp;<br />', 'center', '', 'colspan="5"' )
  394. ),
  395. 'center' );
  396. }
  397. echo html_tag ( 'table',
  398. html_tag ( 'tr',
  399. html_tag ( 'td', "\n" . '<strong>' . $row['source'] . '</strong>' . "\n", 'center', $color[0], 'colspan="2"' )
  400. ).
  401. concat_hook_function ('address_book_header', $row),
  402. 'center', '', 'width="95%"' ) ."\n".
  403. html_tag ( 'table', '', 'center', '', 'border="0" cellpadding="1" cellspacing="0" width="90%"' ) .
  404. html_tag ( 'tr', "\n" .
  405. html_tag ( 'th', '&nbsp;', 'left', '', 'width="1%"' ) .
  406. html_tag ( 'th', _ ("Nickname") .
  407. show_abook_sort_button ($abook_sort_order, _ ("sort by nickname"), 0, 1),
  408. 'left', '', 'width="10%"' ) .
  409. html_tag ( 'th', _ ("Name") .
  410. show_abook_sort_button ($abook_sort_order, _ ("sort by name"), 2, 3),
  411. 'left', '', 'width="10%"' ) .
  412. html_tag ( 'th', _ ("E-mail").
  413. show_abook_sort_button ($abook_sort_order, _ ("sort by email"), 4, 5),
  414. 'left', '', 'width="10%"' ) .
  415. html_tag ( 'th', _ ("Info").
  416. show_abook_sort_button ($abook_sort_order, _ ("sort by info"), 6, 7),
  417. 'left', '', 'width="10%"' ) .
  418. ($abook->add_extra_field ? html_tag ( 'th', '&nbsp;','left', '', 'width="1%0"'): ''),
  419. '', $color[9] ) . "\n";
  420. $line = 0;
  421. $headerprinted = true;
  422. } /* End of header */
  423. $prevbackend = $row['backend'];
  424. /* Print one row, with alternating color */
  425. if ($line % 2) {
  426. $tr_bgcolor = $color[12];
  427. } else {
  428. $tr_bgcolor = $color[4];
  429. }
  430. // Print special message if that's what we have
  431. // here instead of an actual address entry
  432. if (!empty($row['special_message'])) {
  433. echo html_tag ('tr', '', '', $tr_bgcolor)
  434. . html_tag ('td', $row['special_message'], 'center', '', 'colspan="5"')
  435. . "</tr>\n";
  436. $line++;
  437. continue;
  438. }
  439. /* Check if this user is selected */
  440. $selected = in_array ($row['backend'] . ':' . $row['nickname'], $defselected);
  441. if ($squirrelmail_language == 'ja_JP') {
  442. echo html_tag ( 'tr', '', '', $tr_bgcolor);
  443. if ($abook->backends[$row['backend']]->writeable) {
  444. echo html_tag ( 'td',
  445. '<small>' .
  446. addCheckBox ('sel[' . $count . ']', $selected, $row['backend'].':'.$row['nickname'], ' id="' . $row['backend'] . '_' . urlencode ($row['nickname']) . '"').
  447. '</small>' ,
  448. 'center', '', 'valign="top" width="1%"' );
  449. } else {
  450. echo html_tag ( 'td',
  451. '&nbsp;' ,
  452. 'center', '', 'valign="top" width="1%"' );
  453. }
  454. echo html_tag ( 'td', '&nbsp;<label for="' . $row['backend'] . '_' . urlencode ($row['nickname']) . '">' . sm_encode_html_special_chars ($row['nickname']) . '</label>&nbsp;', 'left', '', 'valign="top" width="10%" nowrap' ) .
  455. html_tag ( 'td', '&nbsp;<label for="' . $row['backend'] . '_' . urlencode ($row['nickname']) . '">' . sm_encode_html_special_chars ($row['lastname']) . ' ' . sm_encode_html_special_chars ($row['firstname']) . '</label>&nbsp;', 'left', '', 'valign="top" width="10%" nowrap' ) .
  456. html_tag ( 'td', '', 'left', '', 'valign="top" width="10%" nowrap' ) . '&nbsp;';
  457. } else {
  458. echo html_tag ( 'tr', '', '', $tr_bgcolor);
  459. if ($abook->backends[$row['backend']]->writeable) {
  460. echo html_tag ( 'td',
  461. '<small>' .
  462. addCheckBox ('sel[' . $count . ']', $selected, $row['backend'] . ':' . $row['nickname'], ' id="' . $row['backend'] . '_' . urlencode ($row['nickname']) . '"').
  463. '</small>' ,
  464. 'center', '', 'valign="top" width="1%"' );
  465. } else {
  466. echo html_tag ( 'td',
  467. '&nbsp;' ,
  468. 'center', '', 'valign="top" width="1%"' );
  469. }
  470. echo html_tag ( 'td', '&nbsp;<label for="' . $row['backend'] . '_' . urlencode ($row['nickname']) . '">' . sm_encode_html_special_chars ($row['nickname']) . '</label>&nbsp;', 'left', '', 'valign="top" width="10%" nowrap' ) .
  471. html_tag ( 'td', '&nbsp;<label for="' . $row['backend'] . '_' . urlencode ($row['nickname']) . '">' . sm_encode_html_special_chars ($row['name']) . '</label>&nbsp;', 'left', '', 'valign="top" width="10%" nowrap' ) .
  472. html_tag ( 'td', '', 'left', '', 'valign="top" width="10%" nowrap' ) . '&nbsp;';
  473. }
  474. $email = $abook->full_address($row);
  475. echo addHidden ($row['backend'] . ':' . $row['nickname'], rawurlencode ($email))
  476. . makeComposeLink ('src/compose.php?send_to='.rawurlencode ($email),
  477. sm_encode_html_special_chars ($row['email'])).
  478. '&nbsp;</td>'."\n".
  479. html_tag ( 'td', '&nbsp;<label for="' . $row['backend'] . '_' . urlencode ($row['nickname']) . '">' . sm_encode_html_special_chars ($row['label']) . '</label>&nbsp;', 'left', '', 'valign="top" width="10%"' );
  480. // add extra column if third party backend needs it
  481. if ($abook->add_extra_field) {
  482. echo html_tag ( 'td',
  483. '&nbsp;' . (isset($row['extra']) ? $row['extra'] : '') . '&nbsp;',
  484. 'left', '', 'valign="top" width="10%"' );
  485. }
  486. echo "</tr>\n";
  487. $line++;
  488. $count++;
  489. }
  490. /* End of list. Close table. */
  491. if ($headerprinted) {
  492. echo html_tag ( 'tr',
  493. html_tag ( 'td',
  494. addSubmit (_ ("Edit selected"), 'editaddr') .
  495. addSubmit (_ ("Delete selected"), 'deladdr').
  496. addSubmit (_ ("Compose to selected"), 'compose_to',
  497. ($javascript_on && $compose_new_win ? $compose_to_in_new_window_javascript : '')),
  498. 'center', '', "colspan=\"$abook_fields\"" )
  499. );
  500. }
  501. echo '</table></form>';
  502. }
  503. } /* end of addresslist */
  504. /* Display the "new address" form */
  505. echo '<a name="AddAddress"></a>' . "\n" .
  506. addForm ($form_url, 'post', 'f_add', '', '', '', TRUE).
  507. html_tag ( 'table',
  508. html_tag ( 'tr',
  509. html_tag ( 'td', "\n". '<strong>' . sprintf (_ ("Add to %s"), $abook->localbackendname) . '</strong>' . "\n",
  510. 'center', $color[0]
  511. )
  512. )
  513. , 'center', '', 'width="95%"' ) ."\n";
  514. address_form ('addaddr', _ ("Add address"), $defdata);
  515. echo "</form>\n";
  516. /* Add hook for anything that wants on the bottom */
  517. do_hook ('addressbook_bottom');
  518. ?>
  519. </body></html>

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

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