wp-cli/wp-cli — pull request #951 by itsananderson (2014-01-09 08:53:55+00:00)
Title: Add --recurse-objects flag for recursive search-replace into objects

As a result of #792, search-replace was modified to disable recursion into objects to replace values. While storing things like options in objects is admittedly not advisable, this still causes problems with some plugins/themes that store options as objects, because these options aren't updated with search-replace calls.

I'd like to propose a change that would add a --recurse-objects flag to search-replace. If this flag isn't included, functionality would remain the same, but if it's included in a call to search-replace, recursion into objects would be enabled, and code paths to detect cycles in arrays/objects would be enabled.

For cycle detection, the code is keeping an array of references to arrays/objects that have been visited and checking on each recursive step. This is relatively cheap to do, since it only stores and checks arrays and objects, and it only keeps track of them as references, so it's not holding on to multiple copies of the data.

Because cycle detection still does a search-replace into the object/array until it detects a cycle, data that has cycles can still have replacement operations done on it, so not only does this change protect against fatal errors, it allows admins to make replacements on all objects and arrays, even if they're cyclical.

**A note on tests**:

Because Search_Replace_Ccmmand::recursive_unserialize_replace is private, it's not easy to unit test. I looked at updating the functional tests, but that didn't seem to fit with the rest of the test, and to be honest, I'm not familiar with Behat.

I wrote a number of unit tests, which can be run by making `recursive_unserialize_replace` public a public method, and dropping these unit tests into the `tests` folder. If you want, I can add these to the branch for merging, but they don't really fit nicely with the rest of the test code, so I thought I'd start with them separated (but mention them in case you'd like to verify the change)
https://gist.github.com/itsananderson/8331193