Introduction

This guide is only for WordPress plugin developers wanting to integrate Prime Mover user adjustment API. This guide requires at least Prime Mover 1.5.2+ for both export and import end. If you are using an earlier version – you cannot use this API and you must upgrade to the latest version of Prime Mover.

Problem description

As you have learned already – Prime Mover is a plugin that can be used to migrate WordPress websites whether multisite sub-sites or single sites. When Prime Mover migrate sites – it also migrate it’s users. When users are migrated to a different/new installation – they are added by Prime Mover using WordPress functions like wp_insert_user for new users or wp_update_user for existing users . You can read how Prime Mover handles user migration here.

When user is added to the newly migrated site, a different user ID is created in the WordPress user database table. Even if the user is the same (e.g. same email address from the source site and the target site) – you must never assume that they have the same user ID!

This can create problems with WordPress plugins hard coding user IDs in their own WordPress custom database table. Since the user IDs might be different – plugin functionality is affected. For example – consider this custom database table wp_my_custom_test_table (added by a fictitious third party WordPress plugin) that is hard coding user IDs as user_id column:

Supposing the tables above is the data in the original/source site. So for example that means dummyfour@dummytest.com user hobby is “swimming“. WordPress users table is the standard user database table like wp_users.

When this site is migrated using Prime Mover to a multisite or it could be another single-site with different users or already existing users – these source site users might not exists and should be added to the new target site. Supposing this is the table after migration (before any user adjustment):

As you have observed after migration – the association between the user IDs and it’s hobbies are disconnected. For exampledummyfour@dummytest.com user ID is now 506 however no associated hobby is found in the custom database table. The tablewp_my_custom_test_table is not adjusted in this case. It still uses the source site user ID. This can create problems in the target site.

Solution: User Adjustment API

The problem above can be fixed permanently by integrating Prime Mover plugin user adjustment API in your third party WordPress plugin (that is hard coding user IDs). The API works as follows:

  • When a site is exported – Prime Mover detects which plugins uses the user adjustment API automatically. This detection requires your plugin to be active on that site to be exported and that you have correct API implementation (see example below).
  • When the site is restored/imported – Prime Mover let’s the third party plugin runs it’s code (that uses the API) to do it’s own user adjustment.
  • After the site is restored – user adjustment is done also.
  • As expected – the user data in the custom database table are connected/updated to use the latest user IDs after migration. This way – site functionality is not affected by the migration/user ID change.

API usage example – object oriented

If you are a third party WordPress plugin developer and using object oriented approach in coding. You can add the integration in very steps . Simply add the filter hook and it’s callback method. You then to configure your own parameter values. That’s it. Example (supposing you implemented the above custom table data wp_my_custom_test_table):

     add_filter('prime_mover_do_process_thirdparty_data', [$this, 'userAdjustment'], 2, 3);

    /**
     * User adjustment when migrating site with Prime Mover plugin
     * @param array $ret
     * @param number $blogid_to_import
     * @param number $start_time
     * @return array
     */
    public function userAdjustment($ret = [], $blogid_to_import = 0, $start_time = 0)
    {
        /**
         * START - CONFIGURATION
         */
        $plugin = 'yourplugin/yourplugin.php';
        $table = 'my_custom_test_table';
        $identifier = "sometestidentifier";
        
        $primary_index = 'key';
        $user_column = 'user_id';
        
        $table_description = 'custom data table';
        $handle_unique_constraint = '';

        /**
         * END -CONFIGURATION
         */
        
        /**
         * DEVELOPERS: DONT EDIT ANYTHING BELOW!
         */
        $validation_error = apply_filters('prime_mover_validate_thirdpartyuser_processing', $ret, $blogid_to_import, $plugin);
        if (is_array($validation_error)) {
            return $validation_error;
        }
        
        if (!empty($ret['3rdparty_current_function']) && __FUNCTION__ !== $ret['3rdparty_current_function']) {
            return $ret;
        }
        
        $ret['3rdparty_current_function'] = __FUNCTION__;        
        $leftoff_identifier = "3rdparty_{$identifier}_leftoff";        
        $column_strings = "{$primary_index}, {$user_column}";
        
        $update_variable = "3rdparty_{$identifier}_log_updated";        
        $progress_identifier = $table_description;
       
        $last_processor = apply_filters('prime_mover_is_thirdparty_lastprocessor', false, $this, __FUNCTION__, $ret, $blogid_to_import);        
        
        return apply_filters('prime_mover_process_userid_adjustment_db', $ret, $table, $blogid_to_import, $leftoff_identifier, $primary_index, $column_strings,
            $update_variable, $progress_identifier, $start_time, $last_processor, $handle_unique_constraint);
    }
    

