2 /************************************************************************
3 * MXChange v0.2.1 Start: 10/19/2003 *
4 * =============== Last change: 08/26/2004 *
6 * -------------------------------------------------------------------- *
7 * File : what-order.php *
8 * -------------------------------------------------------------------- *
9 * Short description : Order mails here *
10 * -------------------------------------------------------------------- *
11 * Kurzbeschreibung : Hier koennen Ihre Mitglieder Mails buchen *
12 * -------------------------------------------------------------------- *
15 * $Tag:: 0.2.1-FINAL $ *
17 * Needs to be in all Files and every File needs "svn propset *
18 * svn:keywords Date Revision" (autoprobset!) at least!!!!!! *
19 * -------------------------------------------------------------------- *
20 * Copyright (c) 2003 - 2009 by Roland Haeder *
21 * For more information visit: http://www.mxchange.org *
23 * This program is free software; you can redistribute it and/or modify *
24 * it under the terms of the GNU General Public License as published by *
25 * the Free Software Foundation; either version 2 of the License, or *
26 * (at your option) any later version. *
28 * This program is distributed in the hope that it will be useful, *
29 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
30 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
31 * GNU General Public License for more details. *
33 * You should have received a copy of the GNU General Public License *
34 * along with this program; if not, write to the Free Software *
35 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, *
37 ************************************************************************/
39 // Some security stuff...
40 if (!defined('__SECURITY')) {
42 } elseif (!isMember()) {
43 redirectToIndexMemberOnlyModule();
46 // Add description as navigation point
47 addMenuDescription('member', __FILE__);
49 if ((!isExtensionActive('order')) && (!isAdmin())) {
50 loadTemplate('admin_settings_saved', false, generateExtensionInactiveNotInstalledMessage('order'));
55 $whereStatement = " WHERE `visible`='Y'";
57 // Set undefined array elements
58 if (isAdmin()) $whereStatement = '';
60 // Minimum mails / order
61 $content['min'] = getConfig('order_min');
63 // Count unconfirmed mails
64 $links = countSumTotalData(getUserId(), 'user_links', 'id', 'userid', true);
66 // Does the user has more than 0 mails per day set?
68 if ((isExtensionActive('holiday')) && (getExtensionVersion('holiday') >= '0.1.3')) {
69 // Fetch also holiday activation data
70 $HOLIDAY = '`holiday_active`';
73 $result_mmails = SQL_QUERY_ESC("SELECT `userid`, `receive_mails`, `mail_orders`, ".$HOLIDAY."
74 FROM `{?_MYSQL_PREFIX?}_user_data`
75 WHERE `userid`=%s AND `max_mails` > 0 LIMIT 1",
76 array(getUserId()), __FILE__, __LINE__);
78 $mmails = SQL_NUMROWS($result_mmails);
79 list($DMY, $MAXI, $ORDERS, $HOLIDAY) = SQL_FETCHROW($result_mmails);
80 SQL_FREERESULT($result_mmails);
81 if ($HOLIDAY == $DMY) $HOLIDAY='N';
83 $ALLOWED = $MAXI - $ORDERS;
84 if (getConfig('order_max_full') == 'MAX') $ALLOWED = $MAXI;
86 // Now check his points amount
87 $total = countSumTotalData(getUserId(), 'user_points', 'points') - countSumTotalData(getUserId(), 'user_data', 'used_points');;
89 if (($HOLIDAY == 'Y') && (getExtensionVersion('holiday') >= '0.1.3')) {
91 loadTemplate('admin_settings_saved', false, getMessage('HOLIDAY_ORDER_NOT_POSSIBLE'));
92 } elseif ((isPostRequestElementSet(('frametester'))) && ($ALLOWED > 0) && (postRequestElement('receiver') > 0)) {
93 // Continue with the frametester, we first need to store the data temporary in the pool
95 // First we would like to store the data and get it's pool position back...
96 $result = SQL_QUERY_ESC("SELECT `id`, `data_type`
98 `{?_MYSQL_PREFIX?}_pool`
100 `sender`=%s AND `url`='%s' AND `timestamp` > (UNIX_TIMESTAMP() - %s)
104 postRequestElement('url'),
105 getConfig('url_tlock')
106 ), __FILE__, __LINE__);
108 $type = 'TEMP'; $id = 0;
109 if (SQL_NUMROWS($result) == 1) {
110 // Load id and mail type
111 list($id, $type) = SQL_FETCHROW($result);
115 SQL_FREERESULT($result);
117 if ($type == 'TEMP') {
118 // No entry found, so we need to check out the stats table as well... :)
119 // We have to add that suff here, now we continue WITHOUT checking and check the text and subject against some filters
121 if (getConfig('test_text') == 'Y') {
122 // Test submitted text against some filters (length, URLs in text etc.)
123 if ((strpos(strtolower(postRequestElement('text')), "https://") > -1) || (strpos(strtolower(postRequestElement('text')), 'http://') > -1) || (strpos(strtolower(postRequestElement('text')), "www") > -1)) {
125 $URL = 'modules.php?module=login&what=order&code=' . getCode('URL_FOUND');
128 // Remove new-line and carriage-return characters
129 $TEST = str_replace("\n", '', str_replace("\r", '', postRequestElement('text')));
131 // Text length within allowed length?
132 if (strlen($TEST) > getConfig('max_tlength')) {
134 $URL = 'modules.php?module=login&what=order&code=' . getCode('OVERLENGTH');
138 // Shall I test the subject line against URLs?
139 if (getConfig('test_subj') == 'Y') {
140 // Check the subject line for issues
141 setRequestPostElement('subject', str_replace("\\", '[nl]', substr(postRequestElement('subject'), 0, 200)));
142 if ((strpos(strtolower(postRequestElement('subject')), 'http://') > -1) || (strpos(strtolower(postRequestElement('subject')), "www") > -1)) {
143 // URL in subject found
144 $URL = 'modules.php?module=login&what=order&code=' . getCode('SUBJ_URL');
148 // And shall I check that his URL is not in the black list?
149 if (getConfig('url_blacklist') == 'Y') {
150 // Ok, I do that for you know...
151 $result = SQL_QUERY_ESC("SELECT UNIX_TIMESTAMP(`timestamp`) AS tstamp FROM `{?_MYSQL_PREFIX?}_url_blacklist` WHERE `url`='%s' LIMIT 1",
152 array(postRequestElement('url')), __FILE__, __LINE__);
154 if (SQL_NUMROWS($result) == 1) {
155 // Jupp, we got one listed
156 list($blist) = SQL_FETCHROW($result);
158 // Create redirect-URL
159 $URL = 'modules.php?module=login&what=order&code=' . getCode('BLIST_URL') . '&blist=' . $blist;
163 SQL_FREERESULT($result);
166 // Enougth receivers entered?
167 if ((postRequestElement('receiver') < getConfig('order_min')) && (!isAdmin())) {
168 // Less than allowed receivers entered!
169 $URL = 'modules.php?module=login&what=order&code=' . getCode('MORE_RECEIVERS3');
173 if (!isUrlValid(postRequestElement('url'))) {
175 $URL = 'modules.php?module=login&what=order&code=' . getCode('INVALID_URL');
178 // Probe for HTML extension
179 if (isExtensionActive('html_mail')) {
180 // HTML or regular text mail?
181 if (postRequestElement('html') == 'Y') {
182 // Chek for valid HTML tags
183 setRequestPostElement('text', checkHtmlTags(postRequestElement('text')));
185 // Maybe invalid tags found?
186 if (!isPostRequestElementSet('text')) $URL = 'modules.php?module=login&what=order&code=' . getCode('INVALID_TAGS')."&id=".$id;
188 // Remove any HTML code
189 setRequestPostElement('text', str_replace('<', '{OPEN_HTML}', str_replace('>', '{CLOSE_HTML}', postRequestElement('text'))));
192 } elseif (!isAdmin()) {
193 // He has already sent a mail within a specific time
194 $URL = 'modules.php?module=login&what=order&code=' . getCode('URL_TLOCK') . '&id=' . $id;
199 // Check if category and number of receivers is okay
201 if ((getConfig('order_multi_page') == 'Y') && (isPostRequestElementSet('zip'))) {
202 // Choose recipients by ZIP code
203 $add = " AND d.zip LIKE '".bigintval(postRequestElement('zip'))."{PER}'";
207 $result = SQL_QUERY_ESC("SELECT
210 `{?_MYSQL_PREFIX?}_user_cats` AS c
212 `{?_MYSQL_PREFIX?}_user_data` AS d
216 c.cat_id=%s AND c.userid != '%s' AND d.`status`='CONFIRMED' AND d.receive_mails > 0".$add."
220 bigintval(postRequestElement('cat')),
222 getConfig('order_select'),
223 getConfig('order_mode'),
224 ), __FILE__, __LINE__);
226 // Do we enougth receivers left?
227 if (SQL_NUMROWS($result) >= postRequestElement('receiver')) {
228 // Check for holiday extensions
230 if (getExtensionVersion('holiday') >= '0.1.3') {
231 // Include checking for users in holiday
235 // Load receivers from database
236 $TEST = array(); $cnt = 0;
237 while ($content = SQL_FETCHARRAY($result)) {
239 // Check for his holiday status
240 $result_holiday = SQL_QUERY_ESC("SELECT
243 `{?_MYSQL_PREFIX?}_user_holidays`
245 `userid`=%s AND `holiday_start` < UNIX_TIMESTAMP() AND `holiday_end` > UNIX_TIMESTAMP()
247 array(bigintval($content['userid'])), __FILE__, __LINE__);
248 if (SQL_NUMROWS($result_holiday) == 1) $content['userid'] = 0; // Exclude user who are in holiday
251 SQL_FREERESULT($result_holiday);
254 if ($content['userid'] > 0) {
256 $TEST[] = $content['userid'];
262 SQL_FREERESULT($result);
264 // Implode array into string for the sending pool
265 $RECEIVER = implode($TEST, ';');
267 // Count array for maximum sent
268 $MAX_SEND = count($TEST);
270 // Update receiver list
271 SQL_QUERY_ESC("UPDATE `{?_MYSQL_PREFIX?}_user_data` SET `receive_mails`=`receive_mails`-1 WHERE `userid` IN (%s) LIMIT %s",
272 array(str_replace(';', ", ", $RECEIVER), $MAX_SEND), __FILE__, __LINE__);
274 // Is calculated max receivers larger than wanted receivers then reset it
275 if ($MAX_SEND > postRequestElement('receiver')) $MAX_SEND = bigintval(postRequestElement('receiver'));
277 // Calculate used points
278 $USED = $MAX_SEND * getPaymentPoints(bigintval(postRequestElement('type')));
280 // Fix empty zip code
281 if (!isPostRequestElementSet('zip')) setRequestPostElement('zip', '0');
283 // Check if he has enougth points for this order and selected more than 0 receivers
284 if (($USED > 0) && ($USED <= $total) && ($MAX_SEND > 0)) {
285 // Gettings points is okay, so we can add $USED later from
287 if (($id == '0') || ($type != 'TEMP')) {
290 if (isExtensionActive('html_mail')) {
291 // HTML extension is active
292 SQL_QUERY_ESC("INSERT INTO `{?_MYSQL_PREFIX?}_pool` (`sender`, `subject`, `text`, `receivers`, `payment_id`, `data_type`, `timestamp`, `url`, `cat_id`, `target_send`, `zip`, `html_msg`)
293 VALUES ('%s','%s','%s','%s','%s','TEMP','%s','%s','%s','%s','%s','%s')",
296 postRequestElement('subject'),
297 postRequestElement('text'),
299 bigintval(postRequestElement('type')),
301 postRequestElement('url'),
302 bigintval(postRequestElement('cat')),
304 bigintval(postRequestElement('zip')),
305 postRequestElement('html')
306 ), __FILE__, __LINE__);
308 // No HTML extension is active
309 SQL_QUERY_ESC("INSERT INTO `{?_MYSQL_PREFIX?}_pool` (`sender`, `subject`, `text`, `receivers`, `payment_id`, `data_type`, `timestamp`, `url`, `cat_id`, `target_send`, `zip`)
310 VALUES ('%s','%s','%s','%s','%s','TEMP','%s','%s','%s','%s','%s')",
313 postRequestElement('subject'),
314 postRequestElement('text'),
316 bigintval(postRequestElement('type')),
318 postRequestElement('url'),
319 bigintval(postRequestElement('cat')),
321 bigintval(postRequestElement('zip')),
322 ), __FILE__, __LINE__);
325 // Change current order
326 if (isExtensionActive('html_mail')) {
327 // HTML extension is active
328 SQL_QUERY_ESC("UPDATE
329 `{?_MYSQL_PREFIX?}_pool`
335 `timestamp`=UNIX_TIMESTAMP(),
345 postRequestElement('subject'),
346 postRequestElement('text'),
348 bigintval(postRequestElement('type')),
349 postRequestElement('url'),
350 bigintval(postRequestElement('cat')),
352 bigintval(postRequestElement('zip')),
353 postRequestElement('html'),
355 ), __FILE__, __LINE__);
357 // No HTML extension is active
358 SQL_QUERY_ESC("UPDATE
359 `{?_MYSQL_PREFIX?}_pool`
365 `timestamp`=UNIX_TIMESTAMP(),
374 postRequestElement('subject'),
375 postRequestElement('text'),
377 bigintval(postRequestElement('type')),
378 postRequestElement('url'),
379 bigintval(postRequestElement('cat')),
381 bigintval(postRequestElement('zip')),
383 ), __FILE__, __LINE__);
387 // Do we need to get the ID number?
389 // Order is placed as temporary. We need to get it's id for the frametester
390 $result = SQL_QUERY_ESC("SELECT `id` FROM `{?_MYSQL_PREFIX?}_pool` WHERE `sender`=%s AND `subject`='%s' AND `payment_id`=%s AND `data_type`='TEMP' AND `timestamp`=%s LIMIT 1",
393 postRequestElement('subject'),
394 bigintval(postRequestElement('type')),
396 ), __FILE__, __LINE__);
398 list($id) = SQL_FETCHROW($result);
399 SQL_FREERESULT($result);
402 // ID is received so we can redirect the user, used points will be added when he send's out the mail
403 $URL = 'modules.php?module=frametester&order=' . $id;
404 } elseif ($MAX_SEND == 0) {
405 // Not enougth receivers found which can receive mails
406 $URL = 'modules.php?module=login&what=order&code=' . getCode('MORE_RECEIVERS2');
408 // No enougth points left!
409 $URL = 'modules.php?module=login&what=order&code=' . getCode('MORE_POINTS');
412 // Ordered more mails than he can send in this category
413 $URL = 'modules.php?module=login&what=order&code=' . getCode('NO_RECS_LEFT');
416 } elseif (postRequestElement('receiver') == '0') {
417 // Not enougth receivers selected
418 $URL = 'modules.php?module=login&what=order&code=' . getCode('MORE_RECEIVERS1');
419 } elseif (($ALLOWED == 0) && (getConfig('order_max_full') == 'ORDER')) {
420 // No more mail orders allowed
421 loadTemplate('admin_settings_saved', false, getMessage('MEMBER_ORDER_ALLOWED_EXHAUSTED'));
422 } elseif (($links < getConfig('unconfirmed')) && ($mmails == '1')) {
423 // Display order form
424 $result_cats = SQL_QUERY("SELECT
427 `{?_MYSQL_PREFIX?}_cats`
430 `sort` ASC", __FILE__, __LINE__);
431 if (SQL_NUMROWS($result_cats) > 0) {
433 // Initialize array...
440 // Enable HTML checking
441 // @TODO Rewrite this to a filter
442 $HTML = ''; $HOLIDAY = false; $HOL_STRING = '';
443 if ((isExtensionActive('html_mail')) && (postRequestElement('html') == 'Y')) $HTML = " AND `html`='Y'";
444 if (getExtensionVersion('holiday') >= '0.1.3') {
445 // Extension's version is fine
446 $HOLIDAY = true; $HOL_STRING = " AND `holiday_active`='N'";
449 // ... and begin loading stuff
450 while ($content = SQL_FETCHARRAY($result_cats)) {
451 $CATS['id'][] = bigintval($content['id']);
452 $CATS['name'][] = $content['cat'];
454 // Select users in current category
455 $result_userids = SQL_QUERY_ESC("SELECT `userid` FROM `{?_MYSQL_PREFIX?}_user_cats` WHERE `cat_id`=%s AND `userid` != '%s' ORDER BY `userid` ASC",
456 array(bigintval($content['id']), getUserId()), __FILE__, __LINE__);
459 while (list($ucat) = SQL_FETCHROW($result_userids)) {
460 // Check for holiday system
463 // Check user's holiday status
464 $result_holiday = SQL_QUERY_ESC("SELECT
465 d.userid FROM `{?_MYSQL_PREFIX?}_user_data` AS d
467 `{?_MYSQL_PREFIX?}_user_holidays` AS h
471 d.userid=%s AND d.receive_mails > 0 AND d.`status`='CONFIRMED' AND d.`holiday_active`='Y' AND
472 h.holiday_start < UNIX_TIMESTAMP() AND h.holiday_end > UNIX_TIMESTAMP()
474 array(bigintval($ucat)), __FILE__, __LINE__);
476 // Is holiday is active?
477 $HOL_ACTIVE = (SQL_NUMROWS($result_holiday) == 1);
480 SQL_FREERESULT($result_holiday);
483 if ($HOL_ACTIVE === false) {
484 // Check if the user want's to receive mails?
485 $result_ver = SQL_QUERY_ESC("SELECT `zip` FROM `{?_MYSQL_PREFIX?}_user_data` WHERE `userid`=%s".$HTML." AND `receive_mails` > 0 AND `status`='CONFIRMED' LIMIT 1",
486 array(bigintval($ucat)), __FILE__, __LINE__);
488 if ((SQL_NUMROWS($result_ver) == 1) && (isPostRequestElementSet('zip')) && (getConfig('order_multi_page') == 'Y')) {
489 list($zip) = SQL_FETCHROW($result_ver);
490 SQL_FREERESULT($result_ver);
491 if (substr($zip, 0, strlen(postRequestElement('zip'))) == postRequestElement('zip')) {
492 // Ok, ZIP part is found
497 $userid_cnt += SQL_NUMROWS($result_ver);
503 SQL_FREERESULT($result_userids);
504 $CATS['userids'][] = $userid_cnt;
508 SQL_FREERESULT($result_cats);
510 // Now we need to load the mail types...
511 $result = SQL_QUERY("SELECT `id`, `price`, `payment`, `mail_title` FROM `{?_MYSQL_PREFIX?}_payments` ORDER BY `payment` ASC", __FILE__, __LINE__);
514 if (SQL_NUMROWS($result) > 0) {
515 // Check for message ID in URL
516 $message = getMessageFromErrorCode(getRequestElement('code'));
518 if (!empty($message)) {
519 // We got system message so we drop it out to the user
520 loadTemplate('admin_settings_saved', false, $message);
523 // Load all email types...
524 while ($typeS[] = SQL_FETCHROW($result)) {
525 // Nothing to do here... ;-)
529 SQL_FREERESULT($result);
531 // Output user's points
532 $content['total'] = translateComma($total);
534 // Check how many mail orders he has placed today and how many he's allowed to send
535 switch (getConfig('order_max_full')) {
536 case 'MAX': // He is allowed to send as much as possible
537 $content['order_max_full'] = getMessage('MEMBER_ORDER_ALLOWED_MAX');
540 case 'ORDER': // He is allowed to send as much as he setup the receiving value
541 $content['order_max_full'] = sprintf(getMessage('MEMBER_ORDER_ALLOWED_RECEIVE'), $ALLOWED, $MAXI);
544 default: // Unknown/invalid
545 logDebugMessage(__FILE__, __LINE__, sprintf("Unknown order_mas_full config detected.", getConfig('order_max_full')));
546 $content['order_max_full'] = sprintf(getMessage('MEMBER_ORDER_ALLOWED_UNKNOWN'), getConfig('order_max_full'));
550 // Load final template
551 loadTemplate('member_order_points', false, $content);
559 // Check if we already have an order placed and make it editable
560 $result = SQL_QUERY_ESC("SELECT
561 `subject`, `text`, `payment_id`, `timestamp`, `url`, `target_send`, `cat_id`, `zip`
563 `{?_MYSQL_PREFIX?}_pool`
565 `sender`=%s AND `data_type`='TEMP'
567 array(getUserId()), __FILE__, __LINE__);
569 if (SQL_NUMROWS($result) == 1) {
571 $content = SQL_FETCHARRAY($result);
573 // Fix max receivers when it is too much
574 if ((isset($CATS['userids'][$content['cat_id']])) && ($content['target_send'] > $CATS['userids'][$content['cat_id']])) $content['target_send'] = $CATS['userids'][$content['cat_id']];
576 // Old order is grabbed
579 // Default output for that your members don't forget it...
580 $content['url'] = 'http://';
584 SQL_FREERESULT($result);
586 if ((isPostRequestElementSet('data')) || ((getConfig('order_multi_page') != 'Y') && ((!isAdmin()) && (!isExtensionActive('html_mail'))))) {
587 // Pre-output categories
589 foreach ($CATS['id'] as $key => $value) {
590 $CAT .= " <option value=\"".$value."\"";
591 if (($OLD_ORDER) && ($content['cat_id'] == $value)) $CAT .= ' selected="selected"';
592 $CAT .= ">".$CATS['name'][$key]." (".$CATS['userids'][$key]." {--USER_IN_CAT--})</option>\n";
597 foreach ($typeS as $key => $value) {
598 $P = translateComma($typeS[$key][1]);
599 if (is_array($value)) {
600 // Output option line
601 $type .= " <option value=\"".$typeS[$key][0]."\"";
602 if (($OLD_ORDER) && ($content['payment_id'] == $typeS[$key][0])) $type .= ' selected="selected"';
603 $type .= ">".$P." {--PER_MAIL--} - ".$typeS[$key][3]." - ".round($typeS[$key][2])." {--PAYMENT--}</option>\n";
607 // Put all in constants for the template
608 $content['category_selection'] = $CAT;
609 $content['type_selection'] = $type;
611 if (isPostRequestElementSet('zip')) {
612 // Output entered ZIP code
613 $content['zip_content'] = loadTemplate('member_order-zip', true, postRequestElement('zip'));
615 $content['zip_content'] = "<tr><td colspan=\"5\" height=\"5\" class=\"seperator\"> </td></tr>";
619 if ((isExtensionActive('html_mail')) && (postRequestElement('html') == 'Y')) {
620 // Extension is active so output valid HTML tags
621 $content['html_extension'] = loadTemplate('member_order-html_ext', true, addValidHtmlTags());
623 // Extension not active and/or class not uploaded
624 $content['html_extension'] = "<tr><td colspan=\"5\"><input type=\"hidden\" name=\"html\" value=\"N\"> /</td></tr>";
627 // Output form for page 2
628 loadTemplate('member_order_page2');
630 // Remember maybe entered ZIP code in constant
632 if (isExtensionActive('html_mail')) {
633 // Add some content when html extension is active
634 if ((getConfig('order_multi_page') == 'Y') || (isAdmin())) $add = "<tr><td colspan=\"2\" class=\"seperator bottom2\" height=\"5\"> </td></tr>\n";
635 $content['html_extension'] = loadTemplate('member_order-html_intro', true);
637 // No HTML extension installed
638 $content['html_extension'] = "<tr><td colspan=\"2\"><input type=\"hidden\" name=\"html\" value=\"N\" /></td></tr>";
641 // Default is no ZIP code
642 $content['zip_content'] = '';
644 // Do we want ZIP code or not?
645 if ((getConfig('order_multi_page') == 'Y') || (isAdmin())) {
647 if (postRequestElement('zip') > 0) {
649 'zip' => bigintval(postRequestElement('zip')),
658 $content['zip_content'] = loadTemplate('member_order-zip1', true, $data);
661 // Output form for page 1 (ZIP code or HTML)
662 loadTemplate('member_order_page1', false, $content);
665 // No mail types defined
666 loadTemplate('admin_settings_saved', false, "<span class=\"member_failed\">{--MEMBER_NO_PAYMENTS--}</span>");
670 loadTemplate('admin_settings_saved', false, "<span class=\"member_failed\">{--MEMBER_NO_POINTS--}</span>");
673 // No cateogries are defined yet
674 loadTemplate('admin_settings_saved', false, "<span class=\"member_failed\">{--MEMBER_NO_CATS--}</span>");
676 } elseif ($mmails == '0') {
677 // Please set more than 0 mails per day
678 loadTemplate('admin_settings_saved', false, getMessage('MEMBER_HAS_ZERO_MMAILS'));
680 // Please confirm some mails first
681 loadTemplate('admin_settings_saved', false, sprintf(getMessage('MEMBER_LINKS_LEFT'), $links, getConfig('unconfirmed')));
685 // Redirect to requested URL