Migrating CustomFields to Movable Type Professional 4.1

14 Mar 2008 ~ App ~ Comments: 7

Installing CustomFields Upgrade Assistant

If you’re upgrading an MT 4.0 install that was using Arvind’s CustomFields plugin to MTP 4.1 which has CustomFields built in, the first thing you need to know is that MTP will not automatically import your old CustomFields data. You need to install the CustomFields Upgrade Assistant plugin to do the migration for you. (Six Apart please get this out of Trac and into the Plugin Directory!)

A note about installing the upgrader: Arvind’s CustomFields plugin lives in the /plugins/ directory; the CustomFields that ships with MTP lives in the /addons/ directory. You should remove the old CustomFields plugin when installing the CF Upgrade Assistant plugin. Make sure that it’s actually replacing your old /plugins/CustomFields/ directory. Leaving the old plugin code in there presents troubles because MT tries to use the old plugin code. The final location for your CF Upgrade assistant should be /plugins/CustomFields/lib/CustomFieldsUpgrader/

Murphy’s Law

I tried logging into Movable Type, but I kept getting the following error:

A Error during upgrade: Can’t call method “can” on an undefined value at /var/www/dev/html/mt/addons/Commercial.pack/lib/CustomFields/Util.pm line 260

I first thought that the MTP upgrade and the CF Upgrade Assistant could not be run at the same time. However, it turns out that errors in the CF upgrade were keeping me stuck in the upgrade loop.

Important note for Safari users: If the upgrade is throwing errors, you won’t see them if you’re using Safari. I’m not sure why, but when the upgrade fails, it gives no feedback or error message in the log window, returns an “Upgrade Complete!” and throws you right back into an upgrade loop. I suspect it has something to do with the javascript.

Troubleshooting Orphans

Hopefully you didn’t read a space into the first word of that subtitle.

Anyhow, I was stuck in an upgrade loop. David Phillips, God bless his soul, stepped in at this point with some heavy duty troubleshooting. Turns out that the upgrade assistant chokes when it gets to orphaned custom field data. What do I mean by orphaned data? You can create custom fields for almost every object in the system (blog, entry, author). However, the older version of CustomFields would not delete the custom field data even if the object associated with that custom field got deleted. So if you had an entry with custom field data, and that entry was deleted, the custom field data would still live in the database, but you’d never see it in the UI. The upgrade assistant would then find these objects, try to migrate them and then fail because the object they’re supposed to be associated with no longer exists.

Unfortunately, there’s no elegant solution.

At this point, the orphans can only be cleaned up through the database. However, to help speed things up, I’m posting the queries I used to get rid of my orphaned data. You can issue these fairly easily through something like phpMyAdmin or CocoaMySQL. And the standard warning: Make sure you back up your database before doing any type of massive database manipulations.

To clean up orphaned custom fields data associated with entries, use the following SQL query:

 DELETE FROM mt_plugindata WHERE 
 LEFT( plugindata_key, 6 ) = 'entry_' 
 AND plugindata_plugin = 'CustomFields' 
 AND (SELECT entry_id FROM mt_entry 
 WHERE LEFT( plugindata_key, 6 ) = 'entry_' 
 AND plugindata_plugin = 'CustomFields' 
 AND SUBSTRING( plugindata_key, 7 ) = entry_id) IS NULL;

To clean up orphaned custom fields data associated with authors, use the following SQL query:

 DELETE FROM mt_plugindata WHERE
 LEFT( plugindata_key, 1 ) = '_' 
 AND plugindata_plugin = 'CustomFields' 
 AND (SELECT author_id FROM mt_author 
 WHERE LEFT( plugindata_key, 1 ) = '_' 
 AND plugindata_plugin = 'CustomFields' 
 AND SUBSTRING( plugindata_key, 2 ) = author_id) IS NULL;
One Last Bug Squash

All your orphans should be gone. But there’s a minor bug in CustomFields that we need to take care of. If you tried running your upgrade at this point, you’d get this error message:

