WordPoints_Importer   A
last analyzed

Complexity

Total Complexity 20

Size/Duplication

Total Lines 234
Duplicated Lines 3.42 %

Coupling/Cohesion

Components 1
Dependencies 1

Importance

Changes 0
Metric Value
dl 8
loc 234
rs 10
c 0
b 0
f 0
wmc 20
lcom 1
cbo 1

9 Methods

Rating   Name   Duplication   Size   Complexity  
is_available() 0 1 ?
A __construct() 0 4 1
A supports_component() 0 4 1
A get_options_for_component() 0 8 2
A do_import() 0 19 3
A no_interruptions() 0 4 1
A validate_import_settings() 0 13 1
C do_import_for_component() 8 36 7
B do_import_for_option() 0 25 4

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

1
<?php
2
3
/**
4
 * Base class for the importers.
5
 *
6
 * @package WordPoints_Importer
7
 * @since 1.0.0
8
 */
9
10
/**
11
 * Represents an importer.
12
 *
13
 * @since 1.0.0
14
 */
15
abstract class WordPoints_Importer {
16
17
	/**
18
	 * The name of the importer.
19
	 *
20
	 * @since 1.0.0
21
	 *
22
	 * @type string $name
23
	 */
24
	protected $name;
25
26
	/**
27
	 * The components supported by this importer.
28
	 *
29
	 * The keys are the component slugs, the values arrays of options for importing
30
	 * to that component.
31
	 *
32
	 * @since 1.0.0
33
	 *
34
	 * @type array[] $components
35
	 */
36
	protected $components = array();
37
38
	/**
39
	 * The feedback provider object.
40
	 *
41
	 * This is only set by self::do_import().
42
	 *
43
	 * @since 1.0.0
44
	 *
45
	 * @type WordPoints_Importer_Feedback $feedback
46
	 */
47
	protected $feedback;
48
49
	/**
50
	 * Check if this importer is available.
51
	 *
52
	 * @since 1.0.0
53
	 *
54
	 * @return true|WP_Error A WP_Error if the importer is not available.
55
	 */
56
	abstract public function is_available();
57
58
	/**
59
	 * Construct the importer.
60
	 *
61
	 * @since 1.0.0
62
	 *
63
	 * @param string $name The name of the importer.
64
	 */
65
	public function __construct( $name ) {
66
67
		$this->name = $name;
68
	}
69
70
	/**
71
	 * Check if this importer supports a specific component.
72
	 *
73
	 * @since 1.0.0
74
	 *
75
	 * @param string $component The slug of a component.
76
	 *
77
	 * @return bool True if the component is supported, otherwise false.
78
	 */
79
	public function supports_component( $component ) {
80
81
		return isset( $this->components[ $component ] );
82
	}
83
84
	/**
85
	 * Get the import options for a component.
86
	 *
87
	 * @since 1.0.0
88
	 *
89
	 * @param string $component The slug of a component.
90
	 *
91
	 * @return array[] The options for this component.
92
	 */
93
	public function get_options_for_component( $component ) {
94
95
		if ( ! $this->supports_component( $component ) ) {
96
			return array();
97
		}
98
99
		return $this->components[ $component ];
100
	}
101
102
	/**
103
	 * Run the import.
104
	 *
105
	 * @since 1.0.0
106
	 *
107
	 * @param array                        $args     The settings for the import.
108
	 * @param WordPoints_Importer_Feedback $feedback The feedback object.
109
	 */
110
	public function do_import( array $args, $feedback = null ) {
111
112
		if ( ! ( $feedback instanceof WordPoints_Importer_Feedback ) ) {
113
			$feedback = new WordPoints_Importer_Feedback();
114
		}
115
116
		$this->feedback = $feedback;
117
118
		// translators: Plugin name.
119
		$this->feedback->info( sprintf( __( 'Importing from %s&hellip;', 'wordpoints-importer' ), $this->name ) );
120
121
		$this->no_interruptions();
122
123
		foreach ( $args as $component => $options ) {
124
			$this->do_import_for_component( $component, $options );
125
		}
126
127
		$this->feedback->info( __( 'Import complete.', 'wordpoints-importer' ) );
128
	}
129
130
	/**
131
	 * Prevent any interruptions from occurring during the import.
132
	 *
133
	 * @since 1.2.1
134
	 */
135
	protected function no_interruptions() {
136
137
		wordpoints_prevent_interruptions();
138
	}
139
140
	/**
141
	 * Validate the import settings for a component.
142
	 *
143
	 * @since 1.0.0
144
	 *
145
	 * @param string $component The slug of the component.
146
	 * @param array  $settings  The settings supplied for this component.
147
	 *
148
	 * @return bool Whether the settings are valid.
149
	 */
150
	protected function validate_import_settings( $component, $settings ) {
151
152
		/**
153
		 * Filter whether the settings are valid before importing.
154
		 *
155
		 * @since 1.0.0
156
		 *
157
		 * @param bool  $valid    Whether the settings are valid.
158
		 * @param array $settings The settings for this component.
159
		 * @param WordPoints_Importer_Feedback $feedback The feedback object.
160
		 */
161
		return apply_filters( "wordpoints_import_settings_valid-{$component}", true, $settings, $this->feedback );
162
	}
163
164
	/**
165
	 * Run the import for a component.
166
	 *
167
	 * @since 1.0.0
168
	 *
169
	 * @param string $component The component to run the import for.
170
	 * @param array  $options   The selected options of what to import.
171
	 */
172
	protected function do_import_for_component( $component, $options ) {
173
174
		$component_data = WordPoints_Components::instance()->get_component(
175
			$component
176
		);
177
178 View Code Duplication
		if ( false === $component_data ) {
179
			// translators: Component name.
180
			$this->feedback->warning( sprintf( __( 'Skipping %s component—not installed.', 'wordpoints-importer' ), esc_html( $component ) ) );
181
			return;
182
		}
183
184 View Code Duplication
		if ( true !== $this->supports_component( $component ) ) {
185
			// translators: Component name.
186
			$this->feedback->warning( sprintf( __( 'Skipping the %s component—not supported.', 'wordpoints-importer' ), $component_data['name'] ) );
187
			return;
188
		}
189
190
		$settings = array();
191
192
		if ( isset( $options['_data'] ) ) {
193
			$settings = $options['_data'];
194
			unset( $options['_data'] );
195
		}
196
197
		if ( empty( $options ) || ! $this->validate_import_settings( $component, $settings ) ) {
198
			return;
199
		}
200
201
		// translators: Component name.
202
		$this->feedback->info( sprintf( __( 'Importing data to the %s component&hellip;', 'wordpoints-importer' ), $component_data['name'] ) );
203
204
		foreach ( $options as $option => $unused ) {
205
			$this->do_import_for_option( $option, $component, $settings );
206
		}
207
	}
208
209
	/**
210
	 * Run the import for an option.
211
	 *
212
	 * The import is split up into different options which the user can select (these
213
	 * are displayed to the user as checkboxes in the form). This handles the import
214
	 * for each of the individual things the user has selected to import. These are
215
	 * all optional, so each is just termed an import "option" here.
216
	 *
217
	 * @since 1.0.0
218
	 *
219
	 * @param string $option    An import option that has been selected.
220
	 * @param string $component The component this option is for.
221
	 * @param array  $settings  Other settings for this component.
222
	 */
223
	protected function do_import_for_option( $option, $component, $settings ) {
224
225
		if ( ! isset( $this->components[ $component ][ $option ] ) ) {
226
			// translators: Option name.
227
			$this->feedback->warning( sprintf( __( 'Skipping unrecognized import option &#8220;%s&#8221;&hellip;', 'wordpoints-importer' ), $option ) );
228
			return;
229
		}
230
231
		$option_data = $this->components[ $component ][ $option ];
232
233
		// Check if we can actually run this option.
234
		if ( isset( $option_data['can_import'] ) ) {
235
236
			$cant_import = call_user_func( $option_data['can_import'], $settings );
237
238
			if ( is_wp_error( $cant_import ) ) {
239
				// translators: 1. Option name; 2. Reason the import was skipped.
240
				$this->feedback->warning( sprintf( __( 'Skipping importing %1$s. Reason: %2$s', 'wordpoints-importer' ), $option_data['label'], $cant_import->get_error_message() ) );
241
				return;
242
			}
243
		}
244
245
		// OK, we can run the import method for this option.
246
		call_user_func( $option_data['function'], $settings );
247
	}
248
}
249
250
// EOF
251