Actions and Filters

Developers can tweak WP STAGING using its available actions and filters. This article documents the current hooks and shows example usage to customize the cloning and pushing process to your needs..

For using the hooks and filters, we recommend installing our separate plugin, named  WP STAGING Hooks, or using the hooks and filters on this page in a mu-plugin.
Otherwise, not all actions might work as expected.

WP Staging Hooks Plugin

You can download the WP STAGING hooks plugin that contains many of the filters mentioned in this article for easy usage on your website.
Note: Not all filters mentioned in this article are included in the github repository.

If there is a filter mentioned on this page that is not available in the WP STAGING hooks plugin, you can copy the specific code on this page to either a new mu-plugin or an existing one like the WP STAGING mu-plugin that you can find in wp-content/plugins/wp-staging-optimizer.php

Copy the complete code into the head of the mu-plugin and adjust it to your needs. If you need help with it, just let us know.

Contents

Allow Unlimited Memory Usage

WP STAGING limits the maximum memory consumption to 256M, which is usually sufficient for its cloning and backup process. During this process, all other plugins are disabled, but this will not affect other pages on the website.

A memory limit of 256M is usually sufficient to run WP STAGING successfully. We do not recommend a higher WP_MEMORY_LIMIT or PHP max memory limit above 512M, as going higher may indicate a problem with one of the plugins or many active plugins. It is not advisable to go beyond these limits because the memory limit is related to each PHP process. If a high allowed memory consumption is set for every WordPress request, the available memory on the machine can quickly become filled up, making the website unavailable.

However, in cases where it is necessary to exceed the 256M limit, it is possible to disable the WP STAGING memory limit. Please note that this is not recommended unless there is a valid reason to do so, and the server has sufficient memory available.

To disable the memory limit, use the provided filter to allow unlimited memory consumption for WP STAGING. The only limit, in this case, is the PHP max memory limit.

PHP
add_filter('wpstg.resources.ignoreMemoryLimit', function() {
  return true;
});

Change WP Staging Logo on Login Form (Pro Version)

You can use the code below to change the logo of the staging site’s login formular:

PHP
add_filter('wpstg_login_form_logo', function(){
  return 'https://example.com/path/to/custom/image.png';
});

Increase WP STAGING Request Time and PHP’s Maximum Execution Time

Usually, the WP STAGING backup and restore works even on minor web hosts. If you have a huge database or website with millions of rows, the PHP default execution time limit of 30 seconds may be too low. To make the backup creation/restore work, set the PHP value  max_execution_time= 120 in your php.ini.

Also, increase the apache value Timeout 120 or set the Nginx directive fastcgi_read_timeout 120;

After doing that, add the filter below into a mu-plugin like mu-plugin/wp-staging-optimizer.php.

PHP
​add_filter('wpstg.resources.executionTimeLimit', function(){
return 100;
});

Ensure that the input value is lower than the actual PHP maximum allowed execution time. This is necessary so that WP STAGING request time never exceeds the PHP execution time.

Change Staging Site Title

PHP
function wpstg_get_title(){
   return 'DEV';
}
add_filter('wpstg_staging_site_title', 'wpstg_get_title');

Change Path to Cache Folder

To change the folder that is used to store temporary backup files to the global PHP temp folder or to somewhere else, you can use the code below:

PHP
​add_filter('wpstg.directory.cacheDirectory', function(){
        return trailingslashit(sys_get_temp_dir()) . 'wpstagingcache';
});

Exclude Tables From the Search & Replace operation

Use this if the search & replace process eats up much of your available memory and the cloning or pushing process fails with a memory-exhausted error.  You can also use this to improve the cloning and pushing process speed.

Exclude tables that do not need any search & replacement of any links! These can be tables that contain visitor stats, IP addresses, or something similar. After excluding those tables, you can increase the DB Search & Replace limit in WP STAGING settings to a higher value to get better performance.

PHP
function wpstg_searchreplace_excl_tables($default){
$tables = array('_posts', '_postmeta'); 
return array_merge($default, $tables);
}
add_filter('wpstg_searchreplace_excl_tables','wpstg_searchreplace_excl_tables');

