Completed
Push — master ( eaef00...15db70 )
by Dennis
01:23
created

MslsPlugin::path()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
nc 2
dl 0
loc 3
c 0
b 0
f 0
cc 2
nop 0
rs 10
1
<?php
2
/**
3
 * MslsPlugin
4
 * @author Dennis Ploetner <[email protected]>
5
 * @since 0.9.8
6
 */
7
8
namespace lloc\Msls;
9
10
/**
11
 * Provides functionalities for general hooks and activation/deactivation
12
 *
13
 * @package Msls
14
 */
15
class MslsPlugin {
16
17
	/**
18
	 * Injected MslsOptions object
19
	 *
20
	 * @var MslsOptions
21
	 */
22
	protected $options;
23
24
	/**
25
	 * MslsPlugin constructor.
26
	 *
27
	 * @param MslsOptions $options
28
	 */
29
	public function __construct( MslsOptions $options ) {
30
		$this->options = $options;
31
	}
32
33
	/**
34
	 * Factory
35
	 *
36
	 * @codeCoverageIgnore
37
	 *
38
	 * @return MslsPlugin
39
	 */
40
	public static function init() {
41
		$options = MslsOptions::instance();
42
		$obj     = new self( $options );
43
44
		add_action( 'plugins_loaded', [ $obj, 'init_i18n_support' ] );
45
46
		register_activation_hook(  self::file(), [ $obj, 'activate' ] );
47
48
		if ( function_exists( 'is_multisite' ) && is_multisite() ) {
49
			add_action( 'wp_head', [ __CLASS__, 'print_alternate_links' ] );
50
			add_filter( 'msls_get_output', [ __CLASS__, 'get_output' ] );
51
52
			add_action( 'widgets_init', [ $obj, 'init_widget' ] );
53
			add_filter( 'the_content', [ $obj, 'content_filter' ] );
54
55
			if ( function_exists( 'register_block_type' ) ) {
56
				add_action( 'init', [ $obj, 'block_init' ] );
57
			}
58
59
			\lloc\Msls\ContentImport\Service::instance()->register();
60
61
			if ( is_admin() ) {
62
				add_action( 'admin_menu', [ $obj, 'admin_menu' ] );
63
64
				add_action( 'admin_menu', [ MslsAdmin::class, 'init' ] );
65
				add_action( 'load-post.php', [ MslsMetaBox::class, 'init' ] );
66
				add_action( 'load-post-new.php', [ MslsMetaBox::class, 'init' ] );
67
				add_action( 'load-edit.php', [ MslsCustomColumn::class, 'init' ] );
68
				add_action( 'load-edit.php', [ MslsCustomFilter::class, 'init' ] );
69
70
				add_action( 'load-edit-tags.php', [ MslsCustomColumnTaxonomy::class, 'init' ] );
71
				add_action( 'load-edit-tags.php', [ MslsPostTag::class, 'init' ] );
72
73
				if ( filter_has_var( INPUT_POST, 'action' ) ) {
74
					$action = filter_input( INPUT_POST, 'action', FILTER_SANITIZE_STRING );
75
76
					if ( 'add-tag' === $action ) {
77
						add_action( 'admin_init', [ MslsPostTag::class, 'init' ] );
78
					} elseif ( 'inline-save' === $action ) {
79
						add_action( 'admin_init', [ MslsCustomColumn::class, 'init' ] );
80
					} elseif ( 'inline-save-tax' === $action ) {
81
						add_action( 'admin_init', [ MslsCustomColumnTaxonomy::class, 'init' ] );
82
					}
83
				}
84
85
				add_action( 'wp_ajax_suggest_posts', [ MslsMetaBox::class, 'suggest' ] );
86
				add_action( 'wp_ajax_suggest_terms', [ MslsPostTag::class, 'suggest' ] );
87
			}
88
		} else {
89
			add_action( 'admin_notices', function () {
90
				self::message_handler(
91
					__( 'The Multisite Language Switcher needs the activation of the multisite-feature for working properly. Please read <a onclick="window.open(this.href); return false;" href="http://codex.wordpress.org/Create_A_Network">this post</a> if you don\'t know the meaning.', 'multisite-language-switcher' )
92
				);
93
			} );
94
		}
95
96
		return $obj;
97
	}
98
99
	/**
100
	 * Gets MslsOutput object
101
	 *
102
	 * @return MslsOutput
103
	 */
104
	public static function get_output() {
105
		static $obj = null;
106
107
		if ( is_null( $obj ) ) {
108
			$obj = MslsOutput::init();
109
		}
110
111
		return $obj;
112
	}
113
114
115
	/**
116
	 * Callback for action wp_head
117
	 */
118
	public static function print_alternate_links() {
119
		echo self::get_output()->get_alternate_links(), PHP_EOL;
120
	}
121
122
	/**
123
	 * Filter for the_content()
124
	 *
125
	 * @param string $content
126
	 *
127
	 * @return string
128
	 */
129
	function content_filter( $content ) {
130
		if ( ! is_front_page() && is_singular() ) {
131
			$options = $this->options;
132
133
			if ( $options->is_content_filter() ) {
134
				$content .= $this->filter_string();
135
			}
136
		}
137
138
		return $content;
139
	}
140
141
	/**
142
	 * Create filterstring for msls_content_filter()
143
	 *
144
	 * @param string $pref
145
	 * @param string $post
146
	 *
147
	 * @return string
148
	 */
149
	function filter_string( $pref = '<p id="msls">', $post = '</p>' ) {
150
		$obj    = MslsOutput::init();
151
		$links  = $obj->get( 1, true, true );
152
		$output = __( 'This post is also available in %s.', 'multisite-language-switcher' );
153
154
		if ( has_filter( 'msls_filter_string' ) ) {
155
			/**
156
			 * Overrides the string for the output of the translation hint
157
			 *
158
			 * @param string $output
159
			 * @param array $links
160
			 *
161
			 * @since 1.0
162
			 */
163
			$output = apply_filters( 'msls_filter_string', $output, $links );
164
		} else {
165
			$output = '';
166
167
			if ( count( $links ) > 1 ) {
168
				$last   = array_pop( $links );
169
				$output = sprintf(
170
					$output,
171
					sprintf(
172
						__( '%s and %s', 'multisite-language-switcher' ),
173
						implode( ', ', $links ),
174
						$last
175
					)
176
				);
177
			} elseif ( 1 == count( $links ) ) {
178
				$output = sprintf(
179
					$output,
180
					$links[0]
181
				);
182
			}
183
		}
184
185
		return ! empty( $output ) ? $pref . $output . $post : '';
186
	}
187
188
	/**
189
	 * Register block and shortcode.
190
	 */
191
	public function block_init() {
192
		if ( ! $this->options->is_excluded() ) {
193
			$handle   = 'msls-widget-block';
194
			$callback = [ $this, 'block_render' ];
195
196
			wp_register_script(
197
				$handle,
198
				self::plugins_url( 'js/msls-widget-block.js' ),
199
				[ 'wp-blocks', 'wp-element', 'wp-components', 'wp-editor' ]
200
			);
201
202
			register_block_type( 'lloc/msls-widget-block', [
203
				'attributes'      => [ 'title' => [ 'type' => 'string' ] ],
204
				'editor_script'   => $handle,
205
				'render_callback' => $callback,
206
			] );
207
208
			add_shortcode( 'sc_msls_widget', $callback );
209
210
			return true;
211
		}
212
213
		return false;
214
	}
215
216
	/**
217
	 * Loads styles and some js if needed
218
	 *
219
	 * The method returns true if JS is loaded or false if not
220
	 *
221
	 * @return boolean
222
	 */
223
	public function admin_menu() {
224
		$ver     = defined( 'MSLS_PLUGIN_VERSION' ) ? constant( 'MSLS_PLUGIN_VERSION' ) : false;
225
		$postfix = defined( 'SCRIPT_DEBUG' ) && constant( 'SCRIPT_DEBUG' ) ? '' : '.min';
226
227
		wp_enqueue_style( 'msls-styles', self::plugins_url( 'css/msls.css' ), [], $ver );
228
		wp_enqueue_style( 'msls-flags', self::plugins_url( 'css-flags/css/flag-icon.min.css' ), [], $ver );
229
230
		if ( $this->options->activate_autocomplete ) {
231
			wp_enqueue_script( 'msls-autocomplete', self::plugins_url( "js/msls{$postfix}.js" ), [ 'jquery-ui-autocomplete' ], $ver );
232
233
			return true;
234
		}
235
236
		return false;
237
	}
238
239
	/**
240
	 * Wrapper for plugins_url
241
	 *
242
	 * @param string $path
243
	 *
244
	 * @return string
245
	 */
246
	public static function plugins_url( string $path ): string {
247
		return plugins_url( $path, self::file() );
248
	}
249
250
	/**
251
	 * Wrapper for plugin_dir_path
252
	 *
253
	 * @param string $path
254
	 *
255
	 * @return string
256
	 */
257
	public static function plugin_dir_path( string $path ): string {
258
		return plugin_dir_path( self::file() ) . $path;
259
	}
260
261
	/**
262
	 * @param string $path
263
	 *
264
	 * @return string
265
	 */
266
	public static function dirname( string $path ): string {
267
		return dirname( self::path() ) . $path;
268
	}
269
270
	/**
271
	 * @return string
272
	 */
273
	public static function file(): string {
274
		return defined( 'MSLS_PLUGIN__FILE__' ) ? constant( 'MSLS_PLUGIN__FILE__' ) : '';
275
	}
276
277
	/**
278
	 * @return string
279
	 */
280
	public static function path(): string {
281
		return defined( 'MSLS_PLUGIN_PATH' ) ? constant( 'MSLS_PLUGIN_PATH' ) : '';
282
	}
283
284
	/**
285
	 * Register widget
286
	 *
287
	 * The widget will only be registered if the current blog is not
288
	 * excluded in the configuration of the plugin.
289
	 * @return boolean
290
	 */
291
	public function init_widget() {
292
		if ( ! $this->options->is_excluded() ) {
293
			register_widget( MslsWidget::class );
294
295
			return true;
296
		}
297
298
		return false;
299
	}
300
301
	/**
302
	 * Render widget output
303
	 *
304
	 * @return string
305
	 */
306
	public function block_render() {
307
		if ( ! $this->init_widget() ) {
308
			return '';
309
		}
310
311
		ob_start();
312
		the_widget( MslsWidget::class );
313
		$output = ob_get_clean();
314
315
		return $output;
316
	}
317
318
	/**
319
	 * Load textdomain
320
	 *
321
	 * The method should be executed always on init because we have some
322
	 * translatable string in the frontend too.
323
	 *
324
	 * @return boolean
325
	 */
326
	public function init_i18n_support() {
327
		return load_plugin_textdomain( 'multisite-language-switcher', false, self::dirname( '/languages/' ) );
328
	}
329
330
	/**
331
	 * Message handler
332
	 *
333
	 * Prints a message box to the screen.
334
	 *
335
	 * @param string $message
336
	 * @param string $css_class
337
	 *
338
	 * @return boolean
339
	 */
340
	public static function message_handler( $message, $css_class = 'error' ) {
341
		if ( ! empty( $message ) ) {
342
			printf( '<div id="msls-warning" class="%s"><p>%s</p></div>', $css_class, $message );
343
344
			return true;
345
		}
346
347
		return false;
348
	}
349
350
	/**
351
	 * Activate plugin
352
	 */
353
	public static function activate() {
354
		register_uninstall_hook(  self::file(), [ __CLASS__, 'uninstall' ] );
355
	}
356
357
	/**
358
	 * Uninstall plugin
359
	 *
360
	 * The plugin data in all blogs of the current network will be
361
	 * deleted after the uninstall procedure.
362
	 *
363
	 * @return boolean
364
	 */
365
	public static function uninstall() {
366
		/**
367
		 * We want to be sure that the user has not deactivated the
368
		 * multisite because we need to use switch_to_blog and
369
		 * restore_current_blog
370
		 */
371
		if ( function_exists( 'is_multisite' ) && is_multisite() ) {
372
			$cache = MslsSqlCacher::init( __CLASS__ )->set_params( __METHOD__ );
373
374
			$blogs = $cache->get_results(
375
				$cache->prepare(
376
					"SELECT blog_id FROM {$cache->blogs} WHERE blog_id != %d AND site_id = %d",
377
					$cache->blogid,
378
					$cache->siteid
379
				)
380
			);
381
382
			foreach ( $blogs as $blog ) {
383
				switch_to_blog( $blog->blog_id );
384
				self::cleanup();
385
				restore_current_blog();
386
			}
387
		}
388
389
		return self::cleanup();
390
	}
391
392
	/**
393
	 * Cleanup the options
394
	 *
395
	 * Removes all values of the current blogs which are stored in the
396
	 * options-table and returns true if it was successful.
397
	 *
398
	 * @return boolean
399
	 */
400
	public static function cleanup() {
401
		if ( delete_option( 'msls' ) ) {
402
			$cache = MslsSqlCacher::init( __CLASS__ )->set_params( __METHOD__ );
403
			$sql   = $cache->prepare(
404
				"DELETE FROM {$cache->options} WHERE option_name LIKE %s",
405
				'msls_%'
406
			);
407
408
			return (bool) $cache->query( $sql );
409
		}
410
411
		return false;
412
	}
413
414
	/**
415
	 * Get specific vars from $_POST and $_GET in a safe way
416
	 *
417
	 * @param array $list
418
	 *
419
	 * @return array
420
	 */
421
	public function get_superglobals( array $list ) {
422
		$arr = [];
423
424
		foreach ( $list as $var ) {
425
			$arr[ $var ] = '';
426
427
			if ( filter_has_var( INPUT_POST, $var ) ) {
428
				$arr[ $var ] = filter_input( INPUT_POST, $var );
429
			} elseif ( filter_has_var( INPUT_GET, $var ) ) {
430
				$arr[ $var ] = filter_input( INPUT_GET, $var );
431
			}
432
		}
433
434
		return $arr;
435
	}
436
437
}
438