Simply provide the values inside the code block marked as START - CONFIGURATION and END -CONFIGURATION

These are the parameters needed inside the callback method with some guidance on how to set this up correctly:

  • $plugin = this is your plugin e.g. akismet/akismet.php
  • $table = this is the affected custom database table. Do not include the table prefix!. In the above example, the affected table is wp_my_custom_test_table. Therefore defined only my_custom_test_table (without the prefix “wp_” or any table prefix).
  • $identifier = this should be one word – alphabetic strings only. (No other characters, numbers, spaces, hypens, etc). This is used by Prime Mover to uniquely identify your plugin AP implementation.
  • $primary_index = This is the primary index column used by your custom database table. In the above example for database tablewp_my_custom_test_table, the primary index column is key.
  • $user_column = This is the affected user ID column. This is the column that needs to be adjusted. In the above example, this column is user_id.
  • $table_description = a very short description of your table (should not exceed three words). This will be used internally by Prime Mover plugin to give status of the database update to its user.
  • $handle_unique_constraint = if $user_column is a unique column, then add it here as well. e.g. provide: $handle_unique_constraint = 'user_id'. If your $user_column is not unique (as in most cases) – then you should only provide empty value , e.g. $handle_unique_constraint = ''

Limitation on API object oriented implementation

  • The hook and the callback method should not be using anonymous functions.
  • It should not be inside static class. Use $this.
  • Provide only the table specific parameters as indicated in the API. This does matter whether you have thousands or millions of data rows. Prime Mover will handle everything automatically.
  • Plugin inside /wp-content/mu-plugins is not supported.
  • If there are more than one user ID columns, it requires a separate hook-callback. Each callback should adjust one user ID column only.
  • Your custom database table should have primary keys. It does not support tables that is not using primary keys.
  • The hook priority does not matter. But make it sensible e.g. around 10 – don’t use very high hook priority or negative hook priority.
  • This API implementation should only used for WordPress plugins – adding this to theme functions.php is not supported.
  • For this to fully work – the plugin that is implementing this API should be activated at the source site (before exporting) and should be also be used at the target site. Prime Mover handles the user adjustment automatically to plugins that hooking to this API.

Procedural code method API usage example

If you don’t use object oriented inside your plugin code – you can also implement the API as follows:

add_filter('prime_mover_do_process_thirdparty_data', 'primeMoverCustomUserAdjustment', 77, 3);
/**
 * User adjustment when migrating site with Prime Mover plugin
 * @param array $ret
 * @param number $blogid_to_import
 * @param number $start_time
 * @return array
 */
function primeMoverCustomUserAdjustment($ret = [], $blogid_to_import = 0, $start_time = 0)
{
    /**
     * START -CONFIGURATION
     */  
     $plugin = 'yourplugin/yourplugin.php';
     $table = 'my_custom_test_table';
     $identifier = "sometestidentifier";
        
     $primary_index = 'key';
     $$user_column = 'user_id';
        
     $table_description = 'custom data table';
     $handle_unique_constraint = '';
    /**
     * END -CONFIGURATION
     */
    
    /**
     * DEVELOPERS: DONT EDIT ANYTHING BELOW!
     */
    $validation_error = apply_filters('prime_mover_validate_thirdpartyuser_processing', $ret, $blogid_to_import, $plugin);
    if (is_array($validation_error)) {
        return $validation_error;
    }
    
    if (!empty($ret['3rdparty_current_function']) && __FUNCTION__ !== $ret['3rdparty_current_function']) {
        return $ret;
    }
    
    $ret['3rdparty_current_function'] = __FUNCTION__;
    $leftoff_identifier = "3rdparty_{$identifier}_leftoff";
    $column_strings = "{$primary_index}, {$user_column}";
    
    $update_variable = "3rdparty_{$identifier}_log_updated";
    $progress_identifier = $table_description;
    $last_processor = apply_filters('prime_mover_is_thirdparty_lastprocessor', false, '', __FUNCTION__, $ret, $blogid_to_import);
    
    return apply_filters('prime_mover_process_userid_adjustment_db', $ret, $table, $blogid_to_import, $leftoff_identifier, $primary_index, $column_strings,
        $update_variable, $progress_identifier, $start_time, $last_processor, $handle_unique_constraint);
}

