A feature you will often see large plugins provide is the ability to import and export their settings, making it much easier to migrate sites or to simply replicate the same setup across multiple sites.
A few days ao I saw a tweet from Sean Davis about how he’d been struggling to successfully build a settings import and export feature in his theme framework:
I completely failed at creating import/export functionality for Volatyl today lol. I'm such a rookie… very resourceful at times, though.
— Sean Davis (@SDavisMedia) December 18, 2013
Sean is a smart guy so I’m sure he figured it out, but it made me realize that a lot of developers are probably unsure of how this kind of feature works. I know that for my first few years in plugin development I certainly had no clue how to write one, but it turns out they are actually not very difficult at all. The most challenging aspect of a settings import and export feature is over thinking them. There is something about the feature that just makes it easy to over complicate.
I have written a sample plugin for you that has a complete settings import and export system to help illustrate how it works, and I’m going to walk you through the process below.
The sample plugin does nothing more than register a settings page with a few options on it, and gives an option to both export and import the settings, as shown in this screenshot:
The export process is simple:
- Retrieve the plugin settings from the database. If not already stored in a single array, put them in an array
- Convert the settings to JSON
- Download the converted settings as a JSON file
And the import process is just as simple:
- Upload the JSON file created above
- Convert the JSON to a PHP array
- Update the plugin settings with the new array. If your settings are stored in multiple options, you will extract the individual values from the array
Let’s go through the export process first.
Building a JSON file of your plugin’s settings is easiest if your settings are all stored in a single option in the database, as I’ve done with my example plugin (which can be downloaded below). For example, when I want to retrieve the options, I do this:
1 | $options = get_option( 'pwsix_settings' ); |
This gives me an array of my settings. Obviously it depends on the settings you have registered, but my example settings look like this:
1 2 3 4 5 6 | Array ( [text] => Some text for the plugin [label] => Some text for a label [enabled] => 1 ) |
The text and label options are simple text fields and the enabled option is a (checked) checkbox.
During the export process, we need to convert this array to JSON because it provides us a plain text version of the data that can be easily saved in a text (or .json) file. Note, we could also serialize the data using serialize() but I prefer JSON.
To convert the array to JSON, we can use the json_encode() function:
1 2 | $options = get_option( 'pwsix_settings' ); $json = json_encode( $options ); |
The result of the conversion looks like this:
{"text":"Some text for the plugin","label":"Some text for a label","enabled":"1"}
Once we have converted our array to JSON, we can tell the browser to download it by outputting some headers:
1 2 3 4 5 6 7 8 9 | $settings = get_option( 'pwsix_settings' ); nocache_headers(); header( 'Content-Type: application/json; charset=utf-8' ); header( 'Content-Disposition: attachment; filename=pwsix-settings-export-' . date( 'm-d-Y' ) . '.json' ); header( "Expires: 0" ); echo json_encode( $settings ); exit; |
These headers will tell the browser to download a file called pwsix-settings-export-{current date here}.json.
Once the JSON file has been generated, we can then upload it to another site in order to import our settings.
The import process is very similar to the export process. First we grab the file that has been uploaded:
1 2 3 4 5 | $import_file = $_FILES['import_file']['tmp_name']; if( empty( $import_file ) ) { wp_die( __( 'Please upload a file to import' ) ); } |
NOTE: there should always be validation checks performed on uploaded files before using them. You can see the checks I have written in the example plugin. I have left them out here because I’m simply showing you the overall process of exporting / importing settings.
Once we have the file, we can retrieve its contents and then decode the JSON:
1 2 | // Retrieve the settings from the file and convert the json object to an array. $settings = (array) json_decode( file_get_contents( $import_file ) ); |
json_decode() will, by default, create an object, but since we want an array, we can put (array) before it and let PHP work its magic, converting the object to an array.
As soon as we have decoded the JSON, we will have an array that looks identical to what we had before we converted it to JSON:
1 2 3 4 5 6 | Array ( [text] => Some text for the plugin [label] => Some text for a label [enabled] => 1 ) |
Since the array is identical to what we started with, we can now simply update out plugin’s setting with it:
1 | update_option( 'pwsix_settings', $settings ); |
Your plugin settings will now be successfully imported.
Obviously I have not covered every aspect of the build process for this kind of feature; I wanted to cover the core logic. For a complete example that shows the plugin settings page and the processing functions for import and export, take a look at the sample plugin below:
Is there a specific reason you decided to cast an array when decoding the JSON rather than using:
json_decode( file_get_contents( $import_file ), true );
Adding `true` output an array rather than an object. Just curious to see what your experience has been between the two options.
Ha, that would be because I never realized json_decode() accepted that second parameter 😀
Man, thanks a ton for this. Just a few seconds ago I was able to export and import all of Volatyl’s settings on my local install. It worked perfectly from the plugin with just a few changed values.
Now all I have to do is build it into my system and I’m good to go. THANK YOU!!! This is just what I needed.
That’s great to hear!
Pippin, thanks for the tutorial and example plugin. I’ve been wanting to add this feature to my plugins and just didn’t know the best way to go about it!
Now, I can.
Hi Pippin,
Thank you very much!!! for the code, yes it is extremely helpful to any theme or plugin developer,
I am working on a theme with a small set of option there, and I needed that for sure. you save my time bro!!!,
thank you again…. you are awesome 🙂
Excellent tutorial as always Pippin. I only wish I had found this a few days earlier before spending a good amount of time figuring it out.
Great work, and saved me a bunch of time figuring this out myself. Much appreciated.
One thing I suggest you add however, is some further data in the json file containing the name and version of the plugin it was exported from. That way checks can be added to the import function that they match. As it is, this code could import any json file and load a bunch of whatever as options that have nothing to do with the plugin. Or, more likely, an export file for the plugin with options that don’t correspond to the current version.
Excellent idea!
Hi, thanks for this helpful tutorial. I have image urls in settings and I want to import them on new site, not just settings but also the actual images from existing site to new server. Can you help me on this?
Hello.
I test your codes and it doesn’t work , can you help me ??
Hi
Is there a way to create /already developed, a simple plugin that will export / import any plugin? You would select which plugin you want to export data, and it would create the data file. Most plugins don’t offer option to export data, or ask you to pay the Pro version to be able to do it, having such a plugin that could export any installed plugin data would be awesome!