Cloning & Staging Filters

Run an Action on the Staging Site After Cloning

PHP
add_action( 'wpstg.clone_first_run', array($this, 'wpstg_execute_after_cloning' ), 10);

function wpstg_execute_after_cloning() {
   // add your code
}

Activate or Deactivate Specific Plugins on Staging Site After Cloning

To activate or deactivate some plugins on the staging site after cloning use the filter wpstg.cloning.update_active_plugins like this:

PHP
php
function wpstg_cloning_update_active_plugins($currentActivePlugins) {
// snippet to deactivate
$pluginsToDeactivate = array('plugin1-basename', 'plugin2-basename');
foreach ($pluginsToDeactivate as $pluginToDeactivate) {
  $key = array_search($pluginToDeactivate, $currentActivePlugins, true);
  if (false !== $key) {
    unset($currentActivePlugins[$key]);
  }
}

// snippet to activate
$pluginsToEnable      = array('plugin3-basename');
$currentActivePlugins = array_merge($currentActivePlugins, $pluginsToEnable);

return $currentActivePlugins;

}
add_filter('wpstg.cloning.update_active_plugins','wpstg_cloning_update_active_plugins');

Exclude Rows From Search & Replace in wp_options

PHP
function wpstg_clone_searchreplace_excl_rows($default){
$rows = array('siteurl', 'home'); 
return array_merge($default, $rows);
}
add_filter('wpstg_clone_searchreplace_excl_rows','wpstg_clone_searchreplace_excl_rows');

Exclude Rows From Cloning

This example will exclude rows from the wp_options table depending on the option name or exclude posts from the wp_posts table based on the post_title and post_status and their post metadata.

These operators are available:

['=', '>', '>=', '<', '<=', '<>', '!=', 'LIKE', 'NOT LIKE']

PHP
function queryCloningRows($filters) {
	$filters = [
// Clone only options where option_name is not 'wpstg_is_staging_site'
		'wp_options' => [
			'option_name' => [
				'operator' => '<>',
				'value' => 'wpstg_is_staging_site'
			]
		],
// Clone only posts where post_title LIKE 'Hello%' AND post_status = 'publish'
		'wp_posts' => [
			'post_title' => [
				'operator' => 'LIKE',
				'value' => 'Hello%'
			],
			'post_status' => 'publish'
		],
// will filter postmeta depending upon filtered data in wp_posts, see above wp_posts filter
                'wp_postmeta' => [
			'join' => [
				'table' => 'wp_posts',
				'primaryKey' => 'ID',
				'foreignKey' => 'post_id',
			]
		]
	];
	
	return $filters;
}

add_filter('wpstg.cloning.database.queryRows', 'queryCloningRows');

Exclude Custom Post Type From Cloning

This example will exclude posts under the custom post type “coupon” along with its postmeta data as well:

These operators are available:

['=', '>', '>=', '<', '<=', '<>', '!=', 'LIKE', 'NOT LIKE']

PHP
function queryCloningRows($filters) {
	$myFilters = [
// Clone only posts which do not belong to post_type coupon
		'wp_posts' => [
			'post_type' => [
				'operator' => '<>',
				'value' => 'coupon'
			]
		],
// will filter postmeta depending upon filtered data in wp_posts, see above wp_posts filter
                'wp_postmeta' => [
			'join' => [
				'table' => 'wp_posts',
				'primaryKey' => 'ID',
				'foreignKey' => 'post_id',
			]
		]
	];
	
// will filter postmeta depending upon filtered data in wp_posts, see above wp_posts filter
                'wp_postmeta' => [
			'join' => [
				'table' => 'wp_posts',
				'primaryKey' => 'ID',
				'foreignKey' => 'post_id',
			]
		]
	];

	return array_merge($filters, $myFilters);
}

add_filter('wpstg.cloning.database.queryRows', 'queryCloningRows');

Exclude Strings From Search & Replace

PHP
function wpstg_clone_searchreplace_excl(){
return array('blog.localhost.com','blog1.localhost.com');
}
add_filter('wpstg_clone_searchreplace_excl','wpstg_clone_searchreplace_excl');

