Completed
Push — psr4-jetpack-sync-module ( 862b11...910f64 )
by
unknown
277:16 queued 269:36
created

Import   A

Complexity

Total Complexity 23

Size/Duplication

Total Lines 166
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 1

Importance

Changes 0
Metric Value
dl 0
loc 166
c 0
b 0
f 0
rs 10
wmc 23
lcom 1
cbo 1
1
<?php
2
3
namespace Automattic\Jetpack\Sync\Modules;
4
use Automattic\Jetpack\Sync\Settings;
5
^
0 ignored issues
show
Bug introduced by
This code did not parse for me. Apparently, there is an error somewhere around this line:

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