1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace Automattic\Jetpack\Sync\Modules; |
4
|
|
|
|
5
|
|
|
class Import extends \Jetpack_Sync_Module { |
6
|
|
|
|
7
|
|
|
/** |
8
|
|
|
* Tracks which actions have already been synced for the import |
9
|
|
|
* to prevent the same event from being triggered a second time |
10
|
|
|
* |
11
|
|
|
* @var array |
12
|
|
|
*/ |
13
|
|
|
private $synced_actions = array(); |
14
|
|
|
|
15
|
|
|
/** |
16
|
|
|
* A mapping of action types to sync action name. |
17
|
|
|
* Keys are the name of the import action. |
18
|
|
|
* Values are the resulting sync action. |
19
|
|
|
* |
20
|
|
|
* Note: import_done and import_end both intentionally map to |
21
|
|
|
* jetpack_sync_import_end, as they both track the same type of action, |
22
|
|
|
* the successful completion of an import. Different import plugins use |
23
|
|
|
* differently named actions, and this is an attempt to consolidate. |
24
|
|
|
* |
25
|
|
|
* @var array |
26
|
|
|
*/ |
27
|
|
|
private static $import_sync_action_map = array( |
28
|
|
|
'import_start' => 'jetpack_sync_import_start', |
29
|
|
|
'import_done' => 'jetpack_sync_import_end', |
30
|
|
|
'import_end' => 'jetpack_sync_import_end', |
31
|
|
|
); |
32
|
|
|
|
33
|
|
|
public function name() { |
34
|
|
|
return 'import'; |
35
|
|
|
} |
36
|
|
|
|
37
|
|
|
public function init_listeners( $callable ) { |
38
|
|
|
add_action( 'export_wp', $callable ); |
39
|
|
|
add_action( 'jetpack_sync_import_start', $callable, 10, 2 ); |
40
|
|
|
add_action( 'jetpack_sync_import_end', $callable, 10, 2 ); |
41
|
|
|
|
42
|
|
|
// WordPress. |
43
|
|
|
add_action( 'import_start', array( $this, 'sync_import_action' ) ); |
44
|
|
|
|
45
|
|
|
// Movable type, RSS, Livejournal. |
46
|
|
|
add_action( 'import_done', array( $this, 'sync_import_action' ) ); |
47
|
|
|
|
48
|
|
|
// WordPress, Blogger, Livejournal, woo tax rate. |
49
|
|
|
add_action( 'import_end', array( $this, 'sync_import_action' ) ); |
50
|
|
|
} |
51
|
|
|
|
52
|
|
|
public function set_defaults() { |
53
|
|
|
$this->synced_actions = array(); |
54
|
|
|
} |
55
|
|
|
|
56
|
|
|
public function sync_import_action( $importer ) { |
57
|
|
|
$import_action = current_filter(); |
58
|
|
|
// Map action to event name. |
59
|
|
|
$sync_action = self::$import_sync_action_map[ $import_action ]; |
60
|
|
|
|
61
|
|
|
// Only sync each action once per import. |
62
|
|
|
if ( array_key_exists( $sync_action, $this->synced_actions ) && $this->synced_actions[ $sync_action ] ) { |
63
|
|
|
return; |
64
|
|
|
} |
65
|
|
|
|
66
|
|
|
// Mark this action as synced. |
67
|
|
|
$this->synced_actions[ $sync_action ] = true; |
68
|
|
|
|
69
|
|
|
// Prefer self-reported $importer value. |
70
|
|
|
if ( ! $importer ) { |
71
|
|
|
// Fall back to inferring by calling class name. |
72
|
|
|
$importer = self::get_calling_importer_class(); |
73
|
|
|
} |
74
|
|
|
|
75
|
|
|
// Get $importer from known_importers. |
76
|
|
|
$known_importers = \Jetpack_Sync_Settings::get_setting( 'known_importers' ); |
77
|
|
|
if ( isset( $known_importers[ $importer ] ) ) { |
78
|
|
|
$importer = $known_importers[ $importer ]; |
79
|
|
|
} |
80
|
|
|
|
81
|
|
|
$importer_name = $this->get_importer_name( $importer ); |
82
|
|
|
|
83
|
|
|
switch ( $sync_action ) { |
84
|
|
|
case 'jetpack_sync_import_start': |
85
|
|
|
/** |
86
|
|
|
* Used for syncing the start of an import |
87
|
|
|
* |
88
|
|
|
* @since 7.3.0 |
89
|
|
|
* |
90
|
|
|
* @module sync |
91
|
|
|
* |
92
|
|
|
* @param string $importer Either a string reported by the importer, the class name of the importer, or 'unknown'. |
93
|
|
|
* @param string $importer_name The name reported by the importer, or 'Unknown Importer'. |
94
|
|
|
*/ |
95
|
|
|
do_action( 'jetpack_sync_import_start', $importer, $importer_name ); |
96
|
|
|
break; |
97
|
|
|
|
98
|
|
|
case 'jetpack_sync_import_end': |
99
|
|
|
/** |
100
|
|
|
* Used for syncing the end of an import |
101
|
|
|
* |
102
|
|
|
* @since 7.3.0 |
103
|
|
|
* |
104
|
|
|
* @module sync |
105
|
|
|
* |
106
|
|
|
* @param string $importer Either a string reported by the importer, the class name of the importer, or 'unknown'. |
107
|
|
|
* @param string $importer_name The name reported by the importer, or 'Unknown Importer'. |
108
|
|
|
*/ |
109
|
|
|
do_action( 'jetpack_sync_import_end', $importer, $importer_name ); |
110
|
|
|
break; |
111
|
|
|
} |
112
|
|
|
} |
113
|
|
|
|
114
|
|
|
private function get_importer_name( $importer ) { |
115
|
|
|
$importers = get_importers(); |
116
|
|
|
return isset( $importers[ $importer ] ) ? $importers[ $importer ][0] : 'Unknown Importer'; |
117
|
|
|
} |
118
|
|
|
|
119
|
|
|
/** |
120
|
|
|
* Determine the class that extends `WP_Importer` which is responsible for |
121
|
|
|
* the current action. Designed to be used within an action handler. |
122
|
|
|
* |
123
|
|
|
* @return string The name of the calling class, or 'unknown'. |
124
|
|
|
*/ |
125
|
|
|
private static function get_calling_importer_class() { |
126
|
|
|
// If WP_Importer doesn't exist, neither will any importer that extends it. |
127
|
|
|
if ( ! class_exists( '\WP_Importer', false ) ) { |
128
|
|
|
return 'unknown'; |
129
|
|
|
} |
130
|
|
|
|
131
|
|
|
$action = current_filter(); |
132
|
|
|
$backtrace = debug_backtrace( false ); //phpcs:ignore PHPCompatibility.FunctionUse.NewFunctionParameters.debug_backtrace_optionsFound,WordPress.PHP.DevelopmentFunctions.error_log_debug_backtrace |
133
|
|
|
|
134
|
|
|
$do_action_pos = -1; |
135
|
|
|
$backtrace_len = count( $backtrace ); |
136
|
|
|
for ( $i = 0; $i < $backtrace_len; $i++ ) { |
137
|
|
|
// Find the location in the stack of the calling action. |
138
|
|
|
if ( 'do_action' === $backtrace[ $i ]['function'] && $action === $backtrace[ $i ]['args'][0] ) { |
139
|
|
|
$do_action_pos = $i; |
140
|
|
|
break; |
141
|
|
|
} |
142
|
|
|
} |
143
|
|
|
|
144
|
|
|
// If the action wasn't called, the calling class is unknown. |
145
|
|
|
if ( -1 === $do_action_pos ) { |
146
|
|
|
return 'unknown'; |
147
|
|
|
} |
148
|
|
|
|
149
|
|
|
// Continue iterating the stack looking for a caller that extends WP_Importer. |
150
|
|
|
for ( $i = $do_action_pos + 1; $i < $backtrace_len; $i++ ) { |
151
|
|
|
// If there is no class on the trace, continue. |
152
|
|
|
if ( ! isset( $backtrace[ $i ]['class'] ) ) { |
153
|
|
|
continue; |
154
|
|
|
} |
155
|
|
|
|
156
|
|
|
$class_name = $backtrace[ $i ]['class']; |
157
|
|
|
|
158
|
|
|
// Check if the class extends WP_Importer. |
159
|
|
|
if ( class_exists( $class_name, false ) ) { |
160
|
|
|
$parents = class_parents( $class_name, false ); |
161
|
|
|
if ( $parents && in_array( '\WP_Importer', $parents, true ) ) { |
|
|
|
|
162
|
|
|
return $class_name; |
163
|
|
|
} |
164
|
|
|
} |
165
|
|
|
} |
166
|
|
|
|
167
|
|
|
// If we've exhausted the stack without a match, the calling class is unknown. |
168
|
|
|
return 'unknown'; |
169
|
|
|
} |
170
|
|
|
} |
171
|
|
|
|
This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.
Consider making the comparison explicit by using
empty(..)
or! empty(...)
instead.