Jump to content

jay5r

Clients
  • Posts

    42
  • Joined

  • Last visited

 Content Type 

Downloads

Release Notes

IPS4 Guides

IPS4 Developer Documentation

Invision Community Blog

Development Blog

Deprecation Tracker

Providers Directory

Forums

Events

Store

Gallery

Everything posted by jay5r

  1. Given that I'm trying to get other people (who aren't all that technical or patient) to explain the problem to me, using the default theme would be really difficult. But let me look into that a bit more… Someone who is having problems got back to me with the following: I'll continue to let you know as I learn more.
  2. I just had a user report the same problem with Safari on an iPhone 14, so this may not be a problem with older browsers. I've asked for a screenshot and what country he's in since it doesn't seem English is his first language (hence the local date formats may differ from those in the US - even though what the browser is supposed to submit should be standardized).
  3. OK, I'll write a Javascript to test whether a format-based placeholder helps. And FYI - date inputs are only fully supported by ~75% of browsers, with another ~20% having partial support… https://caniuse.com/?search=date input
  4. Date inputs revert to text inputs in older browsers. In those cases telling the user the proper format is essential since the browser isn't formatting it for the user. Can you tell me the format you're expecting on form submission? (YYYY-MM-DD is the most dependable in my experience, but I don't want to make the assumptions that it will work in this case.) I can test this pretty simply by writing a Javascript that changes the placeholder value, but I need to know a format that will work.
  5. One thought… The input element looks like this… Older browsers may not know how to handle date inputs properly. And your placeholder value is "Birthday" rather than a proper date format. Perhaps the solution is to change the placeholder value to specify the correct format (e.g. YYYY-MM-DD, or whatever) so that users with older devices get it entered correctly.
  6. Here are further details about the one Android user I mentioned above.
  7. As I mentioned, I keep asking, but almost no one gets back to me with their details. Not sure what more I can do.
  8. I've been having this problem for quite a while now - through several version upgrades (I always upgrade pretty much immediately). That said it was a trickle of people a month or two ago, now it's at least 1-2 people a day complaining - so the situation is getting worse. It's been difficult to get real responses back from people when I tell them it's probably some sort of browser problem and tell them to be especially careful entering the year (not sure if that means they did manage to register or they didn't). But I did get the following response that might be helpful… BTW, I'm using IPSFocus' Villain theme, if that has any bearing on things. (They pointed me here.)
  9. Define "corrupt". This would be all I'd have to do to restore the data… INSERT INTO `core_stream_subscriptions` (`id`, `member_id`, `stream_id`, `frequency`, `sent`, `added`) VALUES (2,99547,1,'daily',1642337822,1636000819),(8,101722,4,'daily',1642265420,1642351820); I've verified that the members and the streams exist.
  10. I can say that 4.6.10 didn't fix the problem. It started before I did the upgrade and didn't go away with the upgrade. I just looked at my backup and I do have the data. I could restore it pretty easily.
  11. Just thought you guys should know that there are instances where the cron job can go crazy and apparently get into an infinite loop. It does a lot of this query… /*bzone::bzone::IPS\core\Stream\_Subscription::sendBatch:40*/ SELECT DISTINCT *, core_members.last_visit FROM `core_stream_subscriptions` LEFT JOIN `core_members` ON core_stream_subscriptions.member_id=core_members.member_id WHERE frequency = ? AND sent < ? and last_visit > ? ORDER BY sent ASC LIMIT 0,50 Backing up a bit, a couple weeks ago I noticed that load and CPU usage on my server doubled suddenly around January 16th. One of the symptoms was that there were frequently 2 php threads using 50% CPU each (and MySQL was using far more CPU than normal as well). Based on what my host told me I knew they were cron jobs for IP.Board. When I'd watch the queries that were running in MySQL everything seemed pretty normal. Anyway, finally I took a closer look at the queries that were being called and realized that query above shouldn't be called so frequently. I checked and I only had 5 `core_stream_subscriptions` records. Then I noticed two of them had `sent` values that were old. One of them corresponded with the date when the problem started, so I deleted those two records and my server went back to normal. Unfortunately I didn't delve further before deleting the records, so I'm not sure what exactly about those records were causing the problem. Anyway, you might want to look into situations that can cause infinite loops that constantly call the SQL above.
  12. As I'm working with my host - this does seem to be the issue. It's possible the cron jobs for IPB are being kicked off under a user other than what Apache uses. The other issue is they've found a bad (mirrored) drive that could be slowing things down. In at least one case the post was seen. It got into the RSS feed and was visible on a site that uses the feed. It was a while ago and I forget now whether it was visible on the IPB site. Other cases didn't get into the feed, however. Yes, as I mentioned responding to Runar - my host may have set up the cron job under a different user. Does it matter to IPB what user the crons for IPB are run under? So for now things MIGHT actually be OK. I'll wait to see if things return to normal after the drive is replaced. And thanks for everyone's input!
  13. Geez. How did that horrible "feature" get turned on? Only a spammer would like that feature. So that explained one of the problems. Thanks.
  14. I have two instances of IPB on my server. Both are now having (different) security issues… A bit over a month ago we noticed that spam posts were being inserted into `forums_posts` on one of the sites. Curiously the vast majority of them weren't visible to end users, so the attack wasn't all that successful. It was easy to find the spam posts because `author_id` was always zero (and there are no deleted users on that site). I probably should have followed up here, but didn't get around to it. Fast forward a couple weeks and the Mail Bouncer application I use on my other IPB install stopped working properly. The developer had told me how to call it from outside IPB and it started returning "internal server error" messages. Again, I didn't get around to contacting the developer to figure out the problem. Yesterday I noticed that the load on my server and the server's CPU usage had both doubled starting a bit over a week ago. I dug a bit further and saw that there were one or two suspicious threads using a lot of CPU. I run php using FPM and they were running php without FPM. And they weren't running under the user account that web requests typically use. I had my host investigate and they said they were associated with a number of IPB applications for the install where I was having problems with Mail Bouncer - Calendar, Galleries as well as Mail Bouncer and Delete My Account. The idea that someone can insert data into IPB apparently without going through the normal user interface is bad enough. Now seeing that IPB applications can be used to run rogue PHP threads under a user that IPB shouldn't have the password for - is even worse. And yes, we're religious about applying updates in a timely manner. There's plenty of other code on the server (Wordpress, custom PHP, etc.) but IP.Board is the common thread for these problems. I'm working with my host on this. But if Invision has comments/suggestions, I'm all ears.
  15. I'm seeing quite a few posts being held for moderation and wondering what I'm missing. I wouldn't say it's a majority of new posts, but enough to be noticeable. Automatic moderation is off The option for holding new posts for moderation is NOT checked for that forum section The user does not have any infractions that would result in their posts being held for moderation It's happening even to long-term members with high reputation scores. What else could trigger a new post being held for moderation?
  16. It does whatever Mail Bouncer does. Refer to the documentation for that.
  17. Honestly I don't know exactly everything EmailBouncer does, and whether it meets your requirements (maybe @stoo2000 can answer that), but if it does, the simplified version of my script boils down to this… <?php \define('REPORT_EXCEPTIONS', TRUE); $_SERVER['SCRIPT_FILENAME'] = __FILE__; require_once 'init.php'; header('Content-Encoding: none'); ob_implicit_flush(true); ob_end_flush(); set_time_limit(60*180); echo str_repeat(' ',1024*64.1); $hardfails = array( 'email1@host5.com', 'email2@host4.com', 'email3@host3.com', 'email4@host2.com', 'email5@host1.com' ); $softfails = array( 'email6@host0.com', 'email7@host9.com', 'email8@host8.com', 'email9@host7.com', 'email0@host6.com' ); echo '<!DOCTYPE html><html lang="en-US" dir="ltr"><head><meta charset="utf-8"></head><body>'; echo "<p>Please note: 'Email address not found' can mean two things – 1) that you have a problem because a member record could not be found, or 2) that the member has already corrected the problem. If you see just a few messages like that, it usually indicates that the member already corrected the problem.</p>"; echo "</ul><h2>".count($softfails)." Soft Fails</h2><ul>"; asort($softfails); foreach ($softfails as $fail){ list($email, $datetime) = explode(',', $fail); echo "<li>$email – "; ob_flush(); $member = \IPS\Member::load( $email, 'email' ); if( $member->member_id ) { if ($_GET['test'] != '1'){ $member->bouncerSoftBounce( $datetime ); } echo "set as soft bounce. ($datetime)"; } else { echo "<b>EMAIL ADDRESS NOT FOUND</b>"; } echo "</li>"; ob_flush(); } echo "</ul>"; echo "<h2>".count($hardfails)." Hard Fails</h2><ul>"; asort($hardfails); foreach ($hardfails as $fail){ list($email, $datetime) = explode(',', $fail); echo "<li>$email – "; ob_flush(); $member = \IPS\Member::load( $email, 'email' ); if( $member->member_id ) { if ($_GET['test'] != '1'){ $member->bouncerHardBounce( $datetime ); } echo "set as hard bounce. ($datetime)"; } else { echo "<b>EMAIL ADDRESS NOT FOUND</b>"; } echo "</li>"; } echo "</ul>"; echo "</body></html>"; ?> Take that file, save it as something like bouncing.php and then replace the email@host.com stuff in the two arrays with the list of emails you want handled. Make sure the list is formatted the same way – quotes (or double quotes) around each email address and commas between them. And if you have no hard or soft bounces take out all the examples so it just says array(); After you make those changes, use FTP to put the file in the root directory of your site. Then use this URL: https://yoursite.com/bouncing.php?test=1 That will run through things and do everything except for actually handing the bounces. If everything looks good, then run the same URL without the ?test=1 and it will actually do the hard and/or soft bounces.
  18. So here's my code… It comes with a lot of caveats… Think of it as starting point so you or your developer doesn't have to start from scratch. I'm not the best PHP programmer, so my code may not be quite as beautiful as yours, but it's better than nothing. Also, this code calls MailBouncer, so you must have an active license for that. You can put the the file anywhere and name it anything (ending in .php). The code will almost certainly need to be tweaked. For example, my mail server is running SendMail. If your mail server is running something different the bulk of your messages may have different formatting. Here's what it does… Logs into your email account and scans through all the messages from postmaster@ and MAILER-DAEMON@. You can login with IMAP or POP w/ or w/o SSL. Only IMAP w/o SSL has been tested, but the code is there for the others. After processing the entire mailbox, when you repeat the process you'll probably want to do just examine the most recent period. To do that add ?days=X to the end of the URL where X is the number of days you want to examine. X can be a decimal number. When it scans it classifies things as 4 types: Indeterminate Reputation problem Hard bounce Soft bounce You won't see detailed information about hard and soft bounces, but you will if there's a reputation problem or the outcome was indeterminate. Reputation problems typically mean that your server got on a blacklist. You'll want to rectify this ASAP. Reputation problems are handled as soft bounces, since they're not the fault of the member. Indeterminate issues are when you'll probably need to tweak the code to handle the case (typically different error formatting). You can add trigger phrases to $softphrases, $hardphrases and $reputationphrases. If it's not parsing the email address that's bouncing, that's a little trickier. Or you can just manually go into the IP board admin area and do manually what Mail Bouncer does. It is possible to change up the code to not scan a mailbox and just handle a long list of emails you've manually put together – just replace everything inside if (!$mbox = imap_open($authhost, $user, $pw)){ } else {} with something that populates the $hardfails and $softfails arrays. At the end it does one other thing – it queries the database and finds everyone who has been banned for 8 weeks or longer and processes their email addresses as hard bounces. These people are probably mad at you and don't want your emails, and they're likely to mark your emails as spam just to spite you. So it's best to just treat the email as bad and if/when the member returns they can revalidate their email address. The SQL query is shown. You'll need to rewrite the actual pull from your IP.Board database. I use Fat Free Framework, so that's the syntax you'll see. To turn off handling of long bans permanently just comment out or delete the code. But you can also add lb=off to the end of the URL to not to it on a particular run of the script. With all of that said, here's the code… <?php //I USE FAT FREE FRAMEWORK, SO THERE'S AT LEAST ONE CASE WHERE YOU NEED TO REPLACE F3 CODE WITH YOUR OWN CODE $user = 'your_mail_username'; $pw = 'your_mail_pw'; $mailserver = 'localhost'; \define('REPORT_EXCEPTIONS', TRUE); $_SERVER['SCRIPT_FILENAME'] = __FILE__; require_once '/path/to/init.php'; //PATH TO THE INIT.PHP FILE FOR YOUR IP.BOARD INSTALL header('Content-Encoding: none'); ob_implicit_flush(true); ob_end_flush(); set_time_limit(60*180); echo str_repeat(' ',1024*64.1); $hardfails = array(); $softfails = array(); //THE FOLLOWING ARRAYS OF PHRASES DETERMINE THE TYPE OF FAILURE, EDIT THEM AS NEEDED $softphrases = array(); $softphrases[] = '(reason: 552'; //552 = Exceeded storage allocation $hardphrases[] = '<<< 552'; $softphrases[] = ' over quota'; $softphrases[] = ' inbox is full'; $softphrases[] = ' mailbox is full'; $softphrases[] = ' mailbox full'; $softphrases[] = 'Mail quota exceeded'; $softphrases[] = 'is over quota'; $hardphrases = array(); $hardphrases[] = '550 5.1.1'; $hardphrases[] = '550-5.1.1'; $hardphrases[] = '<<< 550'; //550 = Non-existent email address $softphrases[] = '(reason: 550'; $hardphrases[] = 'Status code: 550'; $hardphrases[] = ' mailbox unavailable'; $hardphrases[] = ' deactivated mailbox'; $hardphrases[] = ' Bad destination mailbox address'; $hardphrases[] = ' no valid recipients'; $hardphrases[] = 'Not a valid recipient'; $hardphrases[] = 'User unknown'; $hardphrases[] = ' Address does not exist'; $hardphrases[] = ' mailbox is disabled'; $hardphrases[] = ' user doesn\'t have a yahoo'; $hardphrases[] = 'is a deactivated mailbox'; $reputationphrases = array(); //things that indicate they just don't like/trust the email //this is a problem if you sent the email, not a problem if some spammer sent the email (pretending to be you) $reputationphrases[] = 'Relay access denied'; //https://serversitters.com/how-to-correct-554-5-7-1-relay-access-denied-email-errors-and-prevent-them-in-the-future.html $reputationphrases[] = ' blocked using '; //ONE OF THE FOLLOWING 4 LINES SHOULD BE UNCOMMENTED DEPENDING ON WHAT TYPE OF CONNECTION YOU WANT TO MAKE TO YOUR MAIL SERVER //$authhost="{".$mailserver.":995/pop3/ssl/novalidate-cert}"; //POP w/o SSL //$authhost="{".$mailserver.":110/pop3/notls}"; //POP w/ SSL $authhost="{".$mailserver.":993/imap/ssl/novalidate-cert}"; //IMAP w/o SSL (this is the only one that's been tested) //$authhost="{".$mailserver.":143/imap/notls}"; //IMAP w/ SSL echo '<!DOCTYPE html><html lang="en-US" dir="ltr"><head><meta charset="utf-8"></head><body>'; if (!$mbox = imap_open($authhost, $user, $pw)){ echo "<p>Could not connect to mail server.</p>"; } else { echo "<p>Connected to mail server.</p>"; $totalrows = imap_num_msg($mbox); echo "<p>Found $totalrows messages</p><ul>"; $result = imap_fetch_overview($mbox, "1:$totalrows", 0); foreach ($result as $overview) { $body = imap_fetchbody($mbox, $overview->msgno, "1"); $datetime = strtotime($overview->date); date_default_timezone_set("UTC"); if (stripos($body, 'https://web.de/email/senderguidelines') !== false && stripos($body, 'cs2172.mojohost.com') !== false) { //ignore these, problem was resolved } else if ($_GET['days'] > 0 && $datetime < time() - ($_GET['days'] * 86400)){ //do nothing, it doesn't meet the cutoff // echo "<li>Skipping: $datetime < ".(time() - ($f3->get('days') * 86400))."</li>"; } else if ((stripos($overview->from, 'Mailer-Daemon@') !== false || stripos($overview->from, 'postmaster@') !== false ) && ((strpos($body, '----- The following addresses had permanent fatal errors -----') !== false && strpos($body, '(reason: ') !== false) || (stripos($body, 'Final-Recipient: ') !== false) || (stripos($body, 'message couldn\'t be delivered to ') !== false) || (stripos($body, '> is a deactivated mailbox') !== false) || (strpos($body, ' to these recipients or groups:') !== false && strpos($body, 'The recipient\'s mailbox is full') !== false))) { //PARSE THE EMAIL ADDRESS THAT'S HAVING A PROBLEM $bademail = ''; if (strpos($body, '----- The following addresses had permanent fatal errors -----') !== false) { $pos1 = strpos($body, '----- The following addresses had permanent fatal errors -----'); $pos1 = $pos1 + strlen('----- The following addresses had permanent fatal errors -----'); $pos2 = strpos($body, '(reason: ', $pos1); if ($pos2 > 0) { $bademail = str_replace('<', '', str_replace('>', '', trim(substr($body, $pos1, $pos2 - $pos1)))); } } else if (stripos($body, 'Final-Recipient: ') !== false){ //The syntax of the field is as follows: // "Final-Recipient" ":" address-type ";" generic-address // i.e. Final-Recipient: rfc822; skijanje-zg@net.hr $pos1 = strpos($body, 'Final-Recipient: '); $pos1 = $pos1 + strlen('Final-Recipient: '); $pos2 = strpos($body, "\r", $pos1); if (strpos($body, "\n", $pos1) < $pos2){ $pos2 = strpos($body, "\n", $pos1); } if ($pos2 > 0) { $bademail = substr($body, $pos1, $pos2 - $pos1); $pos3 = strpos($bademail, ';'); if ($pos3 !== false){ $bademail = substr($bademail, $pos3 + 1); } $bademail = trim($bademail); } } else if (strpos($body, ' to these recipients or groups:') !== false && strpos($body, 'The recipient\'s mailbox is full') !== false){ $pos1 = strpos($body, ' to these recipients or groups:'); $pos1 = $pos1 + strlen(' to these recipients or groups:'); $pos2 = strpos($body, 'The recipient\'s mailbox is full', $pos1); if ($pos2 > 0) { $bademail = trim(substr($body, $pos1, $pos2 - $pos1)); if (strpos($bademail, '<') !== false && strpos($bademail, '>') !== false){ $bademail = substr($bademail, strpos($bademail, '<') + 1); $bademail = substr($bademail, 0, strpos($bademail, '>')); } } } else if(stripos($body, '> is a deactivated mailbox') !== false){ $bademail = substr($body, 0, stripos($body, '> is a deactivated mailbox')); $bademail = substr($bademail, strrpos($bademail, '<') + 1); } else if(stripos($body, 'message couldn\'t be delivered to ') !== false){ $bademail = substr($body, stripos($body, 'message couldn\'t be delivered to ') + strlen('message couldn\'t be delivered to ')); $bademail = substr($bademail, 0, strpos($bademail, '. ')); } //CLEAN UP THE EMAIL ADDRESS if (stripos($bademail, 'mailto:') === 0){ $bademail = substr($bademail, strlen('mailto:')); } if (!filter_var($bademail, FILTER_VALIDATE_EMAIL)) { echo "<li><b>ERROR: PARSED THE EMAIL $bademail BUT IT IS NOT A VALID EMAIL ADDRESS</b></li>"; $bademail = ''; } //EVALUATE DIFFERENT TYPES OF PROBLEMS $result = 'Indeterminate'; if ($result == 'Indeterminate'){ //reputation problems foreach($reputationphrases as $phrase){ if ($result == 'Indeterminate' && stripos($body, $phrase) !== false) { $result = 'Reputation Problem'; } } } if ($result == 'Indeterminate'){ //hard bounces foreach($hardphrases as $phrase){ if ($result == 'Indeterminate' && stripos($body, $phrase) !== false) { $result = 'hard'; } } } if ($result == 'Indeterminate'){ //soft bounces foreach($softphrases as $phrase){ if ($result == 'Indeterminate' && stripos($body, $phrase) !== false) { $result = 'soft'; } } } if ($result == 'Indeterminate' || $bademail == '') { echo "<li>{$overview->msgno}<ul>"; echo "<li>Sent: {$overview->date}</li><li>From: " . htmlspecialchars($overview->from) . "</li><li> Subject: {$overview->subject}</li>"; echo "<li><pre>" . htmlspecialchars(substr($body, 0, 10240)) . "</pre></li>"; echo "<li><b>Bad Email: $bademail</b></li>"; echo "<li>Date/Time: $datetime</li>"; echo "<li><b>Result: $result</b></li>"; echo "</ul></li>"; } elseif ($result == 'Reputation Problem') { echo "<li>{$overview->msgno}<ul>"; echo "<li>Sent: {$overview->date}</li><li>From: " . htmlspecialchars($overview->from) . "</li><li> Subject: {$overview->subject}</li>"; echo "<li><pre>" . htmlspecialchars(substr($body, 0, 10240)) . "</pre></li>"; echo "<li><b>Bad Email: $bademail</b></li>"; echo "<li>Date/Time: $datetime</li>"; echo "<li><b>Result: Reputation Problem (handled as a soft bounce)</b></li>"; echo "</ul></li>"; $exists = false; for($i = 0; $i < count($softfails); $i++){ list($temp_email, $temp_dt) = explode(',', $softfails[$i]); if ($temp_email == $bademail){ $exists = true; if ($temp_dt < $datetime){ $softfails[$i] = "$bademail,$datetime"; //update date time } } } if ($exists === false){ $softfails[] = "$bademail,$datetime"; } } elseif ($result == 'hard' && array_search("$bademail,$datetime", $hardfails) === false) { $exists = false; for($i = 0; $i < count($hardfails); $i++){ list($temp_email, $temp_dt) = explode(',', $hardfails[$i]); if ($temp_email == $bademail){ $exists = true; if ($temp_dt < $datetime){ $hardfails[$i] = "$bademail,$datetime"; //update date time } } } if ($exists === false){ $hardfails[] = "$bademail,$datetime"; } } elseif ($result == 'soft' && array_search("$bademail,$datetime", $softfails) === false) { $exists = false; for($i = 0; $i < count($softfails); $i++){ list($temp_email, $temp_dt) = explode(',', $softfails[$i]); if ($temp_email == $bademail){ $exists = true; if ($temp_dt < $datetime){ $softfails[$i] = "$bademail,$datetime"; //update date time } } } if ($exists === false){ $softfails[] = "$bademail,$datetime"; } } } else if (stripos($overview->subject, "Mail delivery failed") !== false) { echo "<li>{$overview->msgno}<ul>"; echo "<li>Sent: {$overview->date}</li><li>From: " . htmlspecialchars($overview->from) . "</li><li> Subject: {$overview->subject}</li>"; echo "<li><pre>" . htmlspecialchars(substr($body, 0, 10240)) . "</pre></li>"; echo "</ul></li>"; } else if (stripos($overview->subject, "Delivery Status Notification (Failure)") !== false) { //hotmale sends ones like this… echo "<li>{$overview->msgno}<ul>"; echo "<li>Sent: {$overview->date}</li><li>From: " . htmlspecialchars($overview->from) . "</li><li> Subject: {$overview->subject}</li>"; echo "<li><pre>" . htmlspecialchars(substr($body, 0, 10240)) . "</pre></li>"; echo "</ul></li>"; } else if (stripos($overview->subject, "Undeliverable: ") !== false) { //outlook sends ones like this… echo "<li>{$overview->msgno}<ul>"; echo "<li>Sent: {$overview->date}</li><li>From: " . htmlspecialchars($overview->from) . "</li><li> Subject: {$overview->subject}</li>"; echo "<li><pre>" . htmlspecialchars(substr($body, 0, 10240)) . "</pre></li>"; echo "</ul></li>"; } else if (stripos($overview->from, 'postmaster@') === 0) { //catch all echo "<li>{$overview->msgno}<ul>"; echo "<li>Sent: {$overview->date}</li><li>From: " . htmlspecialchars($overview->from) . "</li><li> Subject: {$overview->subject}</li>"; echo "<li><pre>" . htmlspecialchars(substr($body, 0, 10240)) . "</pre></li>"; echo "</ul></li>"; } else if (stripos($overview->from, 'Mailer-Daemon@') === 0) { //catch all echo "<li>{$overview->msgno}<ul>"; echo "<li>Sent: {$overview->date}</li><li>From: " . htmlspecialchars($overview->from) . "</li><li> Subject: {$overview->subject}</li>"; echo "<li><pre>" . htmlspecialchars(substr($body, 0, 10240)) . "</pre></li>"; echo "</ul></li>"; } } //end foreach echo "</ul>"; imap_close($mbox); } //connected ob_flush(); //NOW HAVE ARRAYS OF HARD AND SOFT FAILS, NEED TO PROCESS THEM… echo "<p>Please note: 'Email address not found' can mean two things – 1) that you have a problem because a member record could not be found, or 2) that the member has already corrected the problem. If you see just a few messages like that, it usually indicates that the member already corrected the problem.</p>"; echo "</ul><h2>".count($softfails)." Soft Fails</h2><ul>"; asort($softfails); foreach ($softfails as $fail){ list($email, $datetime) = explode(',', $fail); echo "<li>$email – "; ob_flush(); $member = \IPS\Member::load( $email, 'email' ); if( $member->member_id ) { $member->bouncerSoftBounce( $datetime ); echo "set as soft bounce. ($datetime)"; } else { echo "<b>EMAIL ADDRESS NOT FOUND</b>"; } echo "</li>"; ob_flush(); } echo "</ul>"; echo "<h2>".count($hardfails)." Hard Fails</h2><ul>"; asort($hardfails); foreach ($hardfails as $fail){ list($email, $datetime) = explode(',', $fail); echo "<li>$email – "; ob_flush(); $member = \IPS\Member::load( $email, 'email' ); if( $member->member_id ) { $member->bouncerHardBounce( $datetime ); echo "set as hard bounce. ($datetime)"; } else { echo "<b>EMAIL ADDRESS NOT FOUND</b>"; } echo "</li>"; } echo "</ul>"; if ($_GET['lb'] != 'off'){ $sql = "SELECT `email` FROM `core_members` WHERE `temp_ban` = -1 OR `temp_ban` > NOW() + INTERVAL 8 WEEK"; $results = $bzDB->exec($sql); //REPLACE THIS WITH A SQL QUERY TO YOUR IP.BOARD DATABASE echo "<h2>".count($results)." Long Bans (set as hard bounces)</h2><ul>"; foreach($results as $result){ $email = $result['email']; echo "<li>$email – "; ob_flush(); $member = \IPS\Member::load( $email, 'email' ); if( $member->member_id ) { $member->bouncerHardBounce( time() ); echo "set as hard bounce."; } else { echo "<b>EMAIL ADDRESS NOT FOUND</b>"; } echo "</li>"; } } echo "</body></html>"; ?>
  19. I completed writing my routine to parse the messages in an email inbox, figure out the type of bounce, and then submit it to Mail Bouncer. I'll post the code in a few days. I want to see if I encounter any issues with it before sharing it with folks. It will not be a supported code and will come with no warranty. (Use at your own risk!) The error messages from mail hosts are just too unpredictable for me to want to deal with all the weird cases other people will encounter. Rather, think of it as a starting point for people with some knowledge of PHP programming – something you can tweak to suit your own needs, that means you don't have to start from scratch. And I should mention that it can be modified pretty easily to handle lists you may have of emails that need to be disabled.
  20. Questions about that code… I've figured out how to access the email account receiving the bounce messages and I've parsed the bounces into two arrays – $hardfails and $softfails. I grabbed the code for the 2nd case you specified but it didn't look right to me… Should it be foreach($events as $event)? To me it doesn't make sense to do a new $bounce inside a loop that sets $bounce. Then I figured I'd do it based on your first example, so I came up with this… require_once '/home/httpd/html/mysite.com/public_html/init.php'; echo "<p>Require executed.</p>"; \IPS\Dispatcher\External::i(); foreach ($softfails as $email){ echo "<li>$email – "; ob_flush(); $member = \IPS\Member::load( $email, 'email' ); if( $member->member_id ) { $member->bouncerSoftBounce( time() ); echo "set as soft bounce."; } else { echo "member not found."; } echo "</li>"; } But \IPS\Dispatcher\External::i(); throws a server error (500). Can you give any insight into what I'm doing wrong? Admittedly I'm not all that familiar with programming for IP.Board. Here's what got logged for the error… Error: Call to undefined method stdClass::language() (0) #0 /home/httpd/html/mysite.com/public_html/system/Dispatcher/External.php(64): IPS\Dispatcher\_Standard::baseJs() #1 /home/httpd/html/mysite.com/public_html/system/Dispatcher/External.php(41): IPS\Dispatcher\_External::baseJs() #2 /home/httpd/html/mysite.com/public_html/system/Dispatcher/Dispatcher.php(109): IPS\Dispatcher\_External->init() #3 /home/httpd/html/mysite.com/public_html/bouncers.php(159): IPS\_Dispatcher::i() #4 {main} [To the folks who wanted my source code for parsing the emails, I'll post it when I've got things working and cleaned up.]
  21. @stoo2000 - thanks for that. That could make things easier. I'll give it a shot.
  22. Unless someone comes up with a better idea, here's what I'm thinking of doing… Writing something in PHP to scan the email inbox that receives the bounce notifications. I'll use key phrases in the email to determine if it's a case of a invalid email address or a full mailbox. For now I'll ignore the ones that are basically "we don't like you". I'll then make a SQL connection to my IP.Board database and modify the email address. I'll append ".hf" to the hard fails (invalid email address), and .YYYYMMDD.sf to the ones where their mailbox is full. IP.Board will still attempt to send the email, but it will fail. But it will fail in a way that won't bother legit email servers. That will preserve my reputation with those email providers. The YYYYMMDD in the soft fails will indicate the date of the last failure. I can then write a routine that will go through and search for all the ".sf" email addresses, and if they're more than a week old, I'll strip off the .YYYYMMDD.sf which will let mail be sent to them again. If their mailbox is still full, then the process repeats itself. I'll also (try to) write a Javascript that I'll include on each page that inserts a warning banner at the top of the page if the user's email ends in .hf or .sf warning them that action is needed on their part. But seriously, Invision should make this an easier process. It's a bit ridiculous that we can't just specify a list of email addresses that need their emails turned off (except for validation emails).
  23. @Adriano Faria – as I mentioned, I'm unable to use Mail Bouncer.
  24. I've got a 10 year old site that's got about 65,000 users. Over the years a lot of the member email addresses have gone bad. The problem is I can't find a way to stop emails going to bad email addresses. Yes, there are horribly complicated ways to do it, but they're not practical when there are many hundreds of bad emails. I'm aware of Mail Bouncer, but when I tried it I found that none of it's supported mail services allow adult content. So it's not an option for me. Recently I tried the "Force User to Change Email Address" plugin, which unvalidates the email. But IP.Board keeps sending emails even though the email addresses are no longer validated. IMHO, the only email that should be sent to an unvalidated email address is an email to validate the email address. I'm not asking for something that will comb a mailbox and parse errors. I just want a simple way to turn off the emails once I have a list of problem emails. Does anyone have a suggestion?
  25. I'm using InnoDB, with 3 GB of RAM in a pool with 4 instances. Typically buffer usage is around 98%, and key efficiency 100%. I didn't look too closely when I truncated the table this morning, but I know the first time I did it there were only about 500 records in `core_sessions`. Right now there's about 1250 records in the table and everything is operating smoothly. I simply don't understand how sometimes, all of a sudden, there are problems.
×
×
  • Create New...