Archive for Eventum

Old Eventum Banner Ads

Back when Eventum was still a commercial product of mine, I tried to create some banner ads to try to promote the product. I just found some old copies lying around on my web server:

normal 468x60 banner

And some vertical banners that I would use on my weblog:

vertical banner #1
  
vertical banner #2

Isn’t that adorable? :)

Outlook 2003 and missing Message-ID

So here’s the deal: Outlook 2003 doesn’t include the Message-ID header if you are sending email through a mail server other than Microsoft Exchange. There are other rants about this:

  1. from Peter Pentchev
  2. from Terry Frazier

And they both point to this priceless news bulletin, which contains this gem:

According to Mark, Microsoft apparently had a few complaints from people using Outlook that their machine name was “leaked” in the Message-ID header. Instead of ignoring the complaint or making the host name used in the Message-ID header configurable, Microsoft chose to remove the Message-ID header.

Technically, Outlook 2003 is still RFC-compliant, if Microsoft accepts the fact that messages sent from Outlook 2003 may be marked as spam. Most spam filters that look at Message-ID use that as only one of many factors weighted to determine if a particular message is likely to be spam. Administrators may want to check the weighting for that particular factor and lower it to avoid having too many incoming Outlook 2003 messages marked as spam by mistake.

Mark says that, as he understands it, Microsoft’s position that they expect all mail servers to whitelist outgoing mail from Outlook 2003 users and add a Message-ID header to fill in the one that Outlook omits. To me, that seems a bit much to ask. Why couldn’t Outlook itself add its own Message-ID header that doesn’t reveal personal or computer information?

Stay tuned. I don’t think we’ve heard the last of this issue.

No, that was really the last of this issue. Microsoft did indeed change the behavior in Outlook 2003, and there’s nothing we can do about it. Well, besides add yet another level of hatred here, of course.

So what does one need to do to uniquely identify messages if this is happening? Eventum uses the value on the Message-ID header to decide whether it should download a message from a POP3/IMAP server or not, so if there’s no value on that header, all hell breaks loose.

All I can think of right now is to generate some sort of checksum for each message and check the database when downloading messages to see if we already have a copy or not.

But deep down, I personally blame Peter W. Resnick (the editor of RFC2822) for using SHOULD instead of MUST for the Message-ID header. Here’s some love, Pete.

Eventum now on FreeBSD’s port collection

I had no idea about this, until I noticed a new section on our Wiki page that describes the installation notes for FreeBSD:

You can alternatively take the easy way and install Eventum from FreeBSD’s ports collection. At first, you need to update your ports collection using cvsup (http://www.freebsd.org/doc/en_US.ISO8859-1/books/handbook/cvsup.html). Once you updated your ports directory, use: cd /usr/ports/www/eventum && make install clean

Pretty cool :)

Application Structure

I love how Richard Heyes’ Application Structure post which describes his way of layint out PHP applications is similar to my own personal structure. I have been using something very similar for a few years now, which evolved by working with PHP applications and dealing with problems and how to avoid them in the future, so it’s amusing to see two people come up with something so similar.

I basically agree with the way he separates library code from normal PHP scripts that are available to the Web, but I do things a bit different. I use the following directory structure:

application root
  |
  +- crons
  +- include
  |    +- jpgraph
  |    +- pear
  |    +- Smarty
  +- locks
  +- logs
  +- scripts
  +- setup
  +- templates
  +- templates_c
  +- webroot
       +- css
       +- images
       +- js

Explanation:

  • crons: where scripts that run off the crontab are located.
  • include: the main directory where the business logic classes are located. I also store PEAR, Smarty and Jpgraph classes here since I don’t really need to see them on the top-level directory every time I want to browse for a file. Richard couldn’t be more right about the whole idea of bundling the libraries that you depend on with your application. There’s nothing worse than waking up one day and having your code totally broken because someone upgraded PEAR to the latest release.
  • locks: scripts that run off the crontab save their lock files to avoid having two copies of the same script running at the same time. Since I cannot simply trust PHP to create a temporary file on the appropriate place, I’ll create my own directory for this.
  • logs: where assorted error logs and informative debugging logs are stored.
  • scripts: where other types of scripts are located, such as manual scripts that are available for convenience. In some cases this might not be needed.
  • setup: where configuration related files are stored. The all-mighty config.inc.php file is stored here, as well as database schema files and etc.
  • templates: where smarty template files are stored.
  • templates_c: smarty uses this directory to save compiled templates.
  • webroot: the actual web accessible directory of the application, from which PHP scripts will include the configuration file, business logic classes, Smarty and etc.

So what do I have on my config.inc.php?

< ?php
ini_set('display_errors', 1);
error_reporting(E_ALL);
set_time_limit(0);
// define the constants related to the structure
@define('APP_ROOT_PATH', '/www/htdocs/appname/');
@define('APP_PATH', APP_ROOT_PATH . 'docs/');
@define('APP_INC_PATH', APP_ROOT_PATH . 'include/');
@define('APP_PEAR_PATH', APP_INC_PATH . 'pear/');
@define('APP_SMARTY_PATH', APP_INC_PATH . 'Smarty/');
if ((stristr(PHP_OS, 'darwin')) || (!stristr(PHP_OS, 'win'))) {
    ini_set('include_path', '.:' . APP_PEAR_PATH);
} elseif (stristr(PHP_OS, 'win')) {
    ini_set('include_path', '.;' . APP_PEAR_PATH);
}
@define('APP_SETUP_PATH', APP_ROOT_PATH . 'setup/');
@define('APP_LOG_PATH', APP_ROOT_PATH . 'logs/');
@define('APP_ERROR_LOG', APP_LOG_PATH . 'errors.log');
@define('APP_LOCKS_PATH', APP_ROOT_PATH . 'locks/');
// ...
?>

Then in each PHP script on the webroot directory, I do something like this:

< ?php
include_once('../setup/config.inc.php');
include_once(APP_INC_PATH . 'class.auth.php');
include_once(APP_INC_PATH . 'class.template.php');
include_once(APP_INC_PATH . 'class.db_connection.php');
// ...
?>

And you go from there. I like Richard’s idea to use basename() to get the base directory dynamically.

Eventum presentation at Houston PHP Users Group

Yesterday I gave an introduction to Eventum at the June meeting of the Houston PHP Users Group. You may read the presentation below from Slideshare.

SlideShare | View
« Previous Page« Previous entries « Previous Page · Next Page » Next entries »Next Page »