Change Search & Replace Parameters

PHP
function wpstg_cloning_custom_params($args){
      // Default values - Can be changed
         $args['search_for'] = array_merge(
         $args['search_for'],
         array('SEARCHSTRING', 'SEARCHSTRING')
         );
         $args['replace_with'] = array_merge(
         $args['replace_with'],
         array('REPLACESTRING','REPLACESTRING2')
       );
      $args['replace_guids'] = 'off'; 
      $args['dry_run'] = 'off'; 
      $args['case_insensitive'] = false;
      $args['replace_guids'] = 'off';
      $args['replace_mails'] = 'off';
      $args['skip_transients'] = 'on';
      return $args;
}
add_filter('wpstg_clone_searchreplace_params', 'wpstg_cloning_custom_params');

Exclude Files

PHP
/**
* Cloning: Exclude files from cloning
* Example: You can use a wildcard pattern like *.log to exclude all log files
*/
function wpstg_clone_excluded_file_names($default)
{
    $files = array('custom-file', '*LOG-*', '*.logs');
    return array_merge($default, $files);
}
add_filter('wpstg_clone_excluded_files', 'wpstg_clone_excluded_file_names');

Exclude files from cloning using full path

By default WP STAGING excludes these files from copying whenever it creates a staging site:

  • .htaccess
  • Absolute/path/to/WordPress/directory/wp-content/db.php
  • Absolute/path/to/WordPress/directory/wp-content/object-cache.php
  • Absolute/path/to/WordPress/directory/wp-content/advanced-cache.php

You can change this behavior and modify this list of excluded files by using the filter below:

PHP
/**
* Exclude files from cloning using full path 
*/
function wpstg_clone_excluded_files_full_path($default)
{
    $files = ['full/path/custom-file1', 'full/path/custom-file2']; 
    return array_merge($default, $files);
}
add_filter('wpstg.clone.excluded_files_full_path','wpstg_clone_excluded_files_full_path');

Exclude Folders

PHP
/**
* Excluded folders relative to the wp-content folder 
*/
function wpstg_exclude_folders_custom($args){
$folders = array('plugins/wordpress-seo', 'custom-folder');
     return array_merge($args, $folders);
}
add_filter('wpstg_clone_excl_folders', 'wpstg_exclude_folders_custom');

Multisite: Exclude folders (plugins) from cloning in a multisite

If you use a multiiste network use the filter `wpstg_clone_mu_excl_folders` to exclude folders relative to the wp-content folder. This is helpful if you want to exclude a plugin.

PHP
**
* Excluded folders relative to the wp-content folder
*/
function wpstg_exclude_folders_custom($args){
$folders = array('plugins/wordpress-seo', 'themes/custom-folder');
     return array_merge($args, $folders);
}
add_filter('wpstg_clone_mu_excl_folders', 'wpstg_exclude_folders_custom');

Prevent search & replace of the table prefix in an option in table wp_options

As default WP STAGING clones all tables and replaces values that begin with the table prefix of the new database. You can exclude options from this replacement operation so they will not be modified during cloning:

PHP
function wpstg_excl_option_name_custom($args){
$cols = array('wp_mail_smtp', 'wp_mail_smtp_version');
     return array_merge($args, $cols);
}
add_filter('wpstg_data_excl_rows', 'wpstg_excl_option_name_custom');

Clone network multisites and change the destination hostname

WP STAGING has support for custom domain based multisites. Network sites will be automatically created in the specified subdomain of the main site that you.

Example:

There is a network site with main site example.com and a network subsite example.org and another one example.net:

If you clone the whole network to staging.example.com the network sites will be cloned to:

  • staging.example.org
  • staging.example.net

You can adjust each site by using the filter below. It’s a generic filter that can be used for subdomain based, subdirectory based or even domain based subsites.

PHP
// Convert staging site with ID 2 to dev.example.com
add_filter('wpstg.cloning.multisite.subsite_info', function ($subsiteInfo, $blogId, $stagingSiteURL, $addWWWPrefix) {

if ($blogId === 2) {
    $subsiteInfo['domain'] = 'dev.example.com';
    $subsiteInfo['path']   = '/';
    $subsiteInfo['url']    = 'https://dev.example.com';
}

return $subsiteInfo;
}, 10, 4);

