FeedWordPress 0.991: bug fixes, reorganization, minor features added — and MU compatability

Update 2008-11-06: FeedWordPress 0.991 is now out of date. You can download the latest release — 2008.1105 at the time of this writing — from the project homepage.

0.991 is now available for download[1].

[2]: http://wordpress.org/extend/plugins/feedwordpress/feedwordpress.0.991.zip

Version 0.991 fixes some bugs that were present in version 0.99, adds a couple of minor features, reorganizes the file structure of the archive, and adds one very significant change. Let’s start with the significant change, which I am *very* happy to announce:

* **WORDPRESS MU COMPATABILITY:** FeedWordPress should now be compatible with
recent releases of WordPress MU. Once FeedWordPress is made available
as a plugin, each individual blog can choose to activate FeedWordPress
and syndicate content from its own set of contributors.

And now on to the bug fixes:

* **BUG RELATED TO INTERNATIONAL CHARACTERS IN AUTHOR NAMES FIXED:** Due to a
subtle incompatability between the way that FeedWordPress generated new
user information, and the way that WordPress 2.0 and later added new
authors to the database, FeedWordPress might end up creating duplicate
authors, or throwing a critical error message, when it encountered
authors whose names included international characters. This
incompatability has now been fixed; hopefully, authors with
international characters in their names should now be handled properly.

* **media:content BUG IN MAGPIERSS FIXED:** A bug in MagpieRSS’s handling of
namespaced elements has been fixed. Among other things, this bug caused
items containing a Yahoo MediaRSS `` element (such as
many of the feeds produced by wordpress.com) to be represented
incorrectly, with only a capital “A” where the content of the post
should have been. Feeds containing `` elements should now
be syndicated correctly.

* **MAGPIE WARNINGS NO LONGER DISPLAYED BY DEFAULT:** A number of MagpieRSS warnings or error messages that were displayed when performing an automatic update are no longer displayed, unless debugging parameters have been explicitly enabled.

Some minor bugs in the administrative interface have also been fixed.

I have received some feature requests concerning the new updating system that I introduced in 0.99[3]. Under the old system, there was a (needlessly complicated) system for having FeedWordPress poll its feeds for updates, which could be activated with a cron script on a regular schedule, thus keeping FeedWordPress up to date. In version 0.99, I replaced this with a much simpler system, in which FeedWordPress would *automatically* poll its feeds, according to a certain schedule, when users visited your website. (Of course, a cron script could still be used to make sure that this was activated on a regular schedule.) However, some users wrote me that they preferred that visitors not have to wait for the polling to finish before the page loads. So, I’ve added an HTTP parameter which gives you the option. If you prefer not to use WordPress’s cron-less automatic updates, you can now use the `update_feedwordpress` parameter instead. Here’s how it works:

* Leave Automatic Updates turned off. This will ensure that FeedWordPress polls for updates only when you tell it to do so.

* Add a line something like the following to your crontab:

*/15 * * * * curl –silent http://www.zyx.com/blog/?update_feedwordpress=1

… replacing `http://www.zyx.com/blog/` with the address of the blog where FeedWordPress is installed. This line will instruct FeedWordPress to poll for updates once every 15 minutes. If you have left Automatic Updates off, it will *only* check for updates on the 15 minute interval.

If you prefer the cron-less update method, then that’s still available; just go to **Options –> Syndication** and turn Automatic Updates on.