Error during upgrade: Can’t call method “text” on an undefined value at /var/www/dev/html/mt/addons/Commercial.pack/lib/CustomFields/Util.pm line 322.

You need to edit Util.pm. If you open it up in a text browser, you’ll see this at line 322:

 my $text = ($entry->text || '') . "\n" . ($entry->text_more || '');

Both occurrences of $entry need to be changed to $obj. The final code should look like this:

 my $text = ($obj->text || '') . "\n" . ($obj->text_more || '');
Upgrade!

If you followed these somewhat complicated instructions carefully, the upgrade process should run through smoothly and your CF data should be migrated successfully.

Please feel free to leave your comments or questions here. Several people have told me that they’ve run into this; the more scenarios we can address, the more useful this article will be. Thanks.

Get An Email List of All Authors On Your System

13 Mar 2008 ~ Templates ~ Comments: 2

This little snip of code will dump out a list of all the users and their email addresses on your install in a comma-delimited format that you can easily import into your email client. It’s particularly useful on larger installs:

<mt:Authors include_blogs="all">
    <mt:IfNonEmpty tag="AuthorEmail">
        <mt:IfNonEmpty tag="AuthorDisplayName">"<mt:AuthorDisplayName />" </mt:IfNonEmpty>
        &lt;<mt:AuthorEmail />&gt;,
    </mt:IfNonEmpty>
</mt:Authors>

And the Authors tag allows for all sorts of cool filtering attributes so you can get at any group of authors in the system, ordered however you like:

  • display_name: Specifies a particular author to select.
  • lastn: Limits the selection of authors to the specified number.
  • sortby: Supported values: displayname, name, created_on.
  • sort_order: Supported values: ascend, descend.
  • roles: comma separated list of values. eg “Author, Commenter”
  • need_entry: 1 | 0 (default is 1)
  • status: Supported values: enabled, disabled. Default is enabled.

Note: Some people have asked about creating an email list of all the commenters on the system, and it’s very simple. The code stays the same, but you just need to specify roles=”Commenter” and need_entry=”0” (since most commenters won’t have written an entry). Here’s the code to do it:

 <mt:Authors include_blogs="all" roles="Commenter" need_entry="0" sort_by="display_name"><mt:IfNonEmpty tag="AuthorEmail"><mt:IfNonEmpty tag="AuthorDisplayName">"<mt:AuthorDisplayName />" </mt:IfNonEmpty>&lt;<mt:AuthorEmail />&gt;, </mt:IfNonEmpty>
 </mt:Authors>

Notice the code is much more compressed than the code given previously. If you tried the previous code, you probably noticed that the spacing is crazy because of all the hard returns and spaces we have in there. This second set of code I posted will give you a highly compact list of email addresses than can literally be copied and pasted into an email client.

Just make sure you use this for good, not evil.

Image CustomFields in Movable Type 4.1

5 Mar 2008 ~ Templates ~ Comments: 1

Dilemma: Image Link Instead of Image Many of the sites I build use CustomFields to place a masthead image at the top of an entry. This takes the hassle out of uploading and really just makes it easier for customers... continue →

Movable Type Template Map (.PDF)

25 Feb 2008 ~ Templates ~ Comments: 2

For those of you just upgrading to Movable Type 4, I’m sure you’re experiencing a considerable amount of confusion regarding the new modular template approach. If you’ve just gotten on board, it probably makes even less sense. I won’t... continue →

List Random Authors (via PHP)

24 Jan 2008 ~ Templates ~ Comments: 0

It’s been far too long since I posted to the Tweak. Sometimes it’s hard to document when you’re working, but one of my resolutions is to do better with this (especially with the phenomenal strides Movable Type has taken recently).... continue →

Rotating Banner Ads MT Style

10 Oct 2007 ~ Templates ~ Comments: 6

10/10/2007: Updated for Movable Type 4.x A recent customer asked me if they could have an easy to manage banner ad setup, with the ability to add advertisements and specify links and alternate text. All of this while being able... continue →