Push Filters

Activate or Deactivate Specific Plugins on Production Site After Pushing a Staging Site

To activate or deactivate some plugins on the live site after pushing a staging site use the filter wpstg.pushing.update_active_plugins like this:

PHP
php
function wpstg_pushing_update_active_plugins($currentActivePlugins)
{
    // snippet to deactivate
    $pluginsToDeactivate = array('plugin1-basename', 'plugin2-basename');
    foreach ($pluginsToDeactivate as $pluginToDeactivate) {
        $key = array_search($pluginToDeactivate, $currentActivePlugins, true);
        if (false !== $key) {
            unset($currentActivePlugins[$key]);
        }
    }

    // snippet to activate
    $pluginsToEnable      = array('plugin3-basename');
    $currentActivePlugins = array_merge($currentActivePlugins, $pluginsToEnable);

    return $currentActivePlugins;
}
add_filter('wpstg.pushing.update_active_plugins','wpstg_pushing_update_active_plugins');

Change Search & Replace parameters

PHP
function wpstg_push_custom_params($args){
      // Default values - Can be changed
         $args['search_for'] = array_merge(
         $args['search_for'],
         array('SEARCHSTRING', 'SEARCHSTRING2')
         );
         $args['replace_with'] = array_merge(
         $args['replace_with'],
         array('REPLACESTRING','REPLACESTRING2')
       );
      $args['replace_guids'] = 'off'; 
      $args['dry_run'] = 'off'; 
      $args['case_insensitive'] = false;
      $args['replace_guids'] = 'off';
      $args['replace_mails'] = 'off';
      $args['skip_transients'] = 'on';
      return $args;
}
add_filter('wpstg_push_searchreplace_params', 'wpstg_push_custom_params');

Exclude tables from pushing

PHP
function wpstg_push_excluded_tables($tables){
$customTables = array('options', 'posts'); 
return array_merge($tables, $customTables);
}
add_filter('wpstg_push_excluded_tables','wpstg_push_excluded_tables');

This excludes the tables wp_posts and wp_options from being pushed to the live site.

Exclude Rows From Pushing. Copy Only Specific Rows

This example will exclude certain rows from the wp_options table depending on the option name or exclude posts from the wp_posts table based on the post_title and post_status along with their postmeta data as well.

These operators are available:

['=', '>', '>=', '<', '<=', '<>', '!=', 'LIKE', 'NOT LIKE']

Take care: The table prefix needs to be wpstg0_, wpstg1_, wpstg3, etc. depending on the actual staging sites table prefix, so You have to replace wpstg[int]_.

PHP
function queryPushingRows($filters) {
	$filters = [
		// will only push options where option_name is not 'wpstg_is_staging_site'
		'wp_options' => [
			'option_name' => [
				'operator' => '<>',
				'value' => 'wpstg_is_staging_site'
			]
		],
		// will only push posts where post_title LIKE 'Hello%' AND post_status = 'publish'
		'wp_posts' => [
			'post_title' => [
				'operator' => 'LIKE',
				'value' => 'Hello%'
			],
			'post_status' => 'publish'
		],
                // will filter postmeta depending upon filtered data in wp_posts, see above wp_posts filter
                'wp_postmeta' => [
			'join' => [
				'table' => 'wpstg[int]_posts',
				'primaryKey' => 'ID',
				'foreignKey' => 'post_id',
			]
		]
	];
	
	return $filters;
}

add_filter('wpstg.pushing.database.queryRows', 'queryPushingRows');

Note: Excluding these post types means they will not be available any longer and not be included anymore in the live site after copying the staging site to live.

Exclude Certain Post Type From Pushing

This example will exclude posts with the custom post type “coupon” along with its postmeta data as well:

These operators are available:

['=', '>', '>=', '<', '<=', '<>', '!=', 'LIKE', 'NOT LIKE']

Take care: The table prefix needs to be wpstg0_, wpstg1_, wpstg3, etc. depending on the actual staging sites table prefix, so You have to replace wpstg[int]_.

