Passed
Push — ci ( ddfce8...b91ee7 )
by litefeel
02:37
created

Writing_On_GitHub   D

Complexity

Total Complexity 48

Size/Duplication

Total Lines 383
Duplicated Lines 2.09 %

Coupling/Cohesion

Components 10
Dependencies 11

Test Coverage

Coverage 0%

Importance

Changes 0
Metric Value
wmc 48
lcom 10
cbo 11
dl 8
loc 383
ccs 0
cts 130
cp 0
rs 4.6865
c 0
b 0
f 0

21 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 13 4
A boot() 0 20 1
A edit_post_link() 0 10 3
B ignore_post_meta() 0 22 6
A the_content() 8 23 1
A l10n() 0 3 1
A start_export() 0 3 1
A start_import() 0 3 1
A activate() 0 5 2
A activation_notice() 0 18 2
A controller() 0 3 1
A cli() 0 7 2
A request() 0 7 2
A response() 0 7 2
A api() 0 7 2
A import() 0 7 2
A export() 0 7 2
A semaphore() 0 7 2
A database() 0 7 2
B write_log() 0 15 8
A start_cron() 0 6 1

How to fix   Duplicated Code    Complexity   

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:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like Writing_On_GitHub often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use Writing_On_GitHub, and based on these observations, apply Extract Interface, too.

1
<?php
2
/**
3
 * Plugin Name: Writing on GitHub
4
 * Plugin URI: https://github.com/litefeel/writing-on-github
5
 * Description: A WordPress plugin to allow you writing on GitHub (or Jekyll site).
6
 * Version: 1.5.1
7
 * Author:  litefeel
8
 * Author URI: https://www.litefeel.com
9
 * License: GPLv2
10
 * Text Domain: writing-on-github
11
 */
