Page 4 of 6

Posted: Fri Jun 02, 2006 4:23 pm
by JayBird
woohoo, i found a bug.

Cheerz chris, appreciate it ;)

Posted: Fri Jun 02, 2006 8:23 pm
by s.dot
I just have a question about sendmails mail spool. Oft times i check the mail spool and there's ~1000 messages in it. Bad email addresses? System overload?

What happens when a new email needs to be sent and there's messages in the mail queue? Does it go to the bottom of the list or does it try right away?

Edit: Thank you for this Chris, it is spectacular. I was (still am, till i put your class to use) having some great difficulty getting activation emails to send. Pretty important part! I've tested your class with yahoo, gmail, hotmail, amd various POP3 accounts. Works perfect! =] I actually tried phpmailer BEFORE i tried this class, simply because it was more tested and widely used. Mistake. PHPMailer was a bit confusing and complained that I don't have server relaying enabled? I didn't know what that meant, so I went with Swifty. It works pretty... swiftly ;) Straight and to the point.

Posted: Sat Jun 03, 2006 5:51 am
by Chris Corbyn
scottayy wrote:I just have a question about sendmails mail spool. Oft times i check the mail spool and there's ~1000 messages in it. Bad email addresses? System overload?
This is perectly normal. If sendmail (or exim or any other MTA) is daemonised it will keep trying the queue every 15 mins or so. If messages can't be delivered, the system will keep trying for around 72 hours before giving up. If something fatal happened the messages may be frozen and abandoned altogether. You can retry all the messages pretty quickly by running the following if memory serves correctly:

/usr/sbin/sendmail -qf
scottayy wrote:What happens when a new email needs to be sent and there's messages in the mail queue? Does it go to the bottom of the list or does it try right away?
It tries straight away. If there's a problem, or it's busy doing something else at the time then it goes on the queue.
scottayy wrote:Edit: Thank you for this Chris, it is spectacular. I was (still am, till i put your class to use) having some great difficulty getting activation emails to send. Pretty important part! I've tested your class with yahoo, gmail, hotmail, amd various POP3 accounts. Works perfect! =] I actually tried phpmailer BEFORE i tried this class, simply because it was more tested and widely used. Mistake. PHPMailer was a bit confusing and complained that I don't have server relaying enabled? I didn't know what that meant, so I went with Swifty. It works pretty... swiftly ;) Straight and to the point.
Hey thanks! Glad you like it :)

Posted: Sat Jun 03, 2006 9:21 am
by Maugrim_The_Reaper
Page hit 1,345 times since 27th May 2006 (619 unique).
You should register on SF and FM if not already. Get more exposure and catch any issues quicker. Excellent library by the way - reading the code was actually pleasant. If the good reviews continue I'll start using it in my newer projects.

Posted: Sat Jun 03, 2006 10:49 am
by Chris Corbyn
Maugrim_The_Reaper wrote:
Page hit 1,345 times since 27th May 2006 (619 unique).
You should register on SF and FM if not already. Get more exposure and catch any issues quicker. Excellent library by the way - reading the code was actually pleasant. If the good reviews continue I'll start using it in my newer projects.
It's on HotScripts (Google "Swift Mailer"). I've applied for SF too - still awaiting a response but since I regsitered it I've switched from GPL to LGPL. ;) Some other random website that collects code snippets seems to have listed it too.

I do need a Bug Tracker though at this early stage - SF will be immensely helpful for that. Mailing list is in order too but I'll do that myself :)

There seems to be quite a few people using it already who've sent me messages from the contact page on the site which is nice. Switching to LGPL was definitely a good move too.

It actually comes out (this thread) on the 4th Google results page for "PHP Mailer" - ideally I'd like to focus upon getting it on the first page for that search term. The keywords "OOP Mailer" do bring it up on the first page.

Thanks :)

EDIT | <thinking out=loud> I should call close() in the destructor in the PHP5 version :idea: </thinking>

Posted: Sat Jun 03, 2006 11:59 am
by Maugrim_The_Reaper
A Sourceforge listing carries immense weight for similar Google searches. Given your website, maybe a Mantis bug tracker would work as well, if not better, than SF.

Posted: Sun Jun 04, 2006 4:32 pm
by Chris Corbyn
First official plugin now bundled with 1.1.2 :)

It's an anti-flood plugin. On some shared hosts and some SMTP servers there is a limit of, for example 10 emails sent per connetion. This automatically politely closes the connection at the limit you set, and then opens a fresh one. This happens in the middle of Swift sending a batch email but without actually interfering with anything that would cause things to stop working.

Code: Select all

<?php

