1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
|
<?php declare( strict_types=1 );
namespace Automattic\WooCommerce\Internal\CLI\Migrator\Core;
use InvalidArgumentException; use Automattic\WooCommerce\Internal\CLI\Migrator\Interfaces\PlatformFetcherInterface; use Automattic\WooCommerce\Internal\CLI\Migrator\Interfaces\PlatformMapperInterface; use WP_CLI;
/** * PlatformRegistry class. * * This class is responsible for loading and providing access to registered migration platforms. */ class PlatformRegistry {
/** * An array to hold the configuration for all registered platforms. * * @var array */ private array $platforms = array();
/** * Constructor to load platforms when the service is instantiated. */ public function __construct() { $this->load_platforms(); }
/** * Loads platforms discovered via a filter. * * It also validates that each registered platform provides both a fetcher and a mapper class. */ private function load_platforms(): void { /** * Filters the list of registered migration platforms. * * External platform plugins should hook into this filter to register themselves. * Each platform plugin is responsible for its own autoloading and initialization. * * @param array $platforms An associative array of platform configurations. * Each key is a unique platform ID (e.g., 'shopify'), and the value * is another array containing 'name', 'fetcher', and 'mapper' class names. * @since 1.0.0 */ $platforms = apply_filters( 'woocommerce_migrator_platforms', array() );
if ( ! is_array( $platforms ) ) { return; }
foreach ( $platforms as $platform_id => $config ) { // Validate that required keys exist and have valid values. if ( isset( $config['fetcher'], $config['mapper'] ) && is_string( $config['fetcher'] ) && ! empty( $config['fetcher'] ) && is_string( $config['mapper'] ) && ! empty( $config['mapper'] ) ) { $this->platforms[ $platform_id ] = $config; } } }
/** * Returns the entire array of registered platform configurations. * * @return array */ public function get_platforms(): array { return $this->platforms; }
/** * Returns the configuration array for a single, specified platform ID. * * @param string $platform_id The ID of the platform (e.g., 'shopify'). * * @return array|null The platform configuration or null if not found. */ public function get_platform( string $platform_id ): ?array { return $this->platforms[ $platform_id ] ?? null; }
/** * Retrieves and instantiates the fetcher class for a given platform. * * @param string $platform_id The ID of the platform. * * @return PlatformFetcherInterface An instance of the platform's fetcher class. * * @throws InvalidArgumentException If the platform is not found or the fetcher class is invalid. */ public function get_fetcher( string $platform_id ): PlatformFetcherInterface { $platform = $this->get_platform( $platform_id );
if ( ! $platform ) { throw new InvalidArgumentException( sprintf( /* translators: %s: Platform ID */ esc_html__( 'Platform %s not found.', 'woocommerce' ), esc_html( $platform_id ) ) ); }
$fetcher_class = $platform['fetcher'];
// Validate that fetcher class is a non-empty string. if ( ! is_string( $fetcher_class ) || empty( $fetcher_class ) ) { throw new InvalidArgumentException( sprintf( /* translators: %s: Platform ID */ esc_html__( 'Invalid fetcher class for platform %s. Fetcher must be a non-empty string.', 'woocommerce' ), esc_html( $platform_id ) ) ); }
if ( ! class_exists( $fetcher_class ) ) { throw new InvalidArgumentException( sprintf( /* translators: %1$s: Platform ID, %2$s: Class name */ esc_html__( 'Invalid fetcher class for platform %1$s. Class %2$s does not exist.', 'woocommerce' ), esc_html( $platform_id ), esc_html( $fetcher_class ) ) ); }
if ( ! in_array( PlatformFetcherInterface::class, class_implements( $fetcher_class ), true ) ) { throw new InvalidArgumentException( sprintf( /* translators: %1$s: Platform ID, %2$s: Class name, %3$s: Interface name */ esc_html__( 'Invalid fetcher class for platform %1$s. Class %2$s does not implement %3$s.', 'woocommerce' ), esc_html( $platform_id ), esc_html( $fetcher_class ), esc_html( PlatformFetcherInterface::class ) ) ); }
// Use the WooCommerce DI container to properly inject dependencies. $container = wc_get_container(); return $container->get( $fetcher_class ); }
/** * Retrieves and instantiates the mapper class for a given platform. * * @param string $platform_id The ID of the platform. * @param array $args Optional arguments to pass to the mapper constructor. * * @return PlatformMapperInterface An instance of the platform's mapper class. * * @throws InvalidArgumentException If the platform is not found or the mapper class is invalid. */ public function get_mapper( string $platform_id, array $args = array() ): PlatformMapperInterface { $platform = $this->get_platform( $platform_id );
if ( ! $platform ) { throw new InvalidArgumentException( sprintf( /* translators: %s: Platform ID */ esc_html__( 'Platform %s not found.', 'woocommerce' ), esc_html( $platform_id ) ) ); }
$mapper_class = $platform['mapper'];
// Validate that mapper class is a non-empty string. if ( ! is_string( $mapper_class ) || empty( $mapper_class ) ) { throw new InvalidArgumentException( sprintf( /* translators: %s: Platform ID */ esc_html__( 'Invalid mapper class for platform %s. Mapper must be a non-empty string.', 'woocommerce' ), esc_html( $platform_id ) ) ); }
if ( ! class_exists( $mapper_class ) ) { throw new InvalidArgumentException( sprintf( /* translators: %1$s: Platform ID, %2$s: Class name */ esc_html__( 'Invalid mapper class for platform %1$s. Class %2$s does not exist.', 'woocommerce' ), esc_html( $platform_id ), esc_html( $mapper_class ) ) ); }
if ( ! in_array( PlatformMapperInterface::class, class_implements( $mapper_class ), true ) ) { throw new InvalidArgumentException( sprintf( /* translators: %1$s: Platform ID, %2$s: Class name, %3$s: Interface name */ esc_html__( 'Invalid mapper class for platform %1$s. Class %2$s does not implement %3$s.', 'woocommerce' ), esc_html( $platform_id ), esc_html( $mapper_class ), esc_html( PlatformMapperInterface::class ) ) ); }
// If arguments are provided, instantiate manually to pass constructor args. // Otherwise, use the WooCommerce DI container for dependency injection. if ( ! empty( $args ) ) { return new $mapper_class( $args ); } else { $container = wc_get_container(); return $container->get( $mapper_class ); } }
/** * Determines the platform to use from command arguments, with validation and fallback. * * @param array $assoc_args Associative arguments from the command. * @param string $default_platform The default platform to use if none specified. * * @return string The validated platform slug. */ public function resolve_platform( array $assoc_args, string $default_platform = 'shopify' ): string { $platform = $assoc_args['platform'] ?? null;
if ( empty( $platform ) ) { $platform = $default_platform; WP_CLI::log( "Platform not specified, using default: '{$platform}'." ); }
// Validate the platform exists. if ( ! $this->get_platform( $platform ) ) { $available_platforms = array_keys( $this->get_platforms() ); if ( empty( $available_platforms ) ) { WP_CLI::error( 'No platforms are currently registered. Please ensure platform plugins are installed and activated.' ); } else { WP_CLI::error( sprintf( "Platform '%s' is not registered. Available platforms: %s", $platform, implode( ', ', $available_platforms ) ) ); } }
return $platform; }
/** * Get platform-specific credential fields for setup prompts. * * @param string $platform_slug The platform identifier. * * @return array Array of field_name => prompt_text pairs. */ public function get_platform_credential_fields( string $platform_slug ): array { $platform = $this->get_platform( $platform_slug ); if ( ! is_array( $platform ) ) { return array(); } $credentials = $platform['credentials'] ?? array(); return is_array( $credentials ) ? $credentials : array(); } }
|