Testing – how to check if it works?

Going back to the above problem description – when the plugin implements the API correctly. The user ID in the affected custom database table will also be automatically adjusted by Prime Mover. So the above example will produce this output after migration at the target site (supposing user adjustment is implemented):

As you can see – with API implemented correctly – the user ID is now correctly adjusted in the affected custom database table. To test – simply check the user ID in your WordPress site after migration and check your custom database table to see if it’s adjusted accordingly. You can use the data in the source site to interpolate expected results.

Frequently asked questions

  • What happens if there is no migration – does this code adds performance overhead? No because this code runs only during migration where all plugins are disabled except plugins implementing the API.
  • Does user adjustment needs to run all the time during migration? No, if user equivalence are the same (e.g. you have mirror site for export and import, with same user IDs correspondence.) – then the user adjustment is not needed. This is decided by Prime Mover automatically.
  • Do all WordPress plugins needs to do this? No, this is only for plugins that having custom database table implementation that hard codes user IDs.
  • Why can’t Prime Mover permanently fixes this for all plugins? No, it’s not possible. It is because each WordPress custom database table used by each plugins have it’s own unique definition. This means there is no general solution that works for all plugins. It would be simpler for the third party plugin to hook to Prime Mover and inform it to do it’s own user adjustment when user is migrating site.
  • Does other migration plugins have this API also? No this API is only for Prime Mover plugin.
  • The API integration is very simple – I only need to provide the user ID column, table name, and a few parameters. Where is the rest of the detailed user ID detailed data? – this is designed to be as simple to integrate as possible. It’s almost copy and paste of the above code examples! The rest of the detailed calculations and user IDs complete list – you don’t need need to worry about it as Prime Mover handles all the hard work in the background silently 🙂

Case example: Affected plugin and it’s user adjustment API implementation

In this example – the affected WordPress plugin named as “Third party compat plugin” relies on it’s own custom database tables. These tables have user ID columns that when migrated to another site – these user IDs might change and no longer applies. So in this case – it needs user ID adjustment after import to re-aligned the user ID to correct users.

The user ID adjustment is implemented as another plugin for convenience. The name of this user ID adjustment is “Third party user adjustment API plugin“.

Overall the user ID adjustment implementation steps are as follows:

  • In the source site (where package needs to exported) – re-examine the affected plugin in the database that has user ID columns on it’s own custom database table. Jot down the table name (without the dB prefix- see above example for details), name of the user ID column (e.g. user_id) , the primary index column name of the table (usually it’s ID – but check with it) and the plugin path (e.g. yourplugin/yourplugin.php). You need all these information to write down the user ID adjustment patch.
  • Write down the user ID adjustment patch as another plugin (you can download the plugin example link below).
  • [optional] If there are more than one affected database tables – write another patch for it and put it on the same user adjustment API plugin. Make sure to assign unique identifiers for each adjustment for proper identification (read above example for details on identifiers).
  • Once all is done – review the patch and make sure it contains correct user ID column names, table names, etc.
  • Activate the user ID adjustment plugin in your site. If you have a multisite – activate it on the same subsite where the affected plugin is activated.
  • Once this is done – review your site and make sure it still works great (just a quick look).
  • Finally activate Prime Mover plugin (network activate if multisite).
  • Visit again your site /subsite admin dashboard (where the affected plugin is activated) and make sure that both the affected plugins and it’s corresponding user adjustment API plugin are activated.
  • Once that is done – create an export with Prime Mover.
  • Once export is done – reset your target site database (make sure the database is cleaned up for better testing just like fresh WordPress install if possible).
  • Restore the package to your target site database.
  • Review that the user adjustment is properly implemented and corrected.
  • Once confirmed that the user adjustment is correct – you can send us your working user ID adjustment plugin patch so we can permanently add this patch inside Prime Mover (which would be fixed for all future affected users).

That’s it! You can download the affected plugin and it’s own user adjustment API plugin below so you can study them in details:

Download plugin – Third party user adjustment API plugin

Download plugin – Third party compat plugin

Still have questions?

Please send us your question here. Thank you.

Was this article helpful?
YesNo