Reading from and Writing to mt_plugindata with PHP

With Movable Type 3.2, we were able to read from mt_plugindata using PHP and with Movable Type 3.31, we're finally able to write to it too! The difficulty with reading/writing to mt_plugindata arises from the fact that anything stored into the plugindata_data field is serialized.

Lets start by looking at some Perl code that reads from mt_plugindata and then look at how we'd convert it to PHP.

require MT::PluginData; ## includes the MT::PluginData class so we can work with mt_pludinata
my $data = MT::PluginData->load({ plugin => 'Melody', key => 'Nelson' }); ## Loads the object with fields plugin 'Melody' and key 'Nelson'
$data->data->{foo} ## Returns the value of the foo key
$data->data->{bar} ## Returns the value of the bar key

To be able to work with Movable Type's database, we need to first initialize an instance of the dynamic MT class and its database object:

include('<$MTCGIServerPath$>/php/mt.php');
$mt = new MT(<$MTBlogID$>, '<$MTConfigFile$>');
$db = $mt->db;

Then we can query the database to get the record with the plugin field equal to Melody and the key field equal to Nelson:

$data = $db->get_var("select plugindata_data from mt_plugindata where plugindata_plugin = 'Melody' and plugindata_key = 'Nelson'", ARRAY_A);

As I had mentioned before, everything in plugindata_data is serialized. So we must unserialize it. This is possible using the aptly named unserialize method of $db, our database object and then all our keys are available to us:

$data = $db->unserialize($data); // Unserializes the results from the previous query 
$data['foo']; // Returns the value of the foo key
$data['bar']; // Returns the value of the bar key

Now lets look at how we'd store data into plugindata_data using PHP. We'll begin with some Perl code again:

require MT::PluginData;
my $data = MT::PluginData->new;
$data->plugin('Melody');
$data->key('Nelson');
$data->data({
    foo => 'apple',
    bar => 5
});
$data->save or die $data->errstr;

With PHP, the contents of plugindata_data needs to be an associative array like so:

$data['foo'] = 'apple';
$data['bar'] = 5;

The next step is to serialize this array so that it can be stored into plugindata_data. To serialize anything, we must first include the MTSerialize.php file and create a new serializer object and then call the serialize method:

require("MTSerialize.php"); // We needn't specify any path because php/lib is automatically added to the PHP include path by the MT constructor
$serializer = new MTSerialize();
$data = $serializer->serialize($data);

Finally we can insert this into the mt_plugindata using a simple SQL query. One thing to be careful of is the result after serialization. Often it will span several lines and hence to be able to use it within an SQL query, it must be escaped. Thankfully escaping involves simplying calling the escape method of the database object:

$data = $db->escape($data);
$db->query("insert into mt_plugindata ('plugindata_plugin', 'plugindata_key', 'plugindata_data') values ('Melody', 'Nelson', '$data')"); // We can use the query method of $db because we're not expecting any result back

In summary, a PHP script to read and write from mt_plugindata would look something like this:

<?php
// First initialize the MT object and create a variable that points to the database
include('<$MTCGIServerPath$>/php/mt.php');
$mt = new MT(<$MTBlogID$>, '<$MTConfigFile$>');
$db =& $mt->db; 

// Next lets get the contents of plugindata_data where plugindata_plugin = 'Melody and plugindata_key = 'Nelson'
$data = $db->get_var("select plugindata_data from mt_plugindata where plugindata_plugin = 'Melody' and plugindata_key = 'Nelson'", ARRAY_A);

// Everything stored in plugindata_data is serialized so to be usable, we must unserialize it
$data = $db->unserialize($data);
$data['foo']; // Returns the value of the foo key
$data['bar']; // Returns the value of the bar key

// Now lets store something back in

$data['foo'] = 'apple';
$data['bar'] = 5;

// Everything stored in plugindata_data is serialized, currently $data isn't, so we need to serialize
require("MTSerialize.php"); // We needn't specify any path because php/lib is automatically added to the include path by the MT constructor
$serializer = new MTSerialize();
$data = $serializer->serialize($data);  

// Escape $data to make sure the query never has a syntax error
$data = $db->escape($data);

// Finally insert the values back into mt_plugindata
$db->query("insert into mt_plugindata ('plugindata_plugin', 'plugindata_key', 'plugindata_data') values ('Melody', 'Nelson', '$data')"); // We can use the query method of $db because we're not expecting any result back  
?>