12
13
// If the functions have already been autoloaded, don't reload.
14
// This fixes function duplication during unit testing.
15
if ( defined( 'WRITING_ON_GITHUB_TEST' ) && WRITING_ON_GITHUB_TEST ) {
16
	$path = dirname( __FILE__ ) . '/vendor/autoload.php';
17
	include_once $path;
18
}
19
20
21
// require_once(dirname(__FILE__) . '/Spyc.php');
22
require_once(dirname(__FILE__) . '/lib/database.php');
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after opening bracket; 0 found
Loading history...
Coding Style introduced by
Expected 1 spaces before closing bracket; 0 found
Loading history...
23
require_once(dirname(__FILE__) . '/lib/admin.php');
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after opening bracket; 0 found
Loading history...
Coding Style introduced by
Expected 1 spaces before closing bracket; 0 found
Loading history...
24
require_once(dirname(__FILE__) . '/lib/payload.php');
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after opening bracket; 0 found
Loading history...
Coding Style introduced by
Expected 1 spaces before closing bracket; 0 found
Loading history...
25
require_once(dirname(__FILE__) . '/lib/post.php');
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after opening bracket; 0 found
Loading history...
Coding Style introduced by
Expected 1 spaces before closing bracket; 0 found
Loading history...
26
// require_once(dirname(__FILE__) . '/lib/cli.php');
27
require_once(dirname(__FILE__) . '/lib/controller.php');
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after opening bracket; 0 found
Loading history...
Coding Style introduced by
Expected 1 spaces before closing bracket; 0 found
Loading history...
28
require_once(dirname(__FILE__) . '/lib/export.php');
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after opening bracket; 0 found
Loading history...
Coding Style introduced by
Expected 1 spaces before closing bracket; 0 found
Loading history...
29
require_once(dirname(__FILE__) . '/lib/semaphore.php');
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after opening bracket; 0 found
Loading history...
Coding Style introduced by
Expected 1 spaces before closing bracket; 0 found
Loading history...
30
require_once(dirname(__FILE__) . '/lib/request.php');
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after opening bracket; 0 found
Loading history...
Coding Style introduced by
Expected 1 spaces before closing bracket; 0 found
Loading history...
31
require_once(dirname(__FILE__) . '/lib/client/base.php');
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after opening bracket; 0 found
Loading history...
Coding Style introduced by
Expected 1 spaces before closing bracket; 0 found
Loading history...
32
require_once(dirname(__FILE__) . '/lib/client/fetch.php');
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after opening bracket; 0 found
Loading history...
Coding Style introduced by
Expected 1 spaces before closing bracket; 0 found
Loading history...
33
require_once(dirname(__FILE__) . '/lib/client/persist.php');
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after opening bracket; 0 found
Loading history...
Coding Style introduced by
Expected 1 spaces before closing bracket; 0 found
Loading history...
34
require_once(dirname(__FILE__) . '/lib/import.php');
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after opening bracket; 0 found
Loading history...
Coding Style introduced by
Expected 1 spaces before closing bracket; 0 found
Loading history...
35
require_once(dirname(__FILE__) . '/lib/api.php');
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after opening bracket; 0 found
Loading history...
Coding Style introduced by
Expected 1 spaces before closing bracket; 0 found
Loading history...
36
require_once(dirname(__FILE__) . '/lib/fileinfo.php');
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after opening bracket; 0 found
Loading history...
Coding Style introduced by
Expected 1 spaces before closing bracket; 0 found
Loading history...
37
require_once(dirname(__FILE__) . '/lib/blob.php');
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after opening bracket; 0 found
Loading history...
Coding Style introduced by
Expected 1 spaces before closing bracket; 0 found
Loading history...
38
require_once(dirname(__FILE__) . '/lib/response.php');
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after opening bracket; 0 found
Loading history...
Coding Style introduced by
Expected 1 spaces before closing bracket; 0 found
Loading history...
39
// require_once(dirname(__FILE__) . '/views/setting-field.php');
40
// require_once(dirname(__FILE__) . '/views/options.php');
41
// require_once(dirname(__FILE__) . '/views/user-setting-field.php');
42
43
add_action( 'plugins_loaded', array( new Writing_On_GitHub, 'boot' ) );
44
45
class Writing_On_GitHub {
46
47
	/**
48
	 * Object instance
49
	 * @var self
50
	 */
51
	public static $instance;
52
53
	/**
54
	 * Language text domain
55
	 * @var string
56
	 */
57
	public static $text_domain = 'writing-on-github';
58
59
	/**
60
	 * Controller object
61
	 * @var Writing_On_GitHub_Controller
62
	 */
63
	public $controller;
64
65
	/**
66
	 * Controller object
67
	 * @var Writing_On_GitHub_Admin
68
	 */
69
	public $admin;
70
71
	/**
72
	 * CLI object.
73
	 *
74
	 * @var Writing_On_GitHub_CLI
75
	 */
76
	protected $cli;
77
78
	/**
79
	 * Request object.
80
	 *
81
	 * @var Writing_On_GitHub_Request
82
	 */
83
	protected $request;
84
85
	/**
86
	 * Response object.
87
	 *
88
	 * @var Writing_On_GitHub_Response
89
	 */
90
	protected $response;
91
92
	/**
93
	 * Api object.
94
	 *
95
	 * @var Writing_On_GitHub_Api
96
	 */
97
	protected $api;
98
99
	/**
100
	 * Import object.
101
	 *
102
	 * @var Writing_On_GitHub_Import
103
	 */
104
	protected $import;
105
106
	/**
107
	 * Export object.
108
	 *
109
	 * @var Writing_On_GitHub_Export
110
	 */
111
	protected $export;
112
113
	/**
114
	 * Semaphore object.
115
	 *
116
	 * @var Writing_On_GitHub_Semaphore
117
	 */
118
	protected $semaphore;
119
120
	/**
121
	 * Database object.
122
	 *
123
	 * @var Writing_On_GitHub_Database
124
	 */
125
	protected $database;
126
127
	/**
128
	 * Called at load time, hooks into WP core
129
	 */
130
	public function __construct() {
131
		self::$instance = $this;
132
133
		if ( is_admin() ) {
134
			$this->admin = new Writing_On_GitHub_Admin;
135
		}
136
137
		$this->controller = new Writing_On_GitHub_Controller( $this );
138
139
		if ( defined( 'WP_CLI' ) && WP_CLI ) {
140
			WP_CLI::add_command( 'wogh', $this->cli() );
141
		}
142
	}
143
144
	/**
145
	 * Attaches the plugin's hooks into WordPress.
146
	 */
147
	public function boot() {
148
		register_activation_hook( __FILE__, array( $this, 'activate' ) );
149
		add_action( 'admin_notices', array( $this, 'activation_notice' ) );
150
151
		add_action( 'init', array( $this, 'l10n' ) );
152
153
		// Controller actions.
154
		add_action( 'save_post', array( $this->controller, 'export_post' ) );
155
		add_action( 'delete_post', array( $this->controller, 'delete_post' ) );
156
		add_action( 'wp_ajax_nopriv_wogh_push_request', array( $this->controller, 'pull_posts' ) );
157
        add_action( 'wogh_export', array( $this->controller, 'export_all' ), 10, 2 );
158
		add_action( 'wogh_import', array( $this->controller, 'import_master' ), 10, 1 );
159
		add_filter( 'get_edit_post_link', array( $this, 'edit_post_link' ), 10, 3 );
160
161
		// add_filter( 'wogh_post_meta', array( $this, 'ignore_post_meta' ), 10, 1 );
162
		// add_filter( 'wogh_pre_import_meta', array( $this, 'ignore_post_meta' ), 10, 1 );
163
		add_filter( 'the_content', array( $this, 'the_content' ) );
164
165
		do_action( 'wogh_boot', $this );
166
	}
167
168
	public function edit_post_link($link, $postID, $context) {
0 ignored issues
show
Unused Code introduced by
The parameter $context is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
169
		if ( ! wp_is_post_revision( $postID ) ) {
170
			$post = new Writing_On_GitHub_Post( $postID, Writing_On_GitHub::$instance->api() );
171
			if ( $post->is_on_github() ) {
172
				return $post->github_edit_url();
173
			}
174
		}
175
176
	    return $link;
177
	}
178
179
	public function ignore_post_meta($meta) {
180
		$ignore_meta_keys = get_option('wogh_ignore_metas');
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after opening bracket; 0 found
Loading history...
Coding Style introduced by
Expected 1 spaces before closing bracket; 0 found
Loading history...
181
		if (empty($ignore_meta_keys)) {
0 ignored issues
show
introduced by
No space after opening parenthesis is prohibited
Loading history...
Coding Style introduced by
Expected 1 spaces after opening bracket; 0 found
Loading history...
Coding Style introduced by
Expected 1 spaces before closing bracket; 0 found
Loading history...
introduced by
No space before closing parenthesis is prohibited
Loading history...
182
			return $meta;
183
		}
184
185
		$keys = preg_split("/\\r\\n|\\r|\\n/", $ignore_meta_keys);
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after opening bracket; 0 found
Loading history...
Coding Style introduced by
Expected 1 spaces before closing bracket; 0 found
Loading history...
186
		if (empty($keys)) {
0 ignored issues
show
introduced by
No space after opening parenthesis is prohibited
Loading history...
Coding Style introduced by
Expected 1 spaces after opening bracket; 0 found
Loading history...
Coding Style introduced by
Expected 1 spaces before closing bracket; 0 found
Loading history...
introduced by
No space before closing parenthesis is prohibited
Loading history...
187
			return $meta;
188
		}
189
		foreach ($keys as $key => $value) {
0 ignored issues
show
introduced by
No space after opening parenthesis is prohibited
Loading history...
introduced by
No space before closing parenthesis is prohibited
Loading history...
190
			$keys[$key] = trim($value);
0 ignored issues
show
introduced by
Array keys should be surrounded by spaces unless they contain a string or an integer.
Loading history...
Coding Style introduced by
Expected 1 spaces after opening bracket; 0 found
Loading history...
Coding Style introduced by
Expected 1 spaces before closing bracket; 0 found
Loading history...
191
		}
192
193
		foreach ($meta as $key => $value) {
0 ignored issues
show
introduced by
No space after opening parenthesis is prohibited
Loading history...
introduced by
No space before closing parenthesis is prohibited
Loading history...
194
			if (in_array($key, $keys)) {
0 ignored issues
show
introduced by
No space after opening parenthesis is prohibited
Loading history...
Coding Style introduced by
Expected 1 spaces after opening bracket; 0 found
Loading history...
Coding Style introduced by
Expected 1 spaces before closing bracket; 0 found
Loading history...
introduced by
No space before closing parenthesis is prohibited
Loading history...
195
				unset($meta[$key]);
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after opening bracket; 0 found
Loading history...
Coding Style introduced by
Expected 1 spaces before closing bracket; 0 found
Loading history...
introduced by
Array keys should be surrounded by spaces unless they contain a string or an integer.
Loading history...
196
			}
197
		}
198
199
		return $meta;
200
	}
201
202
	public function the_content($content) {
203
		$arr = wp_upload_dir();
204
		$baseurl = $arr['baseurl'] . '/writing-on-github';
205
206
		$content = preg_replace_callback(
207
			'/(<img [^>]*?src=[\'"])\s*(\/images\/[^\s#]\S+)\s*([\'"][^>]*?>)/',
208 View Code Duplication
			function($matchs) use ($baseurl) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
209
				$url = $baseurl . $matchs[2];
210
				return "${matchs[1]}$url${matchs[3]}";
211
			},
212
			$content
213
		);
214
215
		$content = preg_replace_callback(
216
			'/(<a [^>]*?href=[\'"])\s*(\/images\/[^\s#]\S+)\s*([\'"][^>]*?>)/',
217 View Code Duplication
			function($matchs) use ($baseurl) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
218
				$url = $baseurl . $matchs[2];
219
				return "${matchs[1]}$url${matchs[3]}";
220
			},
221
			$content
222
		);
