← All changes
|
jetpack_vendor/automattic/jetpack-sync/src/modules/class-import.php
+224
-0
16.2-beta
→
16.3
View file →
| @@ -1,0 +1,224 @@ | ||
| 1 | +<?php | |
| 2 | +/** | |
| 3 | + * Import sync module. | |
| 4 | + * | |
| 5 | + * @package automattic/jetpack-sync | |
| 6 | + */ | |
| 7 | + | |
| 8 | +namespace Automattic\Jetpack\Sync\Modules; | |
| 9 | + | |
| 10 | +use Automattic\Jetpack\Sync\Settings; | |
| 11 | + | |
| 12 | +if ( ! defined( 'ABSPATH' ) ) { | |
| 13 | + exit( 0 ); | |
| 14 | +} | |
| 15 | + | |
| 16 | +/** | |
| 17 | + * Class to handle sync for imports. | |
| 18 | + */ | |
| 19 | +class Import extends Module { | |
| 20 | + | |
| 21 | + /** | |
| 22 | + * Tracks which actions have already been synced for the import | |
| 23 | + * to prevent the same event from being triggered a second time. | |
| 24 | + * | |
| 25 | + * @var array | |
| 26 | + */ | |
| 27 | + private $synced_actions = array(); | |
| 28 | + | |
| 29 | + /** | |
| 30 | + * A mapping of action types to sync action name. | |
| 31 | + * Keys are the name of the import action. | |
| 32 | + * Values are the resulting sync action. | |
| 33 | + * | |
| 34 | + * Note: import_done and import_end both intentionally map to | |
| 35 | + * jetpack_sync_import_end, as they both track the same type of action, | |
| 36 | + * the successful completion of an import. Different import plugins use | |
| 37 | + * differently named actions, and this is an attempt to consolidate. | |
| 38 | + * | |
| 39 | + * @var array | |
| 40 | + */ | |
| 41 | + private static $import_sync_action_map = array( | |
| 42 | + 'import_start' => 'jetpack_sync_import_start', | |
| 43 | + 'import_done' => 'jetpack_sync_import_end', | |
| 44 | + 'import_end' => 'jetpack_sync_import_end', | |
| 45 | + ); | |
| 46 | + | |
| 47 | + /** | |
| 48 | + * Sync module name. | |
| 49 | + * | |
| 50 | + * @access public | |
| 51 | + * | |
| 52 | + * @return string | |
| 53 | + */ | |
| 54 | + public function name() { | |
| 55 | + return 'import'; | |
| 56 | + } | |
| 57 | + | |
| 58 | + /** | |
| 59 | + * Initialize imports action listeners. | |
| 60 | + * | |
| 61 | + * @access public | |
| 62 | + * | |
| 63 | + * @param callable $callable Action handler callable. | |
| 64 | + */ | |
| 65 | + public function init_listeners( $callable ) { | |
| 66 | + add_action( 'export_wp', $callable ); | |
| 67 | + add_action( 'jetpack_sync_import_start', $callable, 10, 2 ); | |
| 68 | + add_action( 'jetpack_sync_import_end', $callable, 10, 2 ); | |
| 69 | + | |
| 70 | + // WordPress. | |
| 71 | + add_action( 'import_start', array( $this, 'sync_import_action' ) ); | |
| 72 | + | |
| 73 | + // Movable type, RSS, Livejournal. | |
| 74 | + add_action( 'import_done', array( $this, 'sync_import_action' ) ); | |
| 75 | + | |
| 76 | + // WordPress, Blogger, Livejournal, woo tax rate. | |
| 77 | + add_action( 'import_end', array( $this, 'sync_import_action' ) ); | |
| 78 | + } | |
| 79 | + | |
| 80 | + /** | |
| 81 | + * Set module defaults. | |
| 82 | + * Define an empty list of synced actions for us to fill later. | |
| 83 | + * | |
| 84 | + * @access public | |
| 85 | + */ | |
| 86 | + public function set_defaults() { | |
| 87 | + $this->synced_actions = array(); | |
| 88 | + } | |
| 89 | + | |
| 90 | + /** | |
| 91 | + * Generic handler for import actions. | |
| 92 | + * | |
| 93 | + * @access public | |
| 94 | + * | |
| 95 | + * @param string $importer Either a string reported by the importer, the class name of the importer, or 'unknown'. | |
| 96 | + */ | |
| 97 | + public function sync_import_action( $importer ) { | |
| 98 | + $import_action = current_filter(); | |
| 99 | + // Map action to event name. | |
| 100 | + $sync_action = self::$import_sync_action_map[ $import_action ]; | |
| 101 | + | |
| 102 | + // Only sync each action once per import. | |
| 103 | + if ( array_key_exists( $sync_action, $this->synced_actions ) && $this->synced_actions[ $sync_action ] ) { | |
| 104 | + return; | |
| 105 | + } | |
| 106 | + | |
| 107 | + // Mark this action as synced. | |
| 108 | + $this->synced_actions[ $sync_action ] = true; | |
| 109 | + | |
| 110 | + // Prefer self-reported $importer value. | |
| 111 | + if ( ! $importer ) { | |
| 112 | + // Fall back to inferring by calling class name. | |
| 113 | + $importer = self::get_calling_importer_class(); | |
| 114 | + } | |
| 115 | + | |
| 116 | + // Get $importer from known_importers. | |
| 117 | + $known_importers = Settings::get_setting( 'known_importers' ); | |
| 118 | + if ( is_string( $importer ) && isset( $known_importers[ $importer ] ) ) { | |
| 119 | + $importer = $known_importers[ $importer ]; | |
| 120 | + } | |
| 121 | + | |
| 122 | + $importer_name = $this->get_importer_name( $importer ); | |
| 123 | + | |
| 124 | + switch ( $sync_action ) { | |
| 125 | + case 'jetpack_sync_import_start': | |
| 126 | + /** | |
| 127 | + * Used for syncing the start of an import | |
| 128 | + * | |
| 129 | + * @since 1.6.3 | |
| 130 | + * @since-jetpack 7.3.0 | |
| 131 | + * | |
| 132 | + * @module sync | |
| 133 | + * | |
| 134 | + * @param string $importer Either a string reported by the importer, the class name of the importer, or 'unknown'. | |
| 135 | + * @param string $importer_name The name reported by the importer, or 'Unknown Importer'. | |
| 136 | + */ | |
| 137 | + do_action( 'jetpack_sync_import_start', $importer, $importer_name ); | |
| 138 | + break; | |
| 139 | + | |
| 140 | + case 'jetpack_sync_import_end': | |
| 141 | + /** | |
| 142 | + * Used for syncing the end of an import | |
| 143 | + * | |
| 144 | + * @since 1.6.3 | |
| 145 | + * @since-jetpack 7.3.0 | |
| 146 | + * | |
| 147 | + * @module sync | |
| 148 | + * | |
| 149 | + * @param string $importer Either a string reported by the importer, the class name of the importer, or 'unknown'. | |
| 150 | + * @param string $importer_name The name reported by the importer, or 'Unknown Importer'. | |
| 151 | + */ | |
| 152 | + do_action( 'jetpack_sync_import_end', $importer, $importer_name ); | |
| 153 | + break; | |
| 154 | + } | |
| 155 | + } | |
| 156 | + | |
| 157 | + /** | |
| 158 | + * Retrieve the name of the importer. | |
| 159 | + * | |
| 160 | + * @access private | |
| 161 | + * | |
| 162 | + * @param string $importer Either a string reported by the importer, the class name of the importer, or 'unknown'. | |
| 163 | + * @return string Name of the importer, or "Unknown Importer" if importer is unknown. | |
| 164 | + */ | |
| 165 | + private function get_importer_name( $importer ) { | |
| 166 | + $importers = get_importers(); | |
| 167 | + return isset( $importers[ $importer ] ) ? $importers[ $importer ][0] : 'Unknown Importer'; | |
| 168 | + } | |
| 169 | + | |
| 170 | + /** | |
| 171 | + * Determine the class that extends `WP_Importer` which is responsible for | |
| 172 | + * the current action. Designed to be used within an action handler. | |
| 173 | + * | |
| 174 | + * @access private | |
| 175 | + * @static | |
| 176 | + * | |
| 177 | + * @return string The name of the calling class, or 'unknown'. | |
| 178 | + */ | |
| 179 | + private static function get_calling_importer_class() { | |
| 180 | + // If WP_Importer doesn't exist, neither will any importer that extends it. | |
| 181 | + if ( ! class_exists( 'WP_Importer', false ) ) { | |
| 182 | + return 'unknown'; | |
| 183 | + } | |
| 184 | + | |
| 185 | + $action = current_filter(); | |
| 186 | + $backtrace = debug_backtrace( 0 ); //phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_debug_backtrace | |
| 187 | + | |
| 188 | + $do_action_pos = -1; | |
| 189 | + $backtrace_len = count( $backtrace ); | |
| 190 | + for ( $i = 0; $i < $backtrace_len; $i++ ) { | |
| 191 | + // Find the location in the stack of the calling action. | |
| 192 | + if ( 'do_action' === $backtrace[ $i ]['function'] && $action === $backtrace[ $i ]['args'][0] ) { | |
| 193 | + $do_action_pos = $i; | |
| 194 | + break; | |
| 195 | + } | |
| 196 | + } | |
| 197 | + | |
| 198 | + // If the action wasn't called, the calling class is unknown. | |
| 199 | + if ( -1 === $do_action_pos ) { | |
| 200 | + return 'unknown'; | |
| 201 | + } | |
| 202 | + | |
| 203 | + // Continue iterating the stack looking for a caller that extends WP_Importer. | |
| 204 | + for ( $i = $do_action_pos + 1; $i < $backtrace_len; $i++ ) { | |
| 205 | + // If there is no class on the trace, continue. | |
| 206 | + if ( ! isset( $backtrace[ $i ]['class'] ) ) { | |
| 207 | + continue; | |
| 208 | + } | |
| 209 | + | |
| 210 | + $class_name = $backtrace[ $i ]['class']; | |
| 211 | + | |
| 212 | + // Check if the class extends WP_Importer. | |
| 213 | + if ( class_exists( $class_name, false ) ) { | |
| 214 | + $parents = class_parents( $class_name, false ); | |
| 215 | + if ( $parents && in_array( 'WP_Importer', $parents, true ) ) { | |
| 216 | + return $class_name; | |
| 217 | + } | |
| 218 | + } | |
| 219 | + } | |
| 220 | + | |
| 221 | + // If we've exhausted the stack without a match, the calling class is unknown. | |
| 222 | + return 'unknown'; | |
| 223 | + } | |
| 224 | +} | |