Finally, a word about the re-organization of the archive. is now listed in, and hosted by, the kind folks at the WordPress Plugin Directory(http://wordpress.org/extend/plugins/feedwordpress/). In line with their style guide about how to organize archives, I have moved the main plugin files — `feedwordpress.php` and `syndication-options.php` — to the root directory of the archive, and I have relocated the MagpieRSS upgrade to a subdirectory called, creatively enough, `MagpieRSS-upgrade`. However, please remember that in order to take advantage of the MagpieRSS upgrade — which you will definitely *want* to take advantage of, unless you don’t care about Atom 1.0 feeds, proper handling of multiple categories, or several bug fixes — you must still copy the contents of the `MagpieRSS-upgrade` directory to the `wp-includes` folder of your WordPress installation.

Enjoy, and have a wonderful Thanksgiving, y’all.

0.99: http://projects.radgeek.com/2007/09/24/feedwordpress-099-is-hereby-released-enjoy-wordpress-22-and-23-compatability-bug-fixes-major-new-features-and-updates-without-cron/

Posted in Uncategorized

How to deal with dates and timestamps in WordPress

If I hadn’t moved across the country recently, I probably never would have discovered a bug in how FeedWordPress handles the timestamps of syndicated posts. Fortunately, I did, and this bug is fixed in recently-released version 0.99[1].

[2]: http://projects.radgeek.com/2007/09/24/feedwordpress-099-is-hereby-released-enjoy-wordpress-22-and-23-compatability-bug-fixes-major-new-features-and-updates-without-cron/

To explain what I mean, I’ll have to back up a bit, first.

There are a couple things that FeedWordPress uses date and time information for:

1. **Dating new posts:** When a new post comes in over a feed, FeedWordPress uses the date and time information reported by feeds to date posts appropriately in the WordPress database. This means parsing date and time information and putting the resulting timestamps into the database.

2. **Checking for updates to existing posts:** After a post has been imported into the WordPress database, FeedWordPress will keep checking to see whether the feed reports any updates to that post. This means comparing the last-updated timestamp on the feed to the last-updated timestamp in the database to see which version is newer.

The problem that I noticed came about because FeedWordPress was trying to do something sensible and easy to handle *time zones* when it was doing all this. Date/time handling in WordPress is fairly easy, *once you understand what to do*, but it is certainly anything but sensible, and therein lies the problem.

Part of the problem is, as usual, the stack of programs on top of which FeedWordPress has to sit. In order to get dates from the feed, FeedWordPress has to process two different human-readable date formats. RSS feeds use 822(http://www.faqs.org/rfcs/rfc822.html) (or something like it), which FeedWordPress can convert to a Unix timestamp using the PHP [3](http://us.php.net/strtotime) function. Atom feeds use the DateTime Format(http://www.w3.org/TR/NOTE-datetime), which FeedWordPress can convert to a Unix timestamp using a custom function provided by MagpieRSS, called `parse_w3cdtf()`. Unix timestamps supposedly do not vary by time zone: a Unix timestamp for a particular time is defined as the number of seconds between that time and 12:00 midnight on January 1, 1970 *Greenwich Mean Time*. So both `strtotime()` and `parse_w3cdtf()` make use of the time zone data provided by the format that they handle, and use it to convert the date-time information to a timestamp based on GMT.

So far so good. Now, when converting a syndicated item into a post for the WordPress database, FeedWordPress has to generate *four* different timestamps: `post_date`, which gives the date and time that the post was first published *in the local time zone*; `post_date_gmt`, which gives the date and time that the post was first published *in Greenwich Mean Time*; `post_modified`, which gives the *local* date and time that the post was last modified; and `post_modified_gmt`, which gives the *GMT* date and time that the post was last modified. These fields are stored in the WordPress database as DATETIME objects(http://dev.mysql.com/doc/refman/5.0/en/datetime.html). WordPress later converts them back into Unix timestamps whenever it is necessary for formatting purposes. Here is how I did this in version 0.981:

$post[4] = date(‘Y-m-d H:i:s’,
(!is_null($post[5][6])
? $post[7][8]
: $post[9][10]));
$post[11] = date(‘Y-m-d H:i:s’,
$post[12][13]);
$post[14] = gmdate(‘Y-m-d H:i:s’,
(!is_null($post[15][16])
? $post[17][18]
: $post[19][20]));
$post[21] = gmdate(‘Y-m-d H:i:s’,
$post[22][23]);

The `$post[24]` array contains the Unix timestamps that FeedWordPress got from the feed. The PHP [25](http://us3.php.net/manual/en/function.date.php) function formats a Unix timestamp relative to the local time zone. The [26](http://us3.php.net/manual/en/function.gmdate.php) function formats it relative to Greenwich Mean Time. Given that I need local and Greenwich representations of the date and time that the post was first published, and of the date and time that the post was last updated, this seems like the sensible thing to do. But in spite of (or because of) its seeming so sensible, this way of generating post timestamps introduces a subtle bug. More on that later.

When determining whether or not a post has been updated, FeedWordPress uses two items of information: the last-updated date and time provided by the feed, and the last-updated date and time stored in the database. In order to get these two dates into a common format so that they can be compared, FeedWordPress uses either `strtotime()` or `parse_w3cdtf()` to convert the feed’s last-updated date and time to a Unix timestamp, and it uses the MySQL function [27](http://dev.mysql.com/doc/refman/5.0/en/date-and-time-functions.html#function_unix-timestamp) to get a Unix timestamp from the last-updated date and time in the database. So here is how I did this in version 0.981:

$guid = $post[28];
$result = $wpdb->get_row(”
SELECT id, guid, UNIX_TIMESTAMP(post_modified) AS modified
FROM $wpdb->posts WHERE guid=’$guid’
“);

if (!$result) :
$freshness = 2; // New content
elseif ($post[29][30] > $result->modified) :
$freshness = 1; // Updated content
else :
$freshness = 0;
endif;

`strtotime()` and `parse_w3cdtf()` take account of time zone data; `UNIX_TIMESTAMP()` presumes that the time is in the local time zone. So, I just need to feed it the DATETIME object that’s in the local time zone — `post_modified` instead of `post_modified_gmt`, right? Wrong. Again, in spite of (or because of) its seeming so sensible, this way of comparing timestamps introduces a subtle bug.

Here’s what was wrong with both of these sensible steps: **in any given WordPress installation, there are *three* potentially distinct local time zones that you have to consider**:

1. The local time zone of the web server on which WordPress is running (usually set by the web server’s administrator);

2. The local time zone of the MySQL server that provides the WordPress database (usually set by the MySQL server’s administrator);

3. The local time zone set by the user in WordPress’s General Options page (set by the blog owner);

If any of these differ from each other, then the mismatch could cause problems for the way that older versions of FeedWordPress handled dates.

When the PHP date and time functions convert back and forth between human-readable formats and Unix time stamps, they do so relative to the web server’s local time zone. When MySQL converts a DATETIME object to a Unix timestamp, it does so relative to the MySQL server’s local time zone. When WordPress prepares dates and times for storage in the database, or processes them for sorting and displaying posts, it does so relative to WordPress’s local time zone, as set under General Options.

So, when FeedWordPress used the PHP date and time functions to generate `post_date` and `post_modified`, it used *the wrong time zone* — WordPress expects these to be local times *in the time zone set under General Options*, but the PHP functions use the *web server’s* local time zone. If the user has set a different time zone from the web server’s default time zone, then this date and time information will be incorrect. In order to get the *correct* time, we need to get the time zone information from the WordPress database, and then manually apply that offset, rather than leaning on PHP’s date and time functions. So here is how we do this task in FeedWordPress 0.99:

// Dealing with timestamps in WordPress is so fucking fucked.
$offset = (int) get_option(‘gmt_offset’) * 60 * 60;
$this->post[31] =
gmdate(‘Y-m-d H:i:s’, $this->published() + $offset);
$this->post[32] =
gmdate(‘Y-m-d H:i:s’, $this->updated() + $offset);
$this->post[33] =
gmdate(‘Y-m-d H:i:s’, $this->published());
$this->post[34] =
gmdate(‘Y-m-d H:i:s’, $this->updated());

Note that we use `gmdate()` in all cases, because we are doing the time zone offset manually rather than letting PHP do it for us.

On the other hand, when FeedWordPress used the MySQL date and time functions to convert MySQL DATETIME objects to Unix timestamps, it used the wrong time zone again — since it was using `post_modified`, and in the older versions of FeedWordPress `post_modified` was generated using PHP date and time functions, the time was a local time relative to the *web server’s* time zone. But `UNIX_TIMESTAMP()` presumes that the time it is given is a local time relative to the *MySQL server’s* time zone. Usually this difference should cause no problem, since the web server and the MySQL server are the same machine, or if not the same machine, at least machines that are located in the same place as one another. But if that assumption ever fails, `UNIX_TIMESTAMP()` will return the wrong time–a time that is either a few hours before, or a few hours after, the real last-updated time. Which will mean that posts either get updated when there’s nothing new to update, or don’t get updated even when there is something new to include.

So we need to convert the MySQL DATETIME value to a Unix timestamp in a context where we know, and can set, the right time zone for the conversion. In this case, the best thing to do is to get the *GMT* date and time of the last update (in order to avoid issues that might arise from changes in the local timezone setting in WordPress), and then manually convert that into a Unix timestamp using a function that works relative to GMT. So here’s how FeedWordPress 0.99 checks the update times against each other:

$guid = $wpdb->escape($this->guid());

$result = $wpdb->get_row(”
SELECT id, guid, post_modified_gmt
FROM $wpdb->posts WHERE guid=’$guid’
“);

preg_match(‘/([35]+)-([36]+)-([37]+) ([38]+):([39]+):([40]+)/’,
$result->post_modified_gmt, $backref);
$updated = gmmktime($backref[41], $backref[42], $backref[43],
$backref[44], $backref[45], $backref[46]);
if (!$result) :
$this->_freshness = 2; // New content
elseif ($this->updated() > $updated) :
$this->_freshness = 1; // Updated content
$this->_wp_id = $result->id;
else :
$this->_freshness = 0; // Same old, same old
$this->_wp_id = $result->id;
endif;

`post_modified_gmt` always returns the string representation of a MySQL DATETIME object; the regular expression breaks that representation down into its component parts; and the PHP function [47](http://us3.php.net/gmmktime) reassembles those parts into a Unix timestamp. (You might worry that using the PHP date and time functions might reintroduce the first problem, since it doesn’t account for the local time zone set in WordPress. But since everything is guaranteed to be in GMT, this problem doesn’t arise.)

Strictly speaking, it would probably be better to use MySQL functions, instead of a regular expression, to extract the parts of the MySQL DATETIME object, since ostensibly MySQL knows more about its internal formats than PHP does. In practice this is not likely to make a difference, but it’s likely that in future releases of FeedWordPress I’ll change the section to something more like this:

$guid = $wpdb->escape($this->guid());

$result = $wpdb->get_row(”
SELECT
id, guid,
YEAR(post_modified_gmt) AS year,
MONTH(post_modified_gmt) AS month,
DAYOFMONTH(post_modified_gmt) AS day,
HOUR(post_modified_gmt) AS hour,
MINUTE(post_modified_gmt) AS minute,
SECOND(post_modified_gmt) AS second
FROM $wpdb->posts WHERE guid=’$guid’
“);

if (!$result) :
$this->_freshness = 2; // New content
else:
$updated = gmmktime(
$result->hour, $result->minute, $result->second,
$result->month, $result->day, $result->year
);
if ($this->updated() > $updated) :
$this->_freshness = 1; // Updated content
$this->_wp_id = $result->id;
else :
$this->_freshness = 0; // Same old, same old
$this->_wp_id = $result->id;
endif;
endif;

Oh, and in case you were wondering, the reason that moving across the country helped me find this out is that I moved from Eastern Time to Pacific Time, and I changed the default time zone on one of my web servers before I changed the default time zone on my MySQL server. The mismatch exposed this bug while I was doing testing for most recent release of FeedWordPress[48]. Not particularly interesting, but it did expose a bug to fix, and I hope the guide to time zone issues that resulted may be of some interest.

FeedWordPress 0.99 is hereby released; enjoy WP 2.2 and 2.3 compatibility, bug fixes, major new features, updates without cron

Update 2007-11-21: FeedWordPress 0.99 is now out of date. You can download the latest release — 0.991 at the time of this writing — from the project homepage.

public (non-beta) release of **FeedWordPress version 0.99** is now available for download.(http://projects.radgeek.com/download/feedwordpress-0.99.tar.gz)

There have been changes to the way that FeedWordPress’s code is organized since version 0.98. If you successfully installed either of the beta releases, you don’t need to do anything special to install the current release. However, if you are upgrading from version 0.98 or before, be sure to see the **installation instructions** below.

### Changes since version 0.98 ###

This release provides compatibility with WordPress 2.2 and 2.3. It has been extensively tested against WordPress version 2.2.3 and the version 2.3 release candidate. I think that all the compatibility issues have been hammered out; of course, if you notice any problems, please let me know and I’ll get on a bugfix as soon as possible.

Version 0.99 also includes an overhaul to the user interface, some significant new features, and a number of bug fixes:

* **AUTOMATIC UPDATES WITHOUT CRON:** FeedWordPress now allows you to
automatically schedule checks for new posts without using external task
scheduling tools such as cron. In order to enable automatic updates, go
to **Syndication –> Options** and set “Check for new posts” to
“automatically.” When this option is turned on, FeedWordPress will check for new posts
automatically (1) when someone views your page, (2) if it has been ten minutes (or
whatever interval you set) since the last time someone viewed your page. This offers a
way to keep FeedWordPress up-to-date without having to schedule a cron script. It also
simplifies the process of updating if you do choose to use a cron script — just have curl
fetch your home page on a fixed schedule (so, for example, I would execute
`curl http://feministblogs.org/` every 15 minutes to keep Feminist Blogs up-to-date).
Note that this is not the same thing as precisely scheduled updates — at a minimum,
FeedWordPress will not check for new posts unless and until the next time somebody
views your page. But for practical purposes it does allow you to keep your aggregator
updated without having to run cron, and it is as close to precisely scheduled updates as
you can get without using real scheduling tools such as cron.

An important side-effect of the changes to the update system is that if
you were previously using the cron job and the `update-feeds.php` script
to schedule updates, you need to change your cron set-up. The old
`update-feeds.php` script no longer exists. Instead, if you wish to use
a cron job to guarantee updates on a particular schedule, you should
have the cron job fetch the front page of your blog (for example, by
using `curl http://www.zyx.com/blog/ > /dev/null`) instead of activating
the `update-feeds.php` script. If automatic updates have been enabled,
fetching the front page will automatically trigger the update process.

* **INTERFACE REORGANIZATION:** All FeedWordPress functions are now located
under a top-level “Syndication” menu in the WordPress Dashboard. To
manage the list of syndicated sites, manually check for new posts on
one or more feeds, or syndicate a new site, you should use the main page
under **Syndication**. To change global settings for FeedWordPress,
you should use **Syndication –> Options**.

* **FILE STRUCTURE REORGANIZATION:** Due to a combination of changing styles
for FeedWordPress plugins and lingering bugs in the FeedWordPress admin
menu code, the code for FeedWordPress is now contained in two different
PHP files, which should be installed together in a subdirectory of your
plugins directory named `feedwordpress`. (See README.text for
installation and upgrade instructions relating to the change.)

* **MULTIPLE CATEGORIES SETTING:** Some feeds use non-standard methods to
indicate multiple categories within a single category element. (The most
popular site to do this is del.icio.us, which separates tags with a
space.) FeedWordPress now allows you to set an optional setting, for any
feed which does this, indicating the character or characters used to
divide multiple categories, using a Perl-compatible regular expression.
(In the case of del.icio.us feeds, FeedWordPress will automatically use
\s for the pattern without your having to do any further configuration.)
To turn this setting on, simply use the “Edit” link for the feed that
you want to turn it on for.

* **REGULAR EXPRESSION BUG FIXED:** Eliminated a minor bug in the regular
expressions for e-mail addresses (used in parsing RSS `author`
elements), which could produce unsightly error messages for some users
parsing RSS 2.0 feeds.

* **DATE / UPDATE BUG FIXED:** A bug in date handling was eliminated that may
have caused problems if any of (1) WordPress, or (2) PHP, or (3) your
web server, or (4) your MySQL server, has been set to use a different
time zone from the one that any of the others is set to use. If
FeedWordPress has not been properly updating updated posts, or has been
updating posts when there shouldn’t be any changes for the update, this
release may solve that problem.

* **GOOGLE READER BUGS FIXED:** A couple of bugs that made it difficult for
FeedWordPress to interact with Google Reader public feeds have been
fixed. Firstly, if you encountered an error message reading “There was a
problem adding the newsfeed. ” when you tried to add the feed,
the cause of this error has been fixed. Secondly, if you succeeded in
getting FeedWordPress to check a Google Reader feed, only to find that
the title of posts had junk squashed on to the end of them, that bug
has been fixed too. To fix this bug, you must install the newest version
of the optional MagpieRSS upgrade.

* **FILTER PARAMETERS:** Due to an old, old bug in WordPress 1.5.0 (which was
what was available back when I first wrote the filter interface),
FeedWordPress has traditionally only passed one parameter to
syndicated_item and syndicated_post filters functions — an array
containing either the Magpie representation of a syndicated item from
the feed, or the database representation of a post about to be inserted
into the WordPress database. If you needed information about the feed
that the item came from, this was accessible only through a pair of
global variables, $fwp_channel and $fwp_feedmeta.

Since it’s been a pretty long time since WordPress 1.5.0 was in
widespread usage, I have gone ahead and added an optional second
parameter to the invocation of the syndicated_item and syndicated_post
filters. If you have written a filter for FeedWordPress that uses either
of these hooks, you can now register that filter to accept 2 parameters.
If you do so, the second parameter will be a SyndicatedPost object,
which, among other things, allows you to access information about the
feed from which an item is syndicated using the $post->feed and the
$post->feedmeta elements (where $post is the name of the second
parameter).

NOTE THAT THE OLD GLOBAL VARIABLES ARE STILL AVAILABLE, for the time
being at least, so existing filters will not break with the upgrade.
They should be considered deprecated, however, and may be eliminated in
the future.

* **FILTER CHANGE / BUGFIX:** the array that is passed as the first argument
syndicated_post filters no longer is no longer backslash-escaped for
MySQL when filters are called. This was originally a bug, or an
oversight; the contents of the array should only be escaped for the
database *after* they have gone through all filters. IF YOU HAVE WRITTEN
ANY syndicated_post FILTERS THAT PRESUME THE OLD BEHAVIOR OF PASSING IN
STRINGS THAT ARE ALREADY BACKSLASH-ESCAPED, UPDATE YOUR FILTERS
ACCORDINGLY.

* **OTHER MINOR BUGFIXES AND INTERNAL CHANGES:** The internal architecture of
FeedWordPress has been significantly changed to make the code more
modular and clean; hopefully this should help reduce the number of
compatibility updates that are needed, and make them easier and quicker
when they are needed.

### Installation instructions ###

To *upgrade* an existing installation of FeedWordPress to version 0.99:

1. Download the FeedWordPress archive in zip or gzipped tar format and
extract the files on your computer.

2. If you are upgrading from **version 0.98 or earlier**, then you need to
create a new directory named `feedwordpress` in the `wp-content/plugins`
directory of your WordPress installation, and you also need to *delete*
your existing `wp-content/update-feeds.php` and
`wp-content/plugins/feedwordpress.php` files. The file structure for
FeedWordPress has changed and the files from your old version will not
be overwritten, which could cause conflicts if you leave them in place.

3. Upload the new PHP files to `wp-content/plugins/feedwordpress`,
overwriting any existing FeedWordPress files that are there. Also be
sure to upgrade `wp-includes/rss.php` and
`wp-includes/rss-functions.php` if you use the optional MagpieRSS
upgrade, or don’t use it yet but do want to syndicate Atom 1.0 feeds.

3. If you are upgrading from **version 0.96 or earlier**, **immediately** log
in to the WordPress Dashboard, and go to Options –> Syndicated. Follow
the directions to launch the database upgrade procedure. The new
versions of FeedWordPress incorporate some long-needed improvements, but
old meta-data needs to be updated to prevent duplicate posts and other
possible maladies. If you’re upgrading an existing installation, updates
and FeedWordPress template functions *will not work* until you’ve done
the upgrade. Then take a coffee break while the upgrade runs. It should,
hopefully, finish within a few minutes even on relatively large
databases.

4. If you are upgrading from **version 0.98 or earlier**, note that the old
`update-feeds.php` has been eliminated in favor of a (hopefully) more
humane method for automatic updating. If you used a cron job for
scheduled updates, it will not work anymore, but there is another,
simpler method which will. See Up Feed Updates[1] to get
scheduled updates back on track.

5. Enjoy your new installation of FeedWordPress.

Up Feed Updates: http://projects.radgeek.com/feedwordpress/install/#setting-up-feed-updates

FeedWordPress 0.99 beta 2. Testers still wanted.

Update 2007-11-21: FeedWordPress 0.99b2 is now out of date. You can download the latest release — 0.991 at the time of this writing — from the project homepage.

Thanks to everyone who has been trying out first beta release of FeedWordPress 0.99(http://projects.radgeek.com/2007/09/14/feedwordpress-099-beta-1-testers-wanted/). In response to my own tests and some feedback from users, I have prepared a second beta release, FeedWordPress 0.99b2, which all are welcome to download and test out.

Again, by beta, I really mean beta, not one of those Web 2.0 perpetual beta releases. The point is to put it out there for you all to test out. You should not count on this release being in full working order. There are features due for this release that I haven’t implemented. I will implement them later. Those that I have implemented all seem to be in working order on my end of things, but everyone’s Apache/PHP/MySQL/WordPress/etc. stack is so different that it’s hard to make any promises about how it will work for you, until y’all have had some time to test it.

With that pre-amble out of the way, if you are interested in testing out the beta release, you should feel free to FeedWordPress 0.99b2[1], *read the installation instructions below*, give it a test run, and me know(http://radgeek.com/contact) how it works for you.

[2]: http://projects.radgeek.com/wp-content/download/feedwordpress-0.99b2.tar.gz

If you are installing this beta as an upgrade over FeedWordPress 0.981 or earlier, please be sure to *follow the installation instructions below*. If you have already installed 0.99b1 and are installing the new beta over that, you can just replace the old files with the new ones.

**Installation instructions:** You may have noticed that I have reorganized the file structure of the plugin. Because of this, if you have an older release of FeedWordPress installed, and intend to install the beta release over the older release, first you are going to need to go to your old installation and delete two of the old installation’s files (`wp-content/update-feeds.php` and `wp-content/feedwordpress.php`). Once this is done, create a new directory in your plugins directory, `wp-content/plugins/feedwordpress/`, and copy the new release’s plugin files to this directory. If you don’t delete the old files, then they will not get overwritten and there may be a conflict between the old and new versions. If you do not install the new files in their own directory, the menus will probably not work correctly.

Enjoy, and let me know how it works for you!

FeedWordPress 0.99 beta 1. Testers wanted.

Update 2007-11-21: FeedWordPress 0.99b1 is now out of date. You can download the latest release — 0.991 at the time of this writing — from the project homepage.

It’s been a long time, for several different personal reasons that don’t bear going into here, but the good news is that I am at long last coming back to active development on FeedWordPress. There are some bug fixes and a lot of feature requests that have been waiting for quite some time; and I will be able to start cleaning these out over the course of the next few days.

Toward that end, I am putting out a *beta release* of the next version of FeedWordPress. By beta, I really mean beta, not one of those Web 2.0 perpetual beta releases. The point is to put it out there for you all to test out. You should not count on this release being in full working order. There are features due for this release that I haven’t implemented. I will implement them later. Those that I have implemented all seem to be in working order on my end of things, but everyone’s Apache/PHP/MySQL/WordPress/etc. stack is so different that it’s hard to make any promises about how it will work for you, until y’all have had some time to test it. With that pre-amble out of the way, if you are interested in testing out the beta release, you should feel free to FeedWordPress 0.99b1[1], *read the installation instructions below*, give it a test run, and me know(http://radgeek.com/contact) how it works for you.

[2]: http://projects.radgeek.com/wp-content/download/feedwordpress-0.99b1.tar.gz

So, what’s new? Well, a fair amount has changed under the hood, much of it things that you won’t notice, but which will hopefully clean up the code a bit and make compatibility releases quicker and easier to put out in the future. But there are a couple of significant changes that you will notice.

1. First, FeedWordPress functions have been moved to their own top-level menu, currently called Syndication. To syndicate new feeds, change settings on existing feeds, change global options for FeedWordPress, or to manually instruct FeedWordPress to check for new posts, use the Syndication top-level menu and its submenus.

2. Second, I am changing the way that FeedWordPress checks for new posts. Specifically, I am making the process somewhat less arcane, and making it possible (more or less) to keep up automatic updates *even if you do not have access to `cron`*. To turn this feature on, go to **Syndication –> Options** and tell FeedWordPress to check for new posts automatically. (This option is currently *not* on by default.)

When this option is turned on, FeedWordPress will check for new posts automatically (1) when someone views your page, (2) if it has been ten minutes (or whatever interval you set) since the last time someone viewed your page. This offers a way to keep FeedWordPress up-to-date without having to schedule a cron script. It also simplifies the process of updating if you do choose to use a cron script — just have curl fetch your home page on a fixed schedule (so, for example, I would execute `curl http://feministblogs.org/` every 15 minutes to keep Feminist Blogs up-to-date). Note that this is not the same thing as precisely scheduled updates — at a minimum, FeedWordPress will not check for new posts unless and until the next time somebody views your page. But for practical purposes it does allow you to keep your aggregator updated without having to run cron, and it is as close to precisely scheduled updates as you can get without using real scheduling tools such as cron.

3. I have had several questions about compatibility between FeedWordPress and WordPress 2.2. I have checked this beta release with the latest release of WordPress 2.2 on my testbed server and I have encountered no problems. I do not know of any changes between WordPress 2.1 and 2.2 which would introduce an incompatibility. But please let me know if you have any compatibility issues with WordPress 2.2.

Note that if you are using the beta release of WordPress 2.3, there are changes to the WordPress category system that probably *will* cause compatibility problems with FeedWordPress. This should hopefully be fixed in the next beta release, which should be out sometime within the next few days.

4. As mentioned, I have re-organized a bit. Please make sure you follow the installation instructions below.

**Installation instructions:** You may have noticed that I have reorganized the file structure of the plugin. Because of this, if you have an older release of FeedWordPress installed, and intend to install the beta release over the older release, first you are going to need to go to your old installation and delete two of the old installation’s files (`wp-content/update-feeds.php` and `wp-content/feedwordpress.php`). Once this is done, create a new directory in your plugins directory, `wp-content/plugins/feedwordpress/`, and copy the new release’s plugin files to this directory. If you don’t delete the old files, then they will not get overwritten and there may be a conflict between the old and new versions. If you do not install the new files in their own directory, the menus will probably not work correctly.

Enjoy, and let me know how it works for you!

FeedWordPress 0.981: 1970 date bug re-fixed

Update 2007-11-21: FeedWordPress 0.981 is now out of date. You can download the latest release — 0.991 at the time of this writing — from the project homepage.

If you have been experiencing a bug with FeedWordPress 0.981, which leads to new posts from Atom feeds being dated back to 1970, then you should download a fresh copy of FWP 0.981. Some user bug reports (thanks!) alerted me to the fact that I’d accidentally packaged an older version of the MagpieRSS upgrade in the 0.981 release, which did not fix this bug. The correct version of `rss.php` is now included, and will solve the problem.

You can get the fix by grabbing 0.981 in a gzipped tar(http://projects.radgeek.com/download/feedwordpress-0.981.tar.gz) or 0.981 in a zip archive(http://projects.radgeek.com/download/feedwordpress-0.981.zip).

FeedWordPress filter poll

I am working on version 0.99 of FeedWordPress, which I hope to release sometime in the next couple weeks. One of the less obvious changes that I hope to accomplish to clean up the internal code, which has become a bit ugly and crufty over time. One thing that I would like to overhaul, if I can do so, is the way that FeedWordPress passes information to filters. But I am not yet sure whether or not I can safely do this. **That’s where you come in.**

FeedWordPress allows you to write filters that can transform, filter out, or take actions in response to, new posts coming in. Since these filters are written in PHP, the mechanism is extraordinarily flexible if you know how to use it, but judging from the e-mail I get most people don’t yet know how to use it. (That’s something I hope to address in the future with some example scripts and better documentation. But one thing a time.)

So, here are the questions. Feel free to answer them as you see fit in the comments section or by e-mail.

1. Do you use PHP filters together with FeedWordPress (e.g. `syndicated_item` or `syndicated_post` fliters)?

2. If you do, then what do those filters do?

3. Do your filters rely on any information from the global variables `$fwp_channel` or `$fwp_feedmeta`?

4. What versions of WordPress and FeedWordPress are you using?

Answers will help me make an informed decision about what to do with FeedWordPress’s handling of filters, which will hopefully maximize benefits while minimizing headaches. Let me know!

FeedWordPress 0.981: bugfix and compatibility release allowing use with WordPress 2.1

Update 2007-11-21: FeedWordPress 0.981 is now out of date. You can download the latest release — 0.991 at the time of this writing — from the project homepage.

There’s a lot to say about some long-awaited and frustratingly long-delayed improvements to FeedWordPress, but I don’t have much time tonight, so I’ll be brief.

**FeedWordPress is now compatible with WordPress 2.1.** 0.981 is now available for download[1] (also available in format[2]); the major feature behind this release is code to accommodate the changes to the structure of WordPress’s database between version 2.0.x and 2.1, which until now caused a number of SQL errors and prevented WordPress from syndicating new posts when installed with the latest version of WordPress.

**There is one important change that you should note about the installation procedure.** Due to what seems to me like a fairly pointless bit of wordsmithing on the part of the WordPress development team, you now need to install *two* files from the `OPTIONAL/wp-includes`
directory in order to successfully upgrade your version of MagpieRSS. (The upgrade is necessary for FeedWordPress to support enclosures, multiple categories, or Atom 1.0 feeds.) Be sure that you copy *both* `rss-functions.php` and `rss.php` to your `wp-includes` directory when upgrading MagpieRSS; if you copy only `rss-functions.php` you will *not* end up with a working MagpieRSS (or FeedWordPress) installation.

[3]: http://projects.radgeek.com/download/feedwordpress-0.981.tar.gz
format: http://projects.radgeek.com/download/feedwordpress-0.981.zip

In addition to the compatibility update, and the changes to the installation procedure, some changes have been made to the user interface code which should help FeedWordPress’s pages fit in better with the WordPress 2.x user interface. In particular, the “Categories” checkboxes for assigning categories to all posts syndicated from any source (under Options –> Syndication) or to all posts syndicated from a particular feed (under Blogroll –> Syndicated) should no longer cause an ugly spill all over the interface.

There are also some important fixes to some outstanding and irritating bugs. Here’s a quick summary of the other changes in this release:

* **DATE BUG AFFECTING SOME PHP INSTALLATIONS RESOLVED:** due to a subtle bug
in parse_w3cdtf(), some installations of PHP encountered problems with
FeedWordPress’s attempt to date posts, which would cause some new posts
on Atom feeds to be dated as if they had apppeared in 1969 or 1970
(thus, effectively, never appearing on front apge at all). This bug in
the date handling should now be fixed.

* **PHP `` SHORT FORM ELIMINATED:** some installations of PHP do not
allow the `` short form for printing PHP values, which was used
extensively in the FeedWordPress interface code. Since this could cause
fatal errors for users with the wrong installation of PHP, the short
form has been replaced with full PHP echo statements, and is no longer
used in FeedWordPress.

* **GLOBAL CATEGORIES BUG RESOLVED:** a bug that prevented some users from
setting one or more categories to apply to syndicated posts from all
feeds (using the checkbox interface under Options –> Syndication) has
been resolved.

Please note that 0.981 is preliminary work which I hope will be followed by ongoing work to better integrate FeedWordPress with the new features offered by recent releases of WordPress. If you encounter any problems with it, please be sure to in touch(http://radgeek.com/contact) with me and send as detailed a report of the bug you are encountering as possible. In the next few weeks I hope to be working on a number of other improvements that will bring much more substantial changes to both the user experience and the technical underpinnings for FeedWordPress. As we move towards a 1.0 release, I have high hopes that your experience as a user will get substantially simpler, while the back-end will become substantially more sophisticated.

In any case, **watch this space:** it’s been slow for the pas several months, but there are some big things coming soon.

Enjoy!

FeedWordPress 0.98: now compatible with WordPress 2.0

Update 2007-11-21: FeedWordPress 0.98 is now out of date. You can download the latest release — 0.991 at the time of this writing — from the project homepage.

First things first.

**FeedWordPress is now compatible with WordPress 2.0.** 0.98 is now available for download[1] (also available in format[2]).

[3]: http://projects.radgeek.com/download/feedwordpress-0.98.tar.gz
format: http://projects.radgeek.com/download/feedwordpress-0.98.zip

It’s been way too long since I’ve been able to work on FeedWordPress. Since the last release (0.97, 6 November 2005), WordPress 2.0 has been finalized and released, much to the improvement of WordPress as a piece of software. The downside is that WordPress 2.0 features some changes to the database schema that broke FeedWordPress’s forward-compatibility, so until now you had to rely on quick code hacks to get updates working.

No more. The official release now should work just as well with *either* WordPress 1.5 *or* WordPress 2.0. WordPress 2.0 also makes many more API calls available that let plugin developers avoid direct manipulation of the database; where possible, I’ve taken advantage of these, and my hope is that this will make future releases of WordPress substantially less likely to break FeedWordPress, even if they change database schemas. That’s the hope anyway.

This release has been tested for basic functionality on installations of both WordPress 1.5 and WordPress 2.0. It’s possible that there may still be subtle, non-fatal bugs that I haven’t discovered: if so, please let me know about them in the comments or in private.

Enjoy!

Posted in Uncategorized

FeedWordPress 0.97: one small increment for the revision number, one giant leap for the software

Update 2007-11-21: FeedWordPress 0.97 is now out of date. You can download the latest release — 0.991 at the time of this writing — from the project homepage.

Huzzah! 0.97 is now available for download[1] (also in format[2], if you’re in to that kind of thing). Enjoy, and please feel free to report any problems you have with the software or the documentation to me in the comments section below or e-mail(http://radgeek.com/contact).

[3]: http://projects.radgeek.com/download/feedwordpress-0.97.tar.gz
[4]: http://projects.radgeek.com/download/feedwordpress-0.97.zip

Version 0.97 represents *major* changes, I hope for the better, on several fronts in FeedWordPress. (If I weren’t running out of revision numbers between the current version and 1.0, I would have added a lot more than 0.01 to the version. Stupid decimal notation.) This release will address several long-standing bugs, and hopefully also make other bugs easier to diagnose and to fix. First, the minor inconvenience that this update will impose on you if you are upgrading:

* **INSTALLATION PROCEDURE:** Some of the changes between 0.96 and 0.97
require upgrades to the meta-data stored by FeedWordPress to work
properly. Thus, if you are upgrading from 0.96 or earlier to 0.97, most
FeedWordPress operations (including updates and template functions)
WILL BE DISABLED until you run the upgrade procedure. Fortunately,
running the upgrade procedure is easy: just go to either Options –>
Syndication or Links –> Syndicated in the WordPress Dashboard and press
the button.

Now, the fun stuff. The most important are the new, humane interface for setting feed-specific settings (check it out under Links –> Syndicated –> Edit … no more nerding around with key-value pairs!), Atom 1.0 support, and the overhaul of `update-feeds.php`. Details follow:

* **FEED FORMAT SUPPORT:** Support has been added for the Atom 1.0 IETF
standard. Several other elements are also newly supported
(dcterms:created, dcterms:issued, dcterms:modified, dc:identifier,
proper support for the RSS 2.0 guid element, the RSS 2.0 author element,
the use of Atom author or Dublin Core dc:creator constructs at the feed
level to identify the author of individual items, etc.)

N.B.: full support of several Atom 1.0 features, such as categories
and enclosures, requires you to install the optional rss-functions.php
upgrade in your wp-includes directory.

* **BUG FIX:** Running `update-feeds.php` from command line or crontab
returned “I don’t syndicate…” errors. It turns out that WordPress
sometimes tramples on the internal PHP superglobals that I depended on
to determine whether or not the script was being invoked from the
command line. This has been fixed (the variables are now checked
*before* WordPress can trample them). Note that `update-feeds.php` has
been thoroughly overhauled anyway; see below for details.

* **BUG FIX:** Duplicate categories or author names. Fixed two bugs that could
create duplicate author and/or category names when the name contained
either (a) certain international characters (causing a mismatch between
MySQL and PHP’s handling of lowercasing text), or (b) characters that
have a special meaning in regular expressions (causing MySQL errors when
looking for the author or category due to regexp syntax errors). These
should now be fixed thanks to careful escaping of names that go into
regular expressions and careful matching of lowercasing functions
(comparing results from PHP only to other results from PHP, and results
from MySQL only to other results from MySQL).

* **BUG FIX:** Items dated Decembr 31, 1969 should appear less often. The
function for parsing W3C date-time format dates that ships with
MagpieRSS can only correctly parse fully-specified dates with a
fully-specified time, but valid W3C date-time format dates may omit the
time, the day of the month, or even the month. Some feeds in the wild
date their items with coarse-grained dates, so the optional
`rss-functions.php` upgrade now includes a more flexible parse_w3cdtf()
function that will work with both coarse-grained and fully-specified
dates. (If parts of the date or the time are omitted, they are filled in
with values based on the current time, so ‘2005-09-10’ will be dated to
the current time on that day; ‘2004’ will be dated to this day and time
one year ago.

N.B.: This fix is only available in the optional `rss-functions.php`
upgrade.

* **BUG FIX:** Evil use of HTTP GET has been undone. The WordPress interface
is riddled with inappropriate (non-idempotent) uses of HTTP GET queries
(ordinary links that make the server do something with significant
side-effects, such as deleting a post or a link from the database).
FeedWordPress did some of this too, especially in places where it aped
the WordPress interface (e.g. the “Delete” links in Links –>
Syndicated). That’s bad business, though. I’ve changed the interface so
that all the examples of improper side-effects that I can find now
require an HTTP POST to take effect. I think I got pretty much
everything; if there’s anything that I missed, let me know.

Further reading: Ruby 2005-05-06: This Stuff Matters (http://www.intertwingly.net/blog/2005/05/06/This-Stuff-Matters)

* **BUG FIX:** Categories applied by `cats` setting should no longer prevent
category-based filtering from working. In FeedWordPress, you can (1)
apply certain categories to all syndicated posts, or all posts from
a particular feed; and (2) filter out all posts that don’t match one
of the categories that are already in the WordPress database (allowing
for simple category-based filtering; just load up WordPress with the
categories you want to accept, and then tell FeedWordPress not to create
new ones). However, the way that (1) and (2) were implemented meant that
you couldn’t effectively use them together; once you applied a known
category to all syndicated posts from a particular feed, it meant that
they’d have at least one familiar category (the category or categories
you were applying), and that would get all posts past the filter no
matter what categories they were originally from.

Well, no longer. You can still apply categories to all syndicated posts
(using either Syndication –> Options, or the feed-level settings under
Links –> Syndicated). But these categories are not applied to the post
until *after* it has already passed by the “familiar categories” filter.
So now, if you want, you can do category filtering and *then* apply as
many categories as you please to all and only posts that pass the filter.

* **BUG FIX:** Other minor typos and HTML gaffes were fixed along the way.

* **PERFORMANCE:** get_feed_meta() no longer hits the database for information
on every call; it now caches link data in memory, so FeedWordPress only
goes to the database once for each syndicated link. This may
substantially improve performance if your database server resources
are tight and your templates make a lot of use of custom settings from
get_feed_meta().

* **API CHANGE:** Link ID numbers, rather than RSS URIs, are now used to
identify the feed from which a post is syndicated when you use template
functions such as get_feed_meta(). The practical upshot of this is you
can switch feeds, or change the feed address for a particular syndicated
site, without breaking your templates for all the posts that were
syndicated from the earlier URI.

* **API CHANGE:** if you have plugins or templates that make use of the
get_feed_meta() function or the $fwp_feedmeta global, note that the
data formerly located under the `uri` and `name` fields is now located
under the `link/uri` field and the `link/name` field, respectively. Note
also that you can access the link ID number for any given feed under the
global $fwp_feedmeta[5] (in plugins) or
get_feed_meta(‘link/id’) (in a template in post contexts).

* **FEATURE:** the settings for individual feeds can now be edited using a
humane interface (where formerly you had to tweak key-value pairs in the
Link Notes section). To edit settings for a feed, pick the feed that you
want under Links –> Syndicated and click the Edit link.

* **FEATURE:** The “Unsubscribe” button (formerly “Delete”) in Links –>
Syndicated now offers three options for unsubscribing from a feed: (1)
turning off the subscription without deleting the feed data or affecting
posts that were syndicated from the feed (this works by setting the Link
for the feed as “invisible”); (2) deleting the feed data and all of the
posts that were syndicated from the feed; or (3) deleting the feed data
and *keeping* the posts that were syndicated from the feed
setting the Link to “Invisible” (meaning that it will not be displayed
in lists of the site links on the front page, and it won’t be checked
for updates; (2) deleting the Link and all of the posts that were
syndicated from its feed; or (3) deleting the feed data but keeping the
posts that were syndicated (which will henceforward be treated as if
they were local rather than syndicated posts). (Note that (1) is usually
the best option for aggregator sites, unless you want to clean up the
results of an error or a test.)

* **FEATURE / BUG FIX:** If you have been receiving mysterious “I don’t
syndicate…”, or “(local) HTTP status code was not 200”, or “(local)
transport error – could not open socket”, or “parse error – not well
formed” errors, then this update may solve your problems, and if it does
*not* solve them, it will at least make the reasons for the problems
easier to understand. That’s because I’ve overhauled the way that
FeedWordPress goes about updating feeds.

If you use the command-line PHP scripting method to run scheduled
updates, then not much should change for you, except for fewer
mysterious errors. If you have done updates by sending periodic HTTP
requests to ,
then the details have changed somewhat; mostly in such a way as to make
things easier on you. See the README file or online documentation on
Staying Current for the details.

* **FEATURE:** FeedWordPress now features a more sophisticated system for
timed updates. Instead of polling *every* subscribed feed for updates
*each* time `update-feeds.php` is run, FeedWordPress now keeps track of
the last time it polled each feed, and only polls them again after a
certain period of time has passed. The amount of time is normally set
randomly for each feed, in a period between 30 minutes and 2 hours (so
as to stagger updates over time rather than polling all of the feeds at once. However, the length of time between updates can also be set
directly by the feed, which brings us to …

* **FEATURE:** FeedWordPress now respects the settings in the `ttl` and
Syndication Module RSS elements. Feeds with these elements set will not
be polled any more frequently than they indicate with these feeds unless
the user manually forces FeedWordPress to poll the feed (see Links –>
Syndicated –> Edit settings).