223
		return $content;
224
	}
225
226
	/**
227
	 * Init i18n files
228
	 */
229
	public function l10n() {
230
		load_plugin_textdomain( self::$text_domain );
231
	}
232
233
	/**
234
	 * Sets and kicks off the export cronjob
235
	 */
236
	public function start_export( $force = false ) {
237
		$this->start_cron( 'export', $force );
238
	}
239
240
	/**
241
	 * Sets and kicks off the import cronjob
242
	 */
243
	public function start_import() {
244
		$this->start_cron( 'import' );
245
	}
246
247
	/**
248
	 * Enables the admin notice on initial activation
249
	 */
250
	public function activate() {
251
		if ( 'yes' !== get_option( '_wogh_fully_exported' ) ) {
252
			set_transient( '_wogh_activated', 'yes' );
253
		}
254
	}
255
256
	/**
257
	 * Displays the activation admin notice
258
	 */
259
	public function activation_notice() {
260
		if ( ! get_transient( '_wogh_activated' ) ) {
261
			return;
262
		}
263
264
		delete_transient( '_wogh_activated' );
265
266
		?><div class="updated">
267
			<p>
268
				<?php
269
					printf(
270
						__( 'To set up your site to sync with GitHub, update your <a href="%s">settings</a> and click "Export to GitHub."', 'writing-on-github' ),
271
						admin_url( 'options-general.php?page=' . static::$text_domain)
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces before closing bracket; 0 found
Loading history...
introduced by
Expected next thing to be a escaping function, not 'static'
Loading history...
272
					);
273
				?>
274
			</p>
275
		</div><?php
276
	}