PHP
function queryPushingRows($filters) {
	$myFilters = [
		// Push only posts where post_type is not 'coupon'
		'wp_posts' => [
			'post_type' => [
				'operator' => '<>',
				'value' => 'coupon'
			]
		],
                // will push postmeta depending upon filtered data in wp_posts, see above wp_posts filter
                'wp_postmeta' => [
			'join' => [
				'table' => 'wpstg[int]_posts',
				'primaryKey' => 'ID',
				'foreignKey' => 'post_id',
			]
		]
	];

	return array_merge($filters, $myFilters);
}

add_filter('wpstg.pushing.database.queryRows', 'queryPushingRows');

Exclude folders from pushing

By default WP STAGING PRO does not iterate through, nor does it push any of these folders to the production website:

  • cache
  • wps-hide-login
  • node_modules
  • nbproject
  • wp-staging

You can add custom folders to this list by using the filter below:

PHP
function wpstg_push_directories_excl($default){
$dirs = array('custom-folder', 'custom-folder2'); 
return array_merge($default, $dirs);
}
add_filter('wpstg_push_excl_folders_custom','wpstg_push_directories_excl');

Exclude files from pushing

As default WP STAGING PRO does not push any of these files to the production website:

  • .htaccess
  • .DS_Store
  • .git
  • .svn
  • .tmp
  • desktop.ini
  • .gitignore
  • .log
  • wp-staging-optimizer.php

You can add custom files to this list by using the filter below:

PHP
function wpstg_push_excluded_files($default){
$files = array('custom-file', 'custom-file2'); 
return array_merge($default, $files);
}
add_filter('wpstg_push_excluded_files','wpstg_push_excluded_files');

Preserve data in wp_options and exclude it from pushing

Preserving data means you can push the staging site to the production site and exclude specific data from being overwritten during the push process.

The example below preserves the values for the WordPress options ‘siteurl’ and ‘home’ in the wp_options table of the live site.

Any number of additional options may be added.

PHP
function wpstg_push_options_excl($options){
       $newOptions = array('siteurl', 'home');
       return array_merge($options, $newOptions);
}
add_filter('wpstg_preserved_options','wpstg_push_options_excl');

Run an action after pushing the production site.

You can use this hook to call a method on the production site after pushing a staging site to live.

PHP
function pushingComplete()
{
// do something
}
add_action( 'wpstg_pushing_complete', 'pushingComplete' );

Backup Filters

Restore a multisite backup on another multisite (Migration)

If you created a backup from a multisite network and you want to restore the backup on another existing multisite, for example, to copy the multisite to another server, there are a few things to consider, depending on the type of multisite you operate. Please read this article that explains how to do that in detail and how to use a specific filter for that operation.

Exclude a file extension from backup

Allow users to exclude specific file extensions from being backup exported.

PHP
function wpstg_backup_files_ignore_extensions($default_excluded){
return array_merge($default_excluded, ['zip', 'gz']);
}
add_filter( 'wpstg.export.files.ignore.file_extension', 'wpstg_export_files_ignore_extensions');

Exclude files bigger than the given size from backup

Allow users to exclude files bigger than a given size from being backup exported.

PHP
function wpstg_backup_files_ignore_files_bigger_than($default){
return 10 * MB_IN_BYTES;
}

add_filter( 'wpstg.export.files.ignore.file_bigger_than', 'wpstg_backup_files_ignore_files_bigger_than');

Exclude files with particular extensions larger than the given file size from backup

Allow users to exclude files with extensions larger than the given size from being exported.

PHP
function wpstg_backup_files_ignore_files_w_extension_bigger_than($default){
$ignoreFiles = [
    'gz' => 10 * MB_IN_BYTES, 
    'tar' => 20 * MB_IN_BYTES
];
return array_merge($default, $ignoreFiles);
}

add_filter( 'wpstg.export.files.ignore.file_extension_bigger_than', 'wpstg_backup_files_ignore_files_w_extension_bigger_than');

Exclude directories from being included in a backup