/**
 * Anti-Flood plugin for Swift Mailer, a PHP Mailer class.
 *
 * @package	Swift
 * @version	>= 1.1.2
 * @author	Chris Corbyn
 * @date	4th June 2006
 * @license	http://www.gnu.org/licenses/lgpl.txt Lesser GNU Public License
 *
 * @copyright Copyright &copy; 2006 Chris Corbyn - All Rights Reserved.
 * @filesource
 * 
 *   This library is free software; you can redistribute it and/or
 *   modify it under the terms of the GNU Lesser General Public
 *   License as published by the Free Software Foundation; either
 *   version 2.1 of the License, or (at your option) any later version.
 *
 *   This library is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *   Lesser General Public License for more details.
 *
 *   You should have received a copy of the GNU Lesser General Public
 *   License along with this library; if not, write to
 *
 *   The Free Software Foundation, Inc.,
 *   51 Franklin Street,
 *   Fifth Floor,
 *   Boston,
 *   MA  02110-1301  USA
 *
 *    "Chris Corbyn" <chris@w3style.co.uk>
 *
 */

class Swift_Anti_Flood_Plugin implements Swift_IPlugin
{
	/**
	 * Name of the plugin (identifier)
	 * @var string plugin id
	 */
	public $pluginName = 'Anti_Flood';
	/**
	 * The maximum number of messages to send
	 * over a single connection
	 * @var int max messages
	 */
	public $maxMessages;
	/**
	 * Current messages sent since last reconnect
	 * or plugin loading.
	 * @var int current messages
	 */
	private $currMessages = 0;
	/**
	 * Contains a reference to the main swift object.
	 * @var object swiftInstance
	 */
	private $swiftInstance;
	
	/**
	 * Constructor.
	 * @param int max messages, optional
	 * @return void
	 */
	public function __construct($max=10)
	{
		$this->maxMessages = (int) $max;
	}
	/**
	 * Load in Swift
	 * @param object SwiftInstance
	 */
	public function loadBaseObject(&$object)
	{
		$this->swiftInstance =& $object;
	}
	/**
	 * Event handler for onSend.
	 */
	public function onSend()
	{
		$this->currMessages++;
		if ($this->currMessages >= $this->maxMessages)
		{
			$this->reconnect();
			$this->currMessages = 0;
		}
	}
	/**
	 * Reconnect to the server
	 */
	private function reconnect()
	{
		$this->swiftInstance->close();
		$this->swiftInstance->connect();
		//Re-authenticate if needs be
		if (!empty($this->swiftInstance->username))
		{
			$this->swiftInstance->authenticate(
				$this->swiftInstance->username,
				$this->swiftInstance->password
			);
		}
	}
}

?>
Usage:

Code: Select all

$swift = new Swift($connectionObject);

$swift->loadPlugin(new Swift_Anti_Flood_Plugin(10)); //The 10 is default in any case

/* Go ahead and send out batch mail as usual */

Posted: Thu Jun 08, 2006 4:39 pm
by Chris Corbyn
Another plugin.

It's for verbose errors. This was pretty much needed since some people don't like having to do a check themselves if swift has failed.

With this plugin you'll get errors to the effect of:
Error running command: MAIL FROM: . No connection available near Swift::send in /home/d11wtq/public_html/Swift-1.1.4/test.php on line 22

Sending failed on command: MAIL FROM: near Swift::send in /home/d11wtq/public_html/Swift-1.1.4/test.php on line 22

Code: Select all

<?php

/**
 * Error handling plugin for Swift Mailer, a PHP Mailer class.
 *
 * @package	Swift
 * @version	>= 0.0.4
 * @author	Chris Corbyn
 * @date	8th June 2006
 * @license	http://www.gnu.org/licenses/lgpl.txt Lesser GNU Public License
 *
 * @copyright Copyright &copy; 2006 Chris Corbyn - All Rights Reserved.
 * @filesource
 * 
 *   This library is free software; you can redistribute it and/or
 *   modify it under the terms of the GNU Lesser General Public
 *   License as published by the Free Software Foundation; either
 *   version 2.1 of the License, or (at your option) any later version.
 *
 *   This library is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *   Lesser General Public License for more details.
 *
 *   You should have received a copy of the GNU Lesser General Public
 *   License along with this library; if not, write to
 *
 *   The Free Software Foundation, Inc.,
 *   51 Franklin Street,
 *   Fifth Floor,
 *   Boston,
 *   MA  02110-1301  USA
 *
 *    "Chris Corbyn" <chris@w3style.co.uk>
 *
 */

class Swift_Errors_Plugin implements Swift_IPlugin
{
	/**
	 * Name of the plugin (identifier)
	 * @var string plugin id
	 */
	public $pluginName = 'Errors';
	/**
	 * Contains a reference to the main swift object.
	 * @var object swiftInstance
	 */
	private $swiftInstance;
	/**
	 * The norm is the echo and continue.
	 * Settting this to TRUE makes it echo the die()
	 * @var bool halt
	 */
	private $halt;
	
