Skip to content

Commit df1092f

Browse files
authored
Merge pull request #76 from wp-cli/68-handle-incomplete-class-serialization
Handle incomplete class (un)serialization gracefully
2 parents b45eeb4 + 17c0a88 commit df1092f

File tree

2 files changed

+47
-8
lines changed

2 files changed

+47
-8
lines changed

features/search-replace.feature

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1032,3 +1032,25 @@ Feature: Do global search/replace
10321032
"""
10331033
Success: 1 replacement to be made.
10341034
"""
1035+
1036+
# Regression test for https://github.com/wp-cli/search-replace-command/issues/68
1037+
Scenario: Incomplete classes are handled gracefully during (un)serialization
1038+
1039+
Given a WP install
1040+
And I run `wp option add cereal_isation 'a:1:{i:0;O:10:"CornFlakes":0:{}}'`
1041+
1042+
When I try `wp search-replace CornFlakes Smacks`
1043+
Then STDERR should contain:
1044+
"""
1045+
Warning: Skipping an uninitialized class "CornFlakes", replacements might not be complete.
1046+
"""
1047+
And STDOUT should contain:
1048+
"""
1049+
Success: Made 0 replacements.
1050+
"""
1051+
1052+
When I run `wp option get cereal_isation`
1053+
Then STDOUT should contain:
1054+
"""
1055+
a:1:{i:0;O:10:"CornFlakes":0:{}}
1056+
"""

src/WP_CLI/SearchReplacer.php

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
namespace WP_CLI;
44

5+
use ArrayObject;
56
use Exception;
67

78
class SearchReplacer {
@@ -89,9 +90,19 @@ private function _run( $data, $serialised, $recursion_level = 0, $visited_data =
8990
}
9091
}
9192

92-
elseif ( $this->recurse_objects && is_object( $data ) ) {
93-
foreach ( $data as $key => $value ) {
94-
$data->$key = $this->_run( $value, false, $recursion_level + 1, $visited_data );
93+
elseif ( $this->recurse_objects && ( is_object( $data ) || $data instanceof \__PHP_Incomplete_Class ) ) {
94+
if ( $data instanceof \__PHP_Incomplete_Class ) {
95+
$array = new ArrayObject( $data );
96+
\WP_CLI::warning(
97+
sprintf(
98+
'Skipping an uninitialized class "%s", replacements might not be complete.',
99+
$array['__PHP_Incomplete_Class_Name']
100+
)
101+
);
102+
} else {
103+
foreach ( $data as $key => $value ) {
104+
$data->$key = $this->_run( $value, false, $recursion_level + 1, $visited_data );
105+
}
95106
}
96107
}
97108

@@ -155,13 +166,19 @@ public function clear_log_data() {
155166
* @return string Error constant name.
156167
*/
157168
private function preg_error_message( $error ) {
158-
$constants = get_defined_constants( true );
159-
if ( ! array_key_exists( 'pcre', $constants ) ) {
160-
return '<unknown error>';
169+
static $error_names = null;
170+
171+
if ( null === $error_names ) {
172+
$definitions = get_defined_constants( true );
173+
$pcre_constants = array_key_exists( 'pcre', $definitions )
174+
? $definitions['pcre']
175+
: array();
176+
$error_names = array_flip( $pcre_constants );
161177
}
162178

163-
$names = array_flip( $constants['pcre'] );
164-
return isset( $names[ $error ] ) ? $names[ $error ] : '<unknown error>';
179+
return isset( $error_names[ $error ] )
180+
? $error_names[ $error ]
181+
: '<unknown error>';
165182
}
166183
}
167184

0 commit comments

Comments
 (0)