wp-cli / search-replace-command

Searches/replaces strings in the database.
MIT License
57 stars 45 forks source link

Search-replace does not replace keys in serialized values #137

Open pkarjala opened 4 years ago

pkarjala commented 4 years ago

Bug Report

Describe the current, buggy behavior

When running a search-replace on the database and explicitly declaring --recurse-objects, the command does not change array keys in serialized strings, only array values. As such, keys get looked over and do not get correctly replaced by this command.

Note that this may also occur even if --recurse-objects is not explicitly declared, as it appears that this value is true even if not declared as per https://developer.wordpress.org/cli/commands/search-replace/.

Describe how other contributors can replicate this bug

Describe what you would expect as the correct outcome

When running the above described wp search-replace, it should also replace array keys in serialized string values.

Let us know what environment you are running this on

vagrant@ubuntu-bionic:/var/www/html$ wp --info
OS: Linux 4.15.0-91-generic #92-Ubuntu SMP Fri Feb 28 11:09:48 UTC 2020 x86_64
Shell:  /bin/bash
PHP binary: /usr/bin/php7.2
PHP version:    7.2.24-0ubuntu0.18.04.3
php.ini used:   /etc/php/7.2/cli/php.ini
WP-CLI root dir:    phar://wp-cli.phar/vendor/wp-cli/wp-cli
WP-CLI vendor dir:  phar://wp-cli.phar/vendor
WP_CLI phar path:   /var/www/html
WP-CLI packages dir:
WP-CLI global config:   /home/vagrant/.wp-cli/config.yml
WP-CLI project config:
WP-CLI version: 2.4.0

Provide a possible solution

The applicable section of the code appears to be https://github.com/wp-cli/search-replace-command/blob/master/src/WP_CLI/SearchReplacer.php#L91-L93

It would be necessary to alter this to also replace keys after the data had been searched and replaced.

Provide additional context/Screenshots

Replacing array keys may have unintended consequences, especially if the key exists elsewhere in the database in a place that the person running this command may be unaware of. Perhaps adding an option such as --replace-keys that will ONLY replace array keys in a search-replace?

vanushwashere commented 3 years ago

Can confirm, I store an array of URLs and configuration for them in wp_option table like

update_option(
'my_plugin_configuration'
array( 
     'https://example.com' => 'conf1,conf3, conf5, conf7',
     'https://example.com/page1' => 'conf1',
     'https://example.com/category1/page4' => ''
)

and running wp search-replace https://example.com https://new-example.com --all-tables to migrate from one domain to another doesn't work for this row

devkinetic commented 3 years ago

Possibly related to #45

LjupcheVasilev commented 2 years ago

Hi, any update on this one?

I'm experiencing the same issue. I'm using wp search-replace mainly to replace the URL and Yoast stores postmeta with the URL as a key. Example:

array( 
     'https://example.com/wp-content/uploads/2022/02/01/img.jpg' => 52,
)

which is stored serialized as such:

a:1:{s:57:"https://example.com/wp-content/uploads/2022/02/01/img.jpg";i:52;}
devkinetic commented 1 year ago

@LjupcheVasilev No update, but you can use a regex like I did in #45 to handle the serialized strings.

danielbachhuber commented 1 year ago

I think it was intentional to ignore keys originally. We could add a --recurse-objects-include-keys flag to allow the user to opt-in to updating keys, though.

Feel free to submit a pull request, if you'd like. Here is some guidance on our pull request best practices, if it's helpful. You can also stop by the #cli channel on WordPress.org Slack if you'd like to chat further.