add-note.php 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581
  1. <?php
  2. require_once('../include/prepend.php');
  3. require_once '../include/shared-manual.inc';
  4. require_once '../include/email-validation.inc';
  5. /*
  6. Unleash this if we want the same layout as phpdoc
  7. if (isset($SIDEBAR_DATA)) {
  8. unset($SIDEBAR_DATA);
  9. }
  10. */
  11. commonHeader('Add Manual Note');
  12. ?>
  13. <SCRIPT LANGUAGE="JavaScript" TYPE="text/javascript">
  14. <!--
  15. function check_email() {
  16. if (document.msgform.email.value != '') {
  17. return window.confirm('Please confirm that the email address given is valid');
  18. }
  19. return true;
  20. }
  21. //-->
  22. </SCRIPT>
  23. <?php
  24. $referer = isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : null;
  25. $referrer = isset($_POST['referer']) ? trim($_POST['referer']) : $referer;
  26. if (!$referrer) {
  27. if (isset($_GET['ref'])) {
  28. $referrer = $_GET['ref'];
  29. } else {
  30. /* no idea how this person got here */
  31. header("Location: /");
  32. exit;
  33. }
  34. }
  35. /* better check it, eh? */
  36. $referrer = htmlentities(strip_tags($referrer));
  37. $real = $_SERVER['DOCUMENT_ROOT'];
  38. $real .= str_replace('http://'.$_SERVER['HTTP_HOST'], '', $referrer);
  39. if (!file_exists($real)) {
  40. header("Location: /");
  41. exit;
  42. }
  43. /* Honour form cancellation */
  44. if (isset($_POST['cancel'])) {
  45. header("Location: $referrer");
  46. exit;
  47. }
  48. /* hide everything while we sort it all out */
  49. if ((file_exists($okfile) || $user = get_user()) && file_exists($notesfile)) {
  50. if (isset($_POST['add']) || isset($_POST['preview'])) {
  51. /* Throw out any attempt at redirection */
  52. $len = strlen($_SERVER['HTTP_HOST']) + 7;
  53. if (substr($referrer, 0, $len) != 'http://'.$_SERVER['HTTP_HOST'] || strstr($referrer, '?')) {
  54. header("Location: $referrer");
  55. exit;
  56. }
  57. /* set globals and initialize a bunch of vars */
  58. $email = stripslashes(trim($_POST['email']));
  59. $content = stripslashes(trim($_POST['note']));
  60. $usename = stripslashes(trim($_POST['name']));
  61. $antispam = $_POST['antispam'];
  62. $ip = $_SERVER['REMOTE_ADDR'];
  63. $flag = null;
  64. $spammer = null;
  65. $subject = null;
  66. $errcode = null;
  67. $errmsg = null;
  68. $display = '';
  69. $urls = 0;
  70. $blanklines = 0;
  71. function force_shuffle($item, &$array) {
  72. if (strlen($item) < 2) {
  73. return $item.'z';
  74. }
  75. $shuffled = str_shuffle($item);
  76. $array[] = $shuffled;
  77. if ($item == $shuffled) {
  78. force_shuffle($item, &$array);
  79. }
  80. $result = $array[sizeof($array)-1];
  81. return $result;
  82. }
  83. /* Figure out what the user wants us to display on the site and store it */
  84. $usename = htmlentities(strip_tags($usename));
  85. $email = htmlentities(strip_tags($email));
  86. if ($antispam == 'usename' && $usename != '') {
  87. $burst = explode(' ', $usename);
  88. foreach($burst as $part) {
  89. $display .= ucfirst($part).' ';
  90. }
  91. $display = trim($display);
  92. } else {
  93. if ($email != '') {
  94. if ($antispam == 'random') {
  95. if (strstr($email, '@')) {
  96. $burst = explode('@', $email);
  97. if (strstr($burst[1], '.')) {
  98. $alter = substr($burst[1], 0, strpos($burst[1], '.'));
  99. $shuffled = force_shuffle($alter, &$result);
  100. $display = $burst[0].'@'.substr_replace($burst[1], $shuffled, 0, strlen($alter));
  101. }
  102. }
  103. }
  104. $display = str_replace('@', ' at ', $display ? $display : $email);
  105. $display = str_replace('.', ' dot ', $display);
  106. if ($antispam == 'nospam') {
  107. $display = str_replace('at ', 'at NOSPAM ', $display);
  108. }
  109. }
  110. }
  111. /* check for/create the queue file */
  112. if (file_exists($queuefile) && filesize($queuefile) < 3000) unlink($queuefile);
  113. clearstatcache();
  114. if (!file_exists($queuefile)) {
  115. $db = sqlite_open($queuefile);
  116. sqlite_query($db,
  117. "BEGIN;
  118. CREATE TABLE notes(
  119. id INTEGER PRIMARY KEY,
  120. page CHAR(100),
  121. lang CHAR(5),
  122. date INT(11),
  123. email CHAR(700),
  124. display CHAR(700),
  125. comment CHAR(4000));
  126. COMMIT;"
  127. );
  128. sqlite_close($db);
  129. }
  130. /* check for/create the last_id file while we're at it */
  131. if (!file_exists($last_id) || !file_get_contents($last_id) || file_get_contents($last_id == '0')) {
  132. $db = sqlite_open($notesfile);
  133. $estimate = sqlite_single_query($db, "SELECT COUNT(*) FROM notes");
  134. $setid = sqlite_query($db, "SELECT id FROM notes WHERE id > '$estimate'", SQLITE_ASSOC);
  135. if ($setid && sqlite_num_rows($setid) > 0)
  136. while (sqlite_valid($setid)) {
  137. $rowid = sqlite_fetch_single($setid);
  138. }
  139. else {
  140. $rowid = $estimate;
  141. }
  142. file_put_contents($last_id, $rowid);
  143. sqlite_close($db);
  144. }
  145. }
  146. /* ============================ PREVIEW ONLY ========================= */
  147. if (isset($_POST['preview'])) {
  148. print "<br />\n<p>\nThis is what your entry will look like, roughly:\n</p>\n";
  149. print "<table border='0' cellpadding='0' cellspacing='0' width='100%' align = 'center'>\n";
  150. $temp = array('display' => $display, 'comment' => htmlentities($content), 'date' => time());
  151. makeEntry($temp, false);
  152. print "</table>\n";
  153. print "<br />\n";
  154. print "<a href = '#notes'>Edit the form</a>\n";
  155. }
  156. /* ========================= ADDING TO DATABASE ====================== */
  157. if (isset($_POST['add'])) {
  158. /* If we have a blacklist running today, check whether the user's IP is in it */
  159. if (file_exists($blockfile)) {
  160. $blocked = file_get_contents($blockfile);
  161. $blacklisted = strstr($blocked, $ip);
  162. if (strlen($blacklisted) > 0) {
  163. $btime = substr($blacklisted, strlen($ip) + 1, 11);
  164. if ($btime > strtotime("1 hour ago")) {
  165. /* Pretty darn sure this is a repeat attack. Fail silently */
  166. $blocked = str_replace($ip, "$ip\n".time()." BANNED (GTK_666)", $blocked);
  167. file_put_contents($blockfile, $blocked);
  168. unset($usename);
  169. unset($email);
  170. unset($content);
  171. header("Location: $referrer");
  172. exit;
  173. }
  174. /* It's possible - if unlikely - DHCP is to blame. So just log and flag it */
  175. $flag = true;
  176. $blocked = str_replace($ip, "$ip\n".time()." DHCP? (GTK_666)", $blocked);
  177. file_put_contents($blockfile, $blocked);
  178. }
  179. }
  180. /* ANTI-SPAM MEASURES (keep updated!) */
  181. /* Very short content - errorcode GTK_111 */
  182. if (strlen($content) < 32) {
  183. $spammer = "GTK_111";
  184. $errmsg = "Your note is too short. Trying to test the notes system? Save us the trouble of deleting your test, and don't. It works.";
  185. }
  186. /* Check data against the 'bad word' list - errorcode GTK_333 */
  187. foreach($badwords as $badword) {
  188. if ($spammer) break;
  189. if (!$spammer && $email) $spammer = stristr($email, $badword);
  190. if (!$spammer) $spammer = stristr($content, $badword);
  191. }
  192. /* Check whether the content is mostly URLs - errorcode GTK_222 */
  193. if (strlen($spammer) == 0) {
  194. $lines = explode("\n", $content);
  195. foreach($lines as $no => $line) {
  196. $line = rtrim($line);
  197. if (preg_match("'(http:\/\/|<a href)'is", $line))
  198. $urls++;
  199. if (strlen($line) < 5)
  200. $blanklines++;
  201. }
  202. if ($urls > (sizeof($lines) - $blanklines) / 2) {
  203. $spammer = "GTK_222";
  204. }
  205. }
  206. if (strlen($spammer) > 0) {
  207. if (!strstr($spammer, 'GTK_')) {
  208. $spammer = "GTK_333";
  209. }
  210. if ($flag) {
  211. /* We're 100% sure it's spam, the guy reached here once already. Fail silently */
  212. file_put_contents($stats, "$spammer:id not assigned, $ip banned\n", FILE_APPEND);
  213. $blocked = file_get_contents($blockfile);
  214. $blocked = str_replace($ip, "$ip\n".time()." BANNED ($spammer)", $blocked);
  215. file_put_contents($blockfile, $blocked);
  216. unset($usename);
  217. unset($email);
  218. unset($content);
  219. header("Location: $referrer");
  220. exit;
  221. }
  222. /* We're 96.7% sure it's spam. Log the IP and print a failure message just in case */
  223. file_put_contents($blockfile, "$ip\n".time()." ($spammer)\n\n", FILE_APPEND);
  224. if (!$errmsg) {
  225. $errmsg = "There was an error processing your submission.<br />\nThe development team have been informed.";
  226. }
  227. print stretchPage(22);
  228. print "<p>\n$errmsg\n</p>\n";
  229. print "<p><a href = '$referrer'>Back</a></p>\n";
  230. print "</div>\n";
  231. commonFooter();
  232. exit;
  233. }
  234. /* DEFENSE AGAINST THE REST */
  235. /* Check we aren't currently being flooded by someone else - errorcode GTK_666 */
  236. if (filemtime($queuefile) > $veryrecent) {
  237. $queuedb = sqlite_open($queuefile);
  238. $result = sqlite_query($queuedb, "SELECT id FROM notes WHERE date > $recent");
  239. $count = sqlite_num_rows($result);
  240. if ((int)$count > $likely) {
  241. $spammer = "GTK_666";
  242. }
  243. sqlite_close($queuedb);
  244. }
  245. /*
  246. * If we got this far all's probably well, so invalid/empty email addresses
  247. * are OK to go. We just tag them to ensure we don't try to mail anything
  248. * out to them at a later stage
  249. */
  250. if (!preg_match($email_regex, $email) || strstr($email, 'lists.php')) {
  251. $email = 'GTK_000'.$email;
  252. }
  253. /* Check and secure contents */
  254. if (strlen($content) > 4096) {
  255. print stretchPage(22);
  256. print "<p>Your note is too long to fit on the manual pages! Please review it and try to make it less verbose.</p>\n";
  257. print "</div>\n";
  258. commonFooter();
  259. exit;
  260. }
  261. $content = htmlentities($content, ENT_COMPAT, 'UTF-8');
  262. /* Pick up id, insert note data into queue and mail out admin notification */
  263. if (!$lastid = file_get_contents($last_id)) {
  264. print stretchPage(22);
  265. print "Could not obtain note ID<br />\n<br />\n";
  266. print "</div>\n";
  267. commonFooter();
  268. exit;
  269. }
  270. $id = $lastid + 1;
  271. $url = explode('/', $referrer);
  272. $lang = $url[sizeof($url) - 2];
  273. $page = $url[sizeof($url) - 1];
  274. $date = time();
  275. $db_string = '("'.$id.'", "'.$page.'", "'.$lang.'", "'.$date.'", "'.$email.'", "'.$display.'", "'.$content.'")';
  276. $db_string = sqlite_escape_string($db_string);
  277. $queuedb = sqlite_open($queuefile);
  278. $result = sqlite_exec($queuedb, "INSERT INTO notes VALUES $db_string");
  279. sqlite_close($queuedb);
  280. if (!file_put_contents($last_id, $id)) {
  281. print stretchPage(22);
  282. print "New note ID not saved<br />\n<br />\n";
  283. print "</div>\n";
  284. commonFooter();
  285. exit;
  286. }
  287. $printmsg = "<p>Thank you for contributing! Your note has been queued for processing";
  288. if (!strstr($email, 'GTK_000')) {
  289. $printmsg .= ", and you will be notified by email when it goes live";
  290. }
  291. $printmsg .= ".</p>\n";
  292. print stretchPage(20);
  293. print $printmsg;
  294. print "<p><a href = '$referrer'>Back</a></p>\n";
  295. print "</div>\n";
  296. commonFooter();
  297. if (!$result) {
  298. /* tell admin there's a problem and create an emergency file to retain the data */
  299. file_put_contents($stats, "GTK_ERROR:$errmsg Backup is in $id.txt\n", FILE_APPEND);
  300. $bytes = file_put_contents(DB_DIR."/$id.txt", $id."\n".$page."\n".$lang."\n".$date."\n".$email."\n".$display."\n".$content."\n\n".$ip);
  301. $msg = "page: $page\n\n$content\n\n$display - ".date('d-M-Y H:i', $date);
  302. if ($mail) mail($mailto, "queue system failed: note $id was backed up ($bytes bytes)", $msg, "From: $mailfrom");
  303. commonFooter();
  304. exit;
  305. }
  306. /* Mail success notification to the list */
  307. $msg = "page: <a href='$referrer'>$page</a>\n\n$content\n\n$display - ".date('d-M-Y H:i', $date);
  308. if ($mail) mail($mailto, "note $id has been queued", $msg, "From: $mailfrom");
  309. /*
  310. * We can't check for the current id without holding up the page for a whole
  311. * unacceptable minute - so we keep the current entry in the queue and
  312. * work with the previous successful queue entry from this point instead
  313. */
  314. $handle = @fsockopen('216.92.131.4', 119, $errno, $errstr, 10);
  315. if ($handle) {
  316. $helo = fgets($handle, 1024);
  317. if (substr($helo, 0, 3) == '200') {
  318. stream_set_timeout($handle, 2);
  319. fputs($handle, "GROUP php.gtk.webmaster\r\n");
  320. $groupinfo = fgets($handle, 1024);
  321. preg_match("'\d{4,6}'is", $groupinfo, $matches, 0, 10);
  322. $last_mail = $matches[0];
  323. fputs($handle, "HEAD $last_mail\r\n");
  324. $headerinfo = fgets($handle, 2048);
  325. while ($line != ".\r\n") {
  326. $line = fgets($handle, 2048);
  327. if (strstr($line, "Subject:")) $subject = $line;
  328. $status = socket_get_status($handle);
  329. if ($status['timed_out']) {
  330. break;
  331. }
  332. }
  333. }
  334. fclose($handle);
  335. }
  336. if ($subject) {
  337. $flag = null;
  338. if (!strstr($subject, "note ".$lastid)) {
  339. /* File an error but hold the data in the queue. errorcode GTK_444 */
  340. file_put_contents($stats, "GTK_444: $lastid held in queue\n", FILE_APPEND);
  341. if (strstr($subject, "note ".$id)) { /* NNTP might have been too fast for us! */
  342. $lastid = $id;
  343. $lastemail = $email;
  344. $lastpage = $page;
  345. $flag = true;
  346. }
  347. } else {
  348. /* If we're working with $lastid, we need to get the data out of the queue db first */
  349. $queuedb = sqlite_open($queuefile);
  350. $query = sqlite_unbuffered_query($db, "SELECT * FROM notes WHERE id = $lastid", SQLITE_ASSOC, &$errcode);
  351. if (!$query || $errcode) {
  352. sqlite_close($queuedb);
  353. file_put_contents($stats, "$errcode:$lastid (failed SQL query)\n", FILE_APPEND);
  354. } else {
  355. $last = sqlite_fetch_array($query, SQLITE_ASSOC);
  356. $lastpage = $last['page'];
  357. $lastemail = $last['email'];
  358. $db_string = '("'.$lastid.'", "'.$lastpage.'", "'.$last['lang'].'", "'.$last['date'].'", "'.$lastemail.'", "'.$last['display'].'", "'.$last['note'].'")';
  359. sqlite_close($queuedb);
  360. $flag = true;
  361. }
  362. }
  363. if ($flag) {
  364. $notesdb = sqlite_open($notesfile);
  365. $result = sqlite_exec($notesdb, "INSERT INTO notes VALUES $db_string");
  366. sqlite_close($notesdb);
  367. if (!$result) {
  368. /* Not being able to write to the notes db is pretty worrying. errorcode GTK_888 */
  369. $errcode = "GTK_888";
  370. file_put_contents($stats, "$errcode:$lastid held in queue (write failed)\n", FILE_APPEND);
  371. } else {
  372. $queuedb = sqlite_open($queuefile);
  373. $result = sqlite_exec($queuedb, "DELETE FROM notes WHERE id = $lastid");
  374. sqlite_close($queuedb);
  375. if (!$result) {
  376. /* Not being able to write to the queue isn't great either. errorcode GTK_777 */
  377. $errcode = "GTK_777";
  378. file_put_contents($stats, "$errcode:$lastid not deleted from queue\n", FILE_APPEND);
  379. }
  380. /* Mail the user to confirm good stuff */
  381. if (($errcode != 'GTK_888' && !strstr($last['email'], "GTK_000")) || isset($_COOKIE[$user])) {
  382. $msg = "Hi\n\nThis is to confirm that your PHP-GTK manual note reached the top of the queue and will be available for viewing shortly at <a href='$referrer'>$referrer</a>.\n\nThank you again for your contribution!\n\nRegards,\nThe PHP-GTK Documentation Group";
  383. if (isset($_COOKIE[$user])) $lastemail = $_COOKIE[$user];
  384. if ($mail) mail($lastemail, "PHP-GTK Manual Note $lastid added", $msg, "From: $mailfrom");
  385. }
  386. if (!$errcode) {
  387. file_put_contents($stats, "GTK_SUCCESS:$lastid\n", FILE_APPEND);
  388. }
  389. }
  390. }
  391. } else { /* no return from NNTP */
  392. file_put_contents($stats, "GTK_444: $lastid held in queue (NNTP response failed)\n", FILE_APPEND);
  393. }
  394. if ($spammer && $errcode) { /* spammer can only be GTK_666 at this stage (flood) */
  395. /* We're being attacked and they've managed to screw up at least one db */
  396. /* use GTK_999 but preserve the original combo so we know where to look */
  397. $msg = "page: <a href='$referrer'>$page</a>\n\n$content\n\n$display - ".date('d-M-Y H:i', $date);
  398. if ($mail) mail($mailto, "GTK_999 notification", $msg, "From: $mailfrom");
  399. exit;
  400. }
  401. if ($spammer) {
  402. file_put_contents($blockfile, "$ip\n".time()." ($spammer: note $id)\n\n", FILE_APPEND);
  403. }
  404. exit;
  405. } else {
  406. /* ======================= FORM NOT FILLED IN YET ==================== */
  407. ?>
  408. <br />
  409. <p>
  410. You can contribute to the PHP-GTK manual from the comfort of your own browser!
  411. Just add your comment in the big field below, and your name and email address
  412. in the little ones.
  413. </p>
  414. <p>
  415. Thanks to all those hard-working spammers out there, you now have several options
  416. when it comes to displaying your email address. By default we will simply replace
  417. the @ signs and dots in it (e.g. 'user@example.com' becomes 'user at example dot
  418. com'), but we can also add various anti-spam measures at your request - including
  419. not displaying it at all. We can only inform you of the progress of your note
  420. throughout its lifetime if you use your real email address when submitting it.
  421. </p>
  422. <p>
  423. We will only display your name if you choose that display option.
  424. </p>
  425. <p>
  426. Your IP address will be logged when your note is submitted and used
  427. during our screening process, but will not be made public at any stage.
  428. </p>
  429. <p>
  430. Note that <b>HTML tags</b> are not allowed in the notes, but formatting
  431. is preserved. URLs signalled by 'http://', 'https://' or 'ftp://' will be
  432. turned into clickable links, and PHP code blocks enclosed in the PHP tags
  433. &lt;?php and ?&gt; will be source highlighted automatically - so always
  434. enclose PHP snippets in those tags. (Double-check that your note appears
  435. as you intend during the preview. That's why the preview button is there!)
  436. </p>
  437. <p>
  438. Please read the following points carefully before submitting your
  439. comment. If your post falls into any of the categories mentioned
  440. there, it will be rejected by one of the editors.
  441. </p>
  442. <ul>
  443. <li>If you are trying to report a bug, or request a new feature,
  444. you're in the wrong place. Bugs (and requests!) should be reported at
  445. <a href="http://bugs.php.net">bugs.php.net</a> as 'PHP-GTK related'.</li>
  446. <li>If you are just commenting on the fact that something is not documented,
  447. save your energy. This is where <b>you</b> add to the documentation, not
  448. where you ask <b>us</b> to add the documentation.</li>
  449. <li>This is also not the correct place to ask questions (even if you see
  450. others have done that before). Support is available through either the
  451. general mailing list or IRC; see our
  452. <a href="http://gtk.php.net/resources.php">resources page</a> for details.</li>
  453. </ul>
  454. <p>
  455. <b>If you post a note in any of the categories above, it will be removed.</b>
  456. However, please feel free to come back and add a note here when your
  457. question is answered or you find a solution to your problem!
  458. </p>
  459. <p>
  460. Please note that there is a chance of the information in the user notes
  461. being incorporated into the manual at a later date. This means that any
  462. note posted here becomes the property of the PHP-GTK Documentation Group.
  463. </p>
  464. <a name = 'notes' />
  465. <form name = 'msgform' action = "<?php echo $_SERVER['PHP_SELF'];?>" method = 'POST'>
  466. <table border='0' cellpadding='3' bgcolor='#e0e0e0' align='center' width=<?php echo isset($SIDEBAR_DATA) ? '90%' : '80%'; ?>>
  467. <tr>
  468. <th colspan='2' align='left'>Please choose a display option for your personal data:</th>
  469. </tr>
  470. <tr>
  471. <td colspan='2'>
  472. <input type="radio" name="antispam" value="standard" <?php if (!isset($_POST['antispam']) || (isset($_POST['antispam']) && $antispam == 'standard')) echo 'checked' ?>> Obfuscate my email address before displaying it, e.g. 'user at example dot com' (default)<br />
  473. </td>
  474. </tr>
  475. <tr>
  476. <td colspan='2'>
  477. <input type="radio" name="antispam" value="nospam" <?php if (isset($_POST['antispam']) && $antispam == 'nospam') echo 'checked' ?>> Add NOSPAM to my email address before displaying it, e.g. 'user at NOSPAM example dot com'<br />
  478. </td>
  479. </tr>
  480. <tr>
  481. <td colspan='2'>
  482. <input type="radio" name="antispam" value="random" <?php if (isset($_POST['antispam']) && $antispam == 'random') echo 'checked' ?>> Randomize part of my email address before displaying it, e.g. 'user at mepelxa dot com'<br />
  483. </td>
  484. </tr>
  485. <tr>
  486. <td colspan='2'>
  487. <input type="radio" name="antispam" value="usename" <?php if (isset($_POST['antispam']) && $antispam == 'usename') echo 'checked' ?>> Display my name instead of my email address, e.g. 'User L. Schmidt'<br />
  488. </td>
  489. </tr>
  490. <tr>
  491. <th align='right'>Your name:</th>
  492. <td><input type='text' name='name' size='40' maxlength='40' value="<?php if (isset($_POST['name'])) echo $usename; ?>"></td>
  493. </tr>
  494. <tr>
  495. <th align='right'>Your email address:</th>
  496. <td><input type='text' name='email' size='40' maxlength='40' value="<?php if (isset($_POST['email'])) echo $email; ?>"></td>
  497. </tr>
  498. <tr>
  499. <th align='right' valign='top'>Your note:</th>
  500. <td>
  501. <textarea name='note' rows='15' cols='65' wrap='soft'><?php if (isset($_POST['note'])) echo $content; ?></textarea>
  502. <br />
  503. </td>
  504. </tr>
  505. <tr>
  506. <td>&nbsp;</td>
  507. <td>
  508. <input type = "hidden" name = "referer" value = "<?php echo $referrer; ?>">
  509. <input type = 'submit' name = 'cancel' value = 'Cancel'>
  510. <input type = 'submit' name = 'preview' value = 'Preview'>
  511. <input type = 'submit' name = 'add' value = 'Add note' onClick = 'return check_email();'>
  512. </td>
  513. </tr>
  514. </table>
  515. </form>
  516. <?php
  517. }
  518. } else {
  519. /* hide everything if the notes mechanism is down */
  520. print stretchPage(22);
  521. print "<p>The PHP-GTK manual notes system is off-line at present. Please try again later!</p>\n";
  522. print "<p><a href = '$referrer'>Back</a></p>\n";
  523. print "</div>\n";
  524. }
  525. commonFooter();
  526. ?>