277
278
	/**
279
	 * Get the Controller object.
280
	 *
281
	 * @return Writing_On_GitHub_Controller
282
	 */
283
	public function controller() {
284
		return $this->controller;
285
	}
286
287
	/**
288
	 * Lazy-load the CLI object.
289
	 *
290
	 * @return Writing_On_GitHub_CLI
291
	 */
292
	public function cli() {
293
		if ( ! $this->cli ) {
294
			$this->cli = new Writing_On_GitHub_CLI;
295
		}
296
297
		return $this->cli;
298
	}
299
300
	/**
301
	 * Lazy-load the Request object.
302
	 *
303
	 * @return Writing_On_GitHub_Request
304
	 */
305
	public function request() {
306
		if ( ! $this->request ) {
307
			$this->request = new Writing_On_GitHub_Request( $this );
308
		}
309
310
		return $this->request;
311
	}
312
313
	/**
314
	 * Lazy-load the Response object.
315
	 *
316
	 * @return Writing_On_GitHub_Response
317
	 */
318
	public function response() {
319
		if ( ! $this->response ) {
320
			$this->response = new Writing_On_GitHub_Response( $this );
321
		}
322
323
		return $this->response;
324
	}
325
326
	/**
327
	 * Lazy-load the Api object.
328
	 *
329
	 * @return Writing_On_GitHub_Api
330
	 */