PHP
function wpstg_backup_exclude_directories($excludedDirectories){
        $customExcludedDirectories = [
            'var/www/example.com/htdocs/wp-content/cache'
        ];
        return array_merge($excludedDirectories, $customExcludedDirectories);
    }

add_filter( 'wpstg.backup.exclude.directories', 'wpstg_backup_exclude_directories');

Exclude files from the wp-content folder from being restored

This filter excludes other files not contained in plugins, uploads, or themes from the backup restore.
Note: Existing files in the wp-content folder will still be deleted before running the restore process.

PHP
    /**
     * Backup: Exclude files from being restored
     */
    function wpstg_backup_restore_exclude_other_files($excludedFiles){
        $customExcludedFiles = [
            'wp-content/db.php',
            'wp-content/object-cache.php',
        ];
        return array_merge($excludedFiles, $customExcludedFiles);
    }
add_filter( 'wpstg.backup.restore.exclude.other.files', 'wpstg_backup_restore_exclude_files');

Restore Backup and Keep Existing Media Files, Plugins, or Themes

You can use the filters below to keep existing files:

PHP
// Keep all plugins
add_filter('wpstg.backup.restore.keepExistingPlugins', function(){return true;});

// Keep all mu-plugins
add_filter('wpstg.backup.restore.keepExistingMuPlugins', function(){return true;});

// Keep all themes
add_filter('wpstg.backup.restore.keepExistingThemes', function(){return true;});

// Keep all media files in wp-content/uploads folder.
add_filter('wpstg.backup.restore.keepExistingMedia', function(){return true;});

// Keep all other files in wp-content folder.
add_filter('wpstg.backup.restore.keepExistingOtherFiles', function(){return true;});

Change Temporary Backup Restore Database Table Prefix

Using a custom temporary database prefix during the backup-restore process is possible.

Usage:

PHP
add_filter('wpstg.restore.tmp_database_prefix', function ($defaultTmpPrefix) {
	return 'wpstgt_';
});

This example will replace {WPSTG_TMP_PREFIX} to wpstgt_ instead of using the default tmp prefix wpstgtmp_. This will reduce the chances of restoring errors if the table name, including the temporary prefix, exceeds 64 characters, as this is the MySQL character limit for identifiers in the database.

From the above example, if there is already a table with the wpstgt_ prefix in the current table during the restore process, it will revert back to using the default tmp prefix wpstgtmp_

Activate MultiPart Backups

WP Staging supports the creation of multipart backups that you can use to limit the size of each backup file. This feature can create multiple backup files for plugins, themes, media files, and the database. This is useful if you have a very big site and if it’s not possible to create backup files that have multiple gigabytes of data.

Use the filter below to activate this feature and to specify the maximum backup file size:

PHP
add_filter('wpstg.backup.isMultipartBackup', function() {
    return true;
});

// 256 MB 
add_filter('wpstg.backup.maxMultipartBackupSize', function() {
    return 256 * 1024 * 1024;
});

Increase Google Drive Backup Upload Chunks

This should help reducing requests to Google Drive which might help in case your server’s IP got blocked by Google. Wait 6 hours before you retry uploading the backup to Google. This is the time your IP address will be blocked by Google.

PHP
add_filter('wpstg.remoteStorages.chunkSize', function () {
    return 10 * 1024 * 1024; // 10 MB chunk size, try increasing the chunk size in multiple of 5 MB if this still fails.
}); 

Increase Google Drive Delay Between Requests

Use this filter to increase the delay between requests made from your server to Google Drive during the backup process. This should help in case your IP was blocked by Google. Wait 6 hours before you retry uploading the backup to Google. This is the time your IP address will be blocked by Google.

PHP
add_filter('wpstg.remoteStorages.delayBetweenRequests', function() {
    return 500; // 500ms, if this still fails, try increasing delay by multiple of 250ms.
});

Force Uploading to FTP Remote Storage via FTP extension

As default WP STAGING uploads backup files via the curl extension to FTP but you can switch to curl by using this filter:

PHP
add_filter('wpstg.ftpclient.forceUseFtpExtension', '__return_true');

Updated on October 27, 2023