	/**
	 * Constructor.
	 * @param bool halt (if the script should die() on error)
	 */
	public function __construct($halt=false)
	{
		$this->halt = (bool) $halt;
	}
	/**
	 * Load in Swift
	 * @param object SwiftInstance
	 */
	public function loadBaseObject(&$object)
	{
		$this->swiftInstance =& $object;
	}
	/**
	 * Event handler for onError
	 */
	public function onError()
	{
		$this_error = $this->swiftInstance->lastError;
		
		$error_info = $this->getErrorStartPoint();
		
		if (!empty($error_info['class'])) $class = $error_info['class'].'::';
		else $class = '';
		
		$file_info = ' near '.$class.$error_info['function'].
			' in <strong>'.$error_info['file'].'</strong> on line <strong>'.
			$error_info['line'].'</strong><br />';
		
		$output = '<br />'.$this_error.$file_info;
		echo $output;
		if ($this->halt) exit();
	}
	/**
	 * Get the command that caused the error
	 */
	private function getErrorStartPoint()
	{
		$trace = debug_backtrace();
		$start = array_pop($trace);
		return array(
			'file' => $start['file'],
			'line' => $start['line'],
			'class' => $start['class'],
			'function' => $start['function']
		);
	}
}

?>
Now I have a question. I'm just echoing these errors. The problem being now that you can't use "@" to surpress the error. It shouldn't really matter because you wouldn't load the plugin if you were gonna surpress errors but still I'd like to tweak it if I can (at least in the PHP5 version). I tried using trigger_error() but there was one major flaw. It spits out the file info for the plugin trigger_error() is called from when I want to generate my own user level warning without that info in it.

Anybody know a workaround? :)

Posted: Thu Jun 08, 2006 11:45 pm
by s.dot
d11wtq wrote:I want to generate my own user level warning without that info in it.
Seems you could call your own error handling function with set_error_handler()

Posted: Fri Jun 09, 2006 1:15 am
by Chris Corbyn
scottayy wrote:
d11wtq wrote:I want to generate my own user level warning without that info in it.
Seems you could call your own error handling function with set_error_handler()
But isn't that for actual PHP errors? These are my own defined errors.... they're not actual PHP errors if you know what I mean :)

Posted: Fri Jun 09, 2006 1:52 am
by Christopher
Rather than echoing, why don't you make this class an error logger. Instead of echoing, save the messages in an array. Then the app can do whatever it wants to with them -- display, write to a file, etc. Just add a getErrors() and showErrors() methods.

Posted: Fri Jun 09, 2006 2:26 am
by Chris Corbyn
arborint wrote:Rather than echoing, why don't you make this class an error logger. Instead of echoing, save the messages in an array. Then the app can do whatever it wants to with them -- display, write to a file, etc. Just add a getErrors() and showErrors() methods.
Agreed, but that's what swift already does. It logs them in an array "errors" and stores the latest in "lastError". Nothing ever gets displayed on page, that's what hasFailed() and isConnected() were for. The problem is that I'm getting a fair few emails from n00b people who just haven't checked if things worked or not (it's pretty much always realying denied issues) so I thought I'd make this to make it clear as mud. If I make it too complicated nobody but really experienced developers will choose to use Swift :(

Throw new Exception() should work I guess in PHP5 so I'll try that in the PHP5 version but will have to stick with echoing the errors in PHP4 :)

Posted: Sun Jun 11, 2006 10:30 pm
by akreider
I'd like to warn people to be sure to close the mailer ($mailer->close).

Otherwise it hangs and you don't know why... I just thought my host had banned me from using sendmail.

Aaron

Posted: Mon Jun 12, 2006 2:22 am
by Chris Corbyn
akreider wrote:I'd like to warn people to be sure to close the mailer ($mailer->close).

Otherwise it hangs and you don't know why... I just thought my host had banned me from using sendmail.

Aaron
It shouldn't do that. close() just fclose()'s the connection which is implied (apart from sending a QUIT command) at the end of script execution in any case. Can you send an example of where you're seeing this cheers? :)

Posted: Mon Jun 12, 2006 3:28 am
by akreider
I don't have a good example. If I remember correctly, it's when I run the thing through a web-service (using nusoap). If I don't use the close command then I get a nusoap timeout error, even when i'd just try to send one email. But it worked fine when I'd use the close() command.

I should mention that I'm using version 1.0.0

Timeouts are driving me crazy. Apparently I've got seperate timeouts for
1) php
2) nusoap
3) apache (or so i've heard, I don't know if this is true)

(Does Swift Mailer have any timeouts of its own?)

PHP I've got figured out.

NuSOAP - I've got a pending question to the NuSOAP email list. I've been waiting two weeks for a response.

Apache - I guess I'll look into this.

I want to have my script run for two hours, so I can email people every five seconds (and I want to do it using a web-service - aka via nusoap). The every five seconds is so that my host doesn't kill me. Maybe I should just send a web-service every ten emails, instead of the One Big Web Service.

Or if someone does some benchmarking (and/or optimizing) and its possible to send several emails per second without killing my host, i'd love to do that! I've done some experimenting, and so far it doesn't look like a safe idea. Server load increases too quickly.