331
	public function api() {
332
		if ( ! $this->api ) {
333
			$this->api = new Writing_On_GitHub_Api( $this );
334
		}
335
336
		return $this->api;
337
	}
338
339
	/**
340
	 * Lazy-load the Import object.
341
	 *
342
	 * @return Writing_On_GitHub_Import
343
	 */
344
	public function import() {
345
		if ( ! $this->import ) {
346
			$this->import = new Writing_On_GitHub_Import( $this );
347
		}
348
349
		return $this->import;
350
	}
351
352
	/**
353
	 * Lazy-load the Export object.
354
	 *
355
	 * @return Writing_On_GitHub_Export
356
	 */
357
	public function export() {
358
		if ( ! $this->export ) {
359
			$this->export = new Writing_On_GitHub_Export( $this );
360
		}
361
362
		return $this->export;
363
	}
364
365
	/**
366
	 * Lazy-load the Semaphore object.
367
	 *
368
	 * @return Writing_On_GitHub_Semaphore
369
	 */
370
	public function semaphore() {
371
		if ( ! $this->semaphore ) {
372
			$this->semaphore = new Writing_On_GitHub_Semaphore;
373
		}
374
375
		return $this->semaphore;
376
	}
377
378
	/**
379
	 * Lazy-load the Database object.
380
	 *
381
	 * @return Writing_On_GitHub_Database
382
	 */
383
	public function database() {
384
		if ( ! $this->database ) {
385
			$this->database = new Writing_On_GitHub_Database( $this );
386
		}
387
388
		return $this->database;
389
	}
390
391
	/**
392
	 * Print to WP_CLI if in CLI environment or
393
	 * write to debug.log if WP_DEBUG is enabled
394
	 * @source http://www.stumiller.me/sending-output-to-the-wordpress-debug-log/
395
	 *
396
	 * @param mixed $msg
397
	 * @param string $write
398
	 */
399
	public static function write_log( $msg, $write = 'line' ) {
400
		if ( defined( 'WP_CLI' ) && WP_CLI ) {
401
			if ( is_array( $msg ) || is_object( $msg ) ) {
402
				WP_CLI::print_value( $msg );
403
			} else {
404
				WP_CLI::$write( $msg );
405
			}
406
		} elseif ( true === WP_DEBUG ) {
407
			if ( is_array( $msg ) || is_object( $msg ) ) {
408
				error_log( print_r( $msg, true ) );
0 ignored issues
show
introduced by
The use of function print_r() is discouraged
Loading history...
409
			} else {
410
				error_log( $msg );
411
			}
412
		}
413
	}
414
415
	/**
416
	 * Kicks of an import or export cronjob.
417
	 *
418
     * @param bool   $force
419
     * @param string $type
420
     */
421
	protected function start_cron( $type, $force = false ) {
422
		update_option( '_wogh_' . $type . '_started', 'yes' );
423
		$user_id = get_current_user_id();
424
		wp_schedule_single_event( time(), 'wogh_' . $type . '', array( $user_id, $force ) );
425
		spawn_cron();
426
	}
427
}
428