GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Completed
Push — master ( e4dd68...b0f362 )
by Brad
07:12 queued 04:10
created

FooGallery_Extensions_API::is_active()   C

Complexity

Conditions 8
Paths 7

Size

Total Lines 42
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 8
eloc 14
nc 7
nop 2
dl 0
loc 42
rs 5.3846
c 0
b 0
f 0
1
<?php
2
/**
3
 * @TODO
4
 */
5
6
if ( ! class_exists( 'FooGallery_Extensions_API' ) ) {
7
8
	define( 'FOOGALLERY_EXTENSIONS_ENDPOINT', 'https://raw.githubusercontent.com/fooplugins/foogallery-extensions/master/extensions.json' );
9
	define( 'FOOGALLERY_EXTENSIONS_FUTURE_ENDPOINT', 'https://raw.githubusercontent.com/fooplugins/foogallery-extensions/future/extensions.json' );
10
	//define( 'FOOGALLERY_EXTENSIONS_ENDPOINT', FOOGALLERY_URL . 'extensions/extensions.json.js' );
0 ignored issues
show
Unused Code Comprehensibility introduced by
43% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
11
	define( 'FOOGALLERY_EXTENSIONS_LOADING_ERRORS', 'foogallery_extensions_loading_errors' );
12
	define( 'FOOGALLERY_EXTENSIONS_LOADING_ERRORS_RESPONSE', 'foogallery_extensions_loading_errors_response' );
13
	define( 'FOOGALLERY_EXTENSIONS_AVAILABLE_TRANSIENT_KEY', 'foogallery_extensions_available' );
14
	define( 'FOOGALLERY_EXTENSIONS_MESSAGE_TRANSIENT_KEY', 'foogallery_extensions_message' );
15
	define( 'FOOGALLERY_EXTENSIONS_ACTIVATED_OPTIONS_KEY', 'foogallery_extensions_activated' );
16
	define( 'FOOGALLERY_EXTENSIONS_ERRORS_OPTIONS_KEY', 'foogallery_extensions_errors' );
17
	define( 'FOOGALLERY_EXTENSIONS_SLUGS_OPTIONS_KEY', 'foogallery_extensions_slugs' );
18
	define( 'FOOGALLERY_EXTENSIONS_AUTO_ACTIVATED_OPTIONS_KEY', 'foogallery_extensions_auto_activated' );
19
20
	/**
21
	 * Foogalolery Extensions Manager Class
22
	 * Class FooGallery_Extensions_API
23
	 */
24
	class FooGallery_Extensions_API {
0 ignored issues
show
Coding Style Compatibility introduced by
PSR1 recommends that each class must be in a namespace of at least one level to avoid collisions.

You can fix this by adding a namespace to your class:

namespace YourVendor;

class YourClass { }

When choosing a vendor namespace, try to pick something that is not too generic to avoid conflicts with other libraries.

Loading history...
25
26
		/**
27
		 * Internal list of all extensions
28
		 * @var array
29
		 */
30
		private $extensions = false;
31
32
		/**
33
		 * Internal list of all extension slugs
34
		 * @var array
35
		 */
36
		private $extension_slugs = false;
37
38
		/**
39
		 * Extension API constructor
40
		 * @param bool $load
41
		 */
42
		function __construct( $load = false ) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
43
			if ( $load ) {
44
				$this->load_available_extensions();
45
			}
46
		}
47
48
		/**
49
		 * Returns true if there were errors loading extensions
50
		 * @return bool
51
		 */
52
		public function has_extension_loading_errors() {
53
			return get_option( FOOGALLERY_EXTENSIONS_LOADING_ERRORS );
54
		}
55
56
		/**
57
		 * Returns the actual reposnse when there were errors trying to fetch all extensions
58
		 * @return mixed
59
		 */
60
		public function get_extension_loading_errors_response() {
61
			return get_option( FOOGALLERY_EXTENSIONS_LOADING_ERRORS_RESPONSE );
62
		}
63
64
		/**
65
		 * Get back the extension endpoint based on a setting
66
		 */
67
		public function get_extensions_endpoint() {
68
			if ( 'on' === foogallery_get_setting( 'use_future_endpoint' ) ) {
69
				$extension_url = FOOGALLERY_EXTENSIONS_FUTURE_ENDPOINT;
70
			} else {
71
				$extension_url = FOOGALLERY_EXTENSIONS_ENDPOINT;
72
			}
73
			//make sure we always get the latest version!
74
			$extension_url .= '?v=' . wp_generate_password();
75
76
			return apply_filters('foogallery_extension_api_endpoint', $extension_url );
77
		}
78
79
		/**
80
		 * Reset all previous errors
81
		 */
82
		public function reset_errors() {
83
			delete_option( FOOGALLERY_EXTENSIONS_LOADING_ERRORS );
84
			delete_option( FOOGALLERY_EXTENSIONS_LOADING_ERRORS_RESPONSE );
85
		}
86
87
		/**
88
		 * Load all available extensions from the public endpoint and store in a transient for later use
89
		 */
90
		private function load_available_extensions() {
91
			if ( false === ( $this->extensions = get_transient( FOOGALLERY_EXTENSIONS_AVAILABLE_TRANSIENT_KEY ) ) ) {
92
93
				//clear any previous state
94
				$this->reset_errors();
95
				$this->extensions = null;
0 ignored issues
show
Documentation Bug introduced by
It seems like null of type null is incompatible with the declared type array of property $extensions.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
96
				$expires = 60 * 60 * 24; //1 day
97
98
				$extension_url = $this->get_extensions_endpoint();
99
100
				//fetch the data from our public list of extensions hosted on github
101
				$response = wp_remote_get( $extension_url, array( 'sslverify' => false ) );
102
103
				if( ! is_wp_error( $response ) ) {
104
105
					if ( $response['response']['code'] == 200 ) {
106
						$this->extensions = @json_decode( $response['body'], true );
107
108
						//if we got a valid list of extensions then calculate which are new and cache the result
109
						if ( is_array( $this->extensions ) ) {
110
							$this->determine_new_extensions( );
111
							$this->save_slugs_for_new_calculations();
112
						}
113
					}
114
				}
115
116
				if ( ! is_array( $this->extensions ) ) {
117
					//there was some problem getting a list of extensions. Could be a network error, or the extension json was malformed
118
					update_option( FOOGALLERY_EXTENSIONS_LOADING_ERRORS, true );
119
					update_option( FOOGALLERY_EXTENSIONS_LOADING_ERRORS_RESPONSE, $response );
120
					$this->extensions = $this->default_extenions_in_case_of_emergency();
121
					$expires = 5 * 60; //Only cache for 5 minutes if there are errors.
122
				}
123
124
				//Cache the result
125
				set_transient( FOOGALLERY_EXTENSIONS_AVAILABLE_TRANSIENT_KEY, $this->extensions, $expires );
126
			}
127
		}
128
129
		/**
130
		 * Get an array of default extensions.
131
		 * If for some reason, the extension list cannot be fetched from our public listing, we need to return the defaults so that the plugin can function offline
132
		 *
133
		 * @return array
134
		 */
135
		private function default_extenions_in_case_of_emergency() {
136
			$extensions = array();
137
138
			$extensions[] =	array(
139
				'slug' => 'albums',
140
				'class' => 'FooGallery_Albums_Extension',
141
				'title' => 'Albums',
142
				'categories' =>	array( 'Featured', 'Free' ),
143
				'description' => 'Group your galleries into albums. Boom!',
144
				'html' => 'Group your galleries into albums. Boom!',
145
				'author' => 'FooPlugins',
146
				'author_url' => 'http://fooplugins.com',
147
				'thumbnail' => '/extensions/albums/foogallery-albums.png',
148
				'tags' => array( 'functionality' ),
149
				'source' => 'bundled'
150
			);
151
152
			//FooBox premium
153
			$extensions[] = array(
154
				'slug' => 'foobox',
155
				'class' => 'FooGallery_FooBox_Extension',
156
				'categories' => array( 'Featured', 'Premium' ),
157
				'file' => 'foobox-free.php',
158
				'title' => 'FooBox PRO',
159
				'description' => 'The best lightbox for WordPress just got even better!',
160
				'price' => '$27',
161
				'author' => 'FooPlugins',
162
				'author_url' => 'http://fooplugins.com',
163
				'thumbnail' => '/assets/extension_bg.png',
164
				'tags' => array( 'premium', 'lightbox', ),
165
				'source' => 'fooplugins',
166
				'download_button' =>
167
					array(
168
						'text' => 'Buy - $27',
169
						'target' => '_blank',
170
						'href' => 'http://fooplugins.com/plugins/foobox',
171
						'confirm' => false,
172
					),
173
				'activated_by_default' => true,
174
				'minimum_version' => '2.3.2',
175
				'remove_if_active' => array('foobox-image-lightbox')
176
			);
177
178
			//FooBox lightbox
179
			$extensions[] = array (
180
				'slug' => 'foobox-image-lightbox',
181
				'class' => 'FooGallery_FooBox_Free_Extension',
182
				'categories' => array( 'Featured', 'Free', ),
183
				'file' => 'foobox-free.php',
184
				'title' => 'FooBox FREE',
185
				'description' => 'The best lightbox for WordPress. Free',
186
				'author' => 'FooPlugins',
187
				'author_url' => 'http://fooplugins.com',
188
				'thumbnail' => '/assets/extension_bg.png',
189
				'tags' => array( 'lightbox' ),
190
				'source' => 'repo',
191
				'activated_by_default' => true,
192
				'minimum_version' => '1.0.2.1',
193
			);
194
195
			//The NextGen importer
196
			$extensions[] = array(
197
				'slug' => 'nextgen',
198
				'class' => 'FooGallery_Nextgen_Gallery_Importer_Extension',
199
				'categories' => array( 'Free' ),
200
				'title' => 'NextGen Importer',
201
				'description' => 'Imports all your existing NextGen galleries',
202
				'author' => 'FooPlugins',
203
				'author_url' => 'http://fooplugins.com',
204
				'thumbnail' => '/assets/extension_bg.png',
205
				'tags' => array( 'tools' ),
206
				'source' => 'bundled',
207
			);
208
209
			return $extensions;
210
		}
211
212
		/**
213
		 * @TODO
214
		 */
215
		private function determine_new_extensions() {
216
			$previous_slugs = get_option( FOOGALLERY_EXTENSIONS_SLUGS_OPTIONS_KEY );
217
			if ( $previous_slugs ) {
218
				//only do something if we have a previously saved array
219
				foreach ( $this->extensions as &$extension ) {
220
					if ( ! in_array( $extension['slug'], $previous_slugs ) ) {
221
						if ( ! isset( $extension['tags'] ) ) {
222
							$extension['tags'] = array();
223
						}
224
						array_unshift( $extension['tags'] , __( 'new', 'foogallery' ) );
225
					}
226
				}
227
			}
228
		}
229
230
		/**
231
		 * @TODO
232
		 */
233
		private function save_slugs_for_new_calculations() {
234
			if ( is_array( $this->extensions ) ) {
235
				$slugs = array();
236
				foreach ( $this->extensions as $extension ) {
237
					$slugs[] = $extension['slug'];
238
				}
239
				if ( count( $slugs ) > 0 ) {
240
					update_option( FOOGALLERY_EXTENSIONS_SLUGS_OPTIONS_KEY, $slugs );
241
				}
242
			}
243
		}
244
245
		/**
246
		 * Clears the cached list of extensions
247
		 */
248
		public function clear_cached_extensions() {
249
			delete_transient( FOOGALLERY_EXTENSIONS_AVAILABLE_TRANSIENT_KEY );
250
		}
251
252
		/**
253
		 * Reload the extensions from the public endpoint
254
		 */
255
		public function reload() {
256
			$this->clear_cached_extensions();
257
			$this->load_available_extensions();
258
		}
259
260
		/**
261
		 * Get all loaded extensions
262
		 * @return array
263
		 */
264
		function get_all() {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
265
266
			//check if we need to load
267
			if ( false === $this->extensions ) {
268
				$this->load_available_extensions();
269
			}
270
271
			//get any extra extensions from plugins
272
			$extra_extensions = apply_filters( 'foogallery_available_extensions', array() );
273
274
			if ( count( $extra_extensions ) > 0 ) {
275
				//get a list of slugs so we can determine duplicates!
276
				$this->extension_slugs = array();
277
				foreach ( $this->extensions as $extension ) {
278
					$this->extension_slugs[] = $extension['slug'];
279
				}
280
281
				//only add if not a duplicate
282
				foreach ( $extra_extensions as $extension ) {
283
					if ( ! in_array( $extension['slug'], $this->extension_slugs ) ) {
284
						$this->extensions[] = $extension;
285
					}
286
				}
287
			}
288
289
			return $this->extensions;
290
		}
291
292
293
		/**
294
		 * return a list of all extensions for the extension view.
295
		 * This list could be changed based on other plugin
296
		 */
297
		function get_all_for_view() {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
298
			$all_extensions = $this->get_all();
299
			$extensions = array();
300
			$active_extensions = array();
301
302
			//add all extensions to an array using the slug as the array key
303
			foreach ( $all_extensions as &$extension ) {
304
				$active = $this->is_active( $extension['slug'], true );
305
				$extension['downloaded'] = $active || $this->is_downloaded( $extension );
306
				$extension['is_active'] = $active;
307
				$extension['has_errors'] = $this->has_errors( $extension['slug'] );
308
309
				//build up a list of active extensions
310
				if ( $active ) {
311
					$active_extensions[$extension['slug']] = $extension;
312
				}
313
314
				//remove any bundled extensions that are activated_by_default = true
315
				if ( isset( $extension['activated_by_default'] ) &&
0 ignored issues
show
Unused Code introduced by
This if statement is empty and can be removed.

This check looks for the bodies of if statements that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.

These if bodies can be removed. If you have an empty if but statements in the else branch, consider inverting the condition.

if (rand(1, 6) > 3) {
//print "Check failed";
} else {
    print "Check succeeded";
}

could be turned into

if (rand(1, 6) <= 3) {
    print "Check succeeded";
}

This is much more concise to read.

Loading history...
316
					true === $extension['activated_by_default'] &&
317
					isset( $extension['source'] ) &&
318
					'bundled' === $extension['source']) {
319
					//do not include a bundled extension that is activated by default
320
				} else {
321
					$extensions[ $extension['slug'] ] = $extension;
322
				}
323
			}
324
325
			//loop through all active extensions and remove any other extensions if required based on the 'remove_if_active' property
326
			foreach ( $active_extensions as $active_extension_slug => $active_extension ) {
327
				//check if we need to remove any other extensions from the list
328
				if ( isset( $active_extension['remove_if_active'] ) ) {
329
330
					foreach ( $active_extension['remove_if_active'] as $extension_slug_to_remove ) {
331
						if ( array_key_exists( $extension_slug_to_remove, $extensions ) ) {
332
							unset( $extensions[ $extension_slug_to_remove ] );
333
						}
334
					}
335
				}
336
			}
337
338
			$extensions = apply_filters( 'foogallery_extensions_for_view', $extensions );
339
340
			return $extensions;
341
		}
342
		/**
343
		 * Get all loaded extensions slugs
344
		 * @return array
345
		 */
346
		function get_all_slugs() {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
347
			//load all extensions first!
348
			$this->get_all();
349
350
			return $this->extension_slugs;
351
		}
352
353
		/**
354
		 * Returns a distinct array of categories that are used in the extensions
355
		 * @return mixed
356
		 */
357
		function get_all_categories() {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
358
			$categories['all'] = array(
0 ignored issues
show
Coding Style Comprehensibility introduced by
$categories was never initialized. Although not strictly required by PHP, it is generally a good practice to add $categories = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
359
				'name' => __( 'All', 'foogallery' ),
360
			);
361
			$categories['activated'] = array(
362
				'name' => __( 'Active', 'foogallery' ),
363
			);
364
			$active = 0;
365
			foreach ( $this->get_all() as $extension ) {
366
				if ( $this->is_active( $extension['slug'] ) ) {
367
					$active++;
368
				}
369
				$category_names = $extension['categories'];
370
				foreach ( $category_names as $category_name ) {
371
					$category_slug = foo_convert_to_key( $category_name );
372
373
					if ( ! array_key_exists( $category_slug, $categories ) ) {
374
						$categories[ $category_slug ] = array(
375
							'name'  => $category_name,
376
						);
377
					}
378
				}
379
			}
380
			$categories['build_your_own'] = array(
381
				'name' => __( 'Build Your Own', 'foogallery' )
382
			);
383
			return apply_filters( 'foogallery_extension_categories', $categories );
384
		}
385
386
		/**
387
		 * @TODO
388
		 * @param $slug
389
		 *
390
		 * @return bool
391
		 */
392
		public function get_extension( $slug ) {
393
			foreach ( $this->get_all() as $extension ) {
394
				if ( $extension['slug'] === $slug ) {
395
					return $extension;
396
				}
397
			}
398
			return false;
399
		}
400
401
		/**
402
		 * @TODO
403
		 * @param $file
404
		 *
405
		 * @return bool
406
		 */
407
		public function get_extension_by_file( $file ) {
408
			$file = basename( $file ); //normalize to just the filename
409
410
			foreach ( $this->get_all() as $extension ) {
411
				if ( foo_safe_get( $extension, 'file' ) === $file ) {
412
					return $extension;
413
				}
414
			}
415
			return false;
416
		}
417
418
		/**
419
		 * @TODO
420
		 * @param      $slug
421
		 *
422
		 * @return bool
423
		 */
424
		public function is_active( $slug, $perform_active_check = false ) {
425
			$active_extensions = $this->get_active_extensions();
426
			if ( array_key_exists( $slug, $active_extensions ) ) {
427
				//it has been previously activated through the extensions page
428
				return true;
429
			}
430
431
			if ( $perform_active_check ) {
432
				$extension = $this->get_extension( $slug );
433
434
				//if we have an 'plugin_active_class' attribute and that class exists, it means our plugin must be active
435
				if ( isset( $extension['plugin_active_class'] ) ) {
436
					if ( class_exists( $extension['plugin_active_class'] ) ) {
437
						return true;
438
					}
439
				}
440
441
				//if we cannot find the extension class in memory, then check to see if the extension plugin is activated
442
				if ( isset( $extension['perform_plugin_active_check'] ) && true === $extension['perform_plugin_active_check'] &&
443
					isset( $extension['file'] ) ) {
444
					$plugin = $this->find_active_wordpress_plugin( $extension );
445
446
					return $plugin !== false;
447
				}
448
			}
449
450
			return false;
451
452
//			global $foogallery_extensions;
0 ignored issues
show
Unused Code Comprehensibility introduced by
44% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
453
//
454
//			//first check if the extension class was loaded into memory
455
//			if ( $foogallery_extensions ) {
456
//				if ( array_key_exists( $slug, $foogallery_extensions ) ) {
457
//					return true;
458
//				}
459
//			}
460
//
461
//			//if we cannot find the extension class in memory, then check to see if the extension plugin is activated
462
//			$extension = $this->get_extension( $slug );
463
//			$plugin = $this->find_active_wordpress_plugin( $extension );
464
//			return $plugin;
465
		}
466
467
		/**
468
		 * @TODO
469
		 *
470
		 * @param bool $extension
471
		 *
472
		 * @param bool $slug
473
		 *
474
		 * @return bool
475
		 */
476
		public function is_downloaded( $extension = false, $slug = false ) {
477
			//allow you to pass in a slug rather
478
			if ( ! $extension && $slug !== false ) {
479
				$extension = $this->get_extension( $slug );
480
			}
481
			if ( $extension ) {
482
				//first check if the class exists
483
				if ( class_exists( $extension['class'] ) ) {
484
					return true;
485
				}
486
487
				//next fallback to see if a plugin exists that has the same file name
488
				$plugin = $this->find_wordpress_plugin( $extension );
489
				return false !== $plugin;
490
			}
491
			return false;
492
		}
493
494
		/**
495
		 * @TODO
496
		 * @param $slug
497
		 *
498
		 * @return bool
499
		 */
500
		public function has_errors( $slug ) {
501
			$error_extensions = $this->get_error_extensions();
502
503
			if ( $error_extensions ) {
504
				return array_key_exists( $slug, $error_extensions );
505
			}
506
			return false;
507
		}
508
509
		/**
510
		 * @TODO
511
		 * @param $plugin
512
		 */
513
		public function handle_wordpress_plugin_deactivation( $plugin ) {
514
			$extension = $this->get_extension_by_file( $plugin );
515
			if ( $extension ) {
516
				//we have found a matching extension
517
				$this->deactivate( $extension['slug'], false );
518
			}
519
		}
520
521
		/**
522
		 * @TODO
523
		 * @param $plugin
524
		 */
525
		public function handle_wordpress_plugin_activation( $plugin ) {
526
			$extension = $this->get_extension_by_file( $plugin );
527
			if ( $extension ) {
528
				//we have found a matching extension
529
				$this->activate( $extension['slug'], false );
530
			}
531
		}
532
533
		/**
534
		 * @TODO
535
		 * @param      $slug
536
		 * @param bool $deactivate_wordpress_plugin
537
		 * @param bool $error_loading
538
		 *
539
		 * @return array|mixed|void
540
		 */
541
		public function deactivate( $slug, $deactivate_wordpress_plugin = true, $error_loading = false ) {
542
			$extension = $this->get_extension( $slug );
543
			if ( $extension ) {
544
				if ( $deactivate_wordpress_plugin && 'bundled' !== foo_safe_get( $extension, 'source', false ) ) {
545
					$plugin = $this->find_wordpress_plugin( $extension );
546
					if ( $plugin ) {
547
						$failure = deactivate_plugins( $plugin['file'], true, false );
548
						if ( null !== $failure ) {
549
							return array(
550
								'message' => sprintf( __( 'The extension %s could NOT be deactivated!', 'foogallery' ), "<strong>{$extension['title']}</strong>" ),
551
								'type' => 'error'
552
							);
553
						}
554
					}
555
				}
556
557
				$active_extensions = $this->get_active_extensions();
558
				if ( array_key_exists( $slug, $active_extensions ) ) {
559
					unset( $active_extensions[ $slug ] );
560
					if ( empty($active_extensions) ) {
561
						delete_option( FOOGALLERY_EXTENSIONS_ACTIVATED_OPTIONS_KEY );
562
					} else {
563
						update_option( FOOGALLERY_EXTENSIONS_ACTIVATED_OPTIONS_KEY, $active_extensions );
564
					}
565
				}
566
567
				if ( $error_loading ) {
568
					$this->add_to_error_extensions( $slug );
569
				}
570
571
				//we are done, allow for extensions to do something after an extension is activated
572
				do_action( 'foogallery_extension_deactivated-' . $slug );
573
574
				return apply_filters( 'foogallery_extensions_deactivated_message-' . $slug, array(
575
					'message' => sprintf( __( 'The extension %s was successfully deactivated', 'foogallery' ), "<strong>{$extension['title']}</strong>" ),
576
					'type' => 'success',
577
				) );
578
			}
579
			return array(
580
				'message' => sprintf( __( 'Unknown extension : %s', 'foogallery' ), $slug ),
581
				'type' => 'error',
582
			);
583
		}
584
585
		/**
586
		 * @TODO
587
		 *
588
		 * @param      $slug
589
		 * @param bool $activate_wordpress_plugin
590
		 *
591
		 * @return array|mixed|void
592
		 */
593
		public function activate( $slug, $activate_wordpress_plugin = true ) {
594
			$extension = $this->get_extension( $slug );
595
			if ( $extension ) {
596
				//first remove it from our error list (if it was there before)
597
				$this->remove_from_error_extensions( $slug );
598
599
				if ( $activate_wordpress_plugin && 'bundled' !== foo_safe_get( $extension, 'source', false ) ) {
600
					//activate the plugin, WordPress style!
601
					$plugin = $this->find_wordpress_plugin( $extension );
602
603
					if ( $plugin ) {
604
605
						//check min version
606
						$minimum_version = foo_safe_get( $extension, 'minimum_version' );
607
						if ( !empty($minimum_version) ) {
608
							$actual_version = $plugin['plugin']['Version'];
609
							if ( version_compare( $actual_version, $minimum_version ) < 0 ) {
610
								$this->add_to_error_extensions( $slug, sprintf( __( 'Requires %s version %s','foogallery' ), $extension['title'], $minimum_version ) );
611
								return array(
612
									'message' => sprintf( __( 'The extension %s could not be activated, because you are using an outdated version! Please update %s to at least version %s.', 'foogallery' ), $extension['title'], $extension['title'], $minimum_version ),
613
									'type' => 'error',
614
								);
615
							}
616
						}
617
618
						//try to activate the plugin
619
						$failure = activate_plugin( $plugin['file'], '', false, false );
620
						if ( null !== $failure ) {
621
							return array(
622
								'message' => sprintf( __( 'The extension %s could NOT be activated!', 'foogallery' ), "<strong>{$extension['title']}</strong>" ),
623
								'type' => 'error',
624
							);
625
						}
626
					}
627
				}
628
				//load an instance of the extension class into memory
629
				$loader = new FooGallery_Extensions_Loader();
630
				$loader->load_extension( $slug, foo_safe_get( $extension, 'class', false ) );
631
632
				//then add the extension to our saved option so that it can be loaded on startup
633
				$this->add_to_activated_extensions( $extension );
634
635
				//we are done, allow for extensions to do something after an extension is activated
636
				do_action( 'foogallery_extension_activated-' . $slug );
637
638
				//return our result
639
				return apply_filters( 'foogallery_extension_activated_message-' . $slug, array(
640
					'message' => sprintf( __( 'The extension %s was successfully activated', 'foogallery' ), "<strong>{$extension['title']}</strong>" ),
641
					'type' => 'success',
642
				) );
643
			}
644
			return array(
645
				'message' => sprintf( __( 'Unknown extension : %s', 'foogallery' ), $slug ),
646
				'type' => 'error',
647
			);
648
		}
649
650
		/**
651
		 * @TODO
652
		 * @param boolean $extension
653
		 *
654
		 * @return array|bool
655
		 */
656
		private function find_wordpress_plugin( $extension ) {
657
			$plugins = get_plugins();
658
			foreach ( $plugins as $plugin_file => $plugin ) {
659
				if ( isset($extension['file']) && foo_ends_with( $plugin_file, $extension['file'] ) ) {
660
					return array(
661
						'file' => $plugin_file,
662
						'plugin' => $plugin,
663
						'active' => is_plugin_active( $plugin_file ),
664
					);
665
				}
666
			}
667
			return false;
668
		}
669
670
		/**
671
		 * @TODO
672
		 * @param boolean $extension
673
		 *
674
		 * @return array|bool
675
		 */
676
		private function find_active_wordpress_plugin( $extension ) {
677
			$plugins = get_plugins();
678
			foreach ( $plugins as $plugin_file => $plugin ) {
679
				if ( is_plugin_active( $plugin_file ) && isset($extension['file']) && foo_ends_with( $plugin_file, $extension['file'] ) ) {
680
					return array(
681
						'file' => $plugin_file,
682
						'plugin' => $plugin
683
					);
684
				}
685
			}
686
			return false;
687
		}
688
689
		/**
690
		 * @TODO
691
		 * @param $slug
692
		 *
693
		 * @return array|mixed|void
694
		 */
695
		public function download( $slug ) {
696
			$extension = $this->get_extension( $slug );
697
			if ( $extension ) {
698
699
				//we need some files!
700
				require_once ABSPATH . 'wp-admin/includes/plugin-install.php'; // plugins_api calls
701
				require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php'; // Plugin_Upgrader class
702
				require_once FOOGALLERY_PATH . 'includes/admin/class-silent-installer-skin.php'; //our silent installer skin
703
704
				$download_link = isset( $extension['download_link'] ) ? $extension['download_link'] : false;
705
706
				if ( 'repo' === $extension['source'] ) {
707
					$plugins_api = plugins_api( 'plugin_information', array( 'slug' => $slug, 'fields' => array( 'sections' => false ) ) );
708
709
					if ( is_wp_error( $plugins_api ) ) {
710
						return array(
711
							'message' => sprintf( __( 'Unable to connect to the WordPress.org plugin API to download %s. Full error log: %s', 'foogallery' ), $slug,  '<br />' . var_export( $plugins_api, true ) ),
712
							'type' => 'error',
713
						);
714
					}
715
716
					//get the download link from the API call
717
					if ( isset( $plugins_api->download_link ) ) {
718
						$download_link = $plugins_api->download_link;
719
					}
720
				}
721
722
				//check we have something to download
723
				if ( empty( $download_link ) ) {
724
					return array(
725
						'message' => sprintf( __( 'The extension %s has no download link!', 'foogallery' ), $slug ),
726
						'type' => 'error',
727
					);
728
				}
729
730
				$skin = new FooGallery_Silent_Installer_Skin();
731
732
				//instantiate Plugin_Upgrader
733
				$upgrader = new Plugin_Upgrader( $skin );
734
735
				$upgrader->install( $download_link );
736
737
				if ( 'process_failed' === $skin->feedback ) {
738
					$error_message = is_wp_error( $skin->result ) ? $skin->result->get_error_message() : __( 'Unknown!', 'foogallery' );
739
740
					//save the error message for the extension
741
					$this->add_to_error_extensions( $slug, sprintf( __('Could not be downloaded! Error : %s', 'foogallery' ), $error_message ) );
742
743
					//we had an error along the way
744
					return apply_filters( 'foogallery_extensions_download_failure-' . $slug, array(
745
						'message' => sprintf( __( 'The extension %s could NOT be downloaded! Error : %s', 'foogallery' ), "<strong>{$extension['title']}</strong>", $error_message ),
746
						'type' => 'error'
747
					) );
748
				}
749
750
				//return our result
751
				return apply_filters( 'foogallery_extensions_download_success-' . $slug, array(
752
					'message' => sprintf( __( 'The extension %s was successfully downloaded and can now be activated. %s', 'foogallery' ),
753
						"<strong>{$extension['title']}</strong>",
754
						'<a href="' . esc_url( add_query_arg( array(
755
								'action' => 'activate',
756
								'extension' => $slug, ) ) ) . '">' . __( 'Activate immediately', 'foogallery' ) . '</a>'
757
					),
758
					'type' => 'success',
759
				) );
760
			}
761
			return array(
762
				'message' => sprintf( __( 'Unknown extension : %s', 'foogallery' ), $slug ),
763
				'type' => 'error',
764
			);
765
		}
766
767
		/**
768
		 * @TODO
769
		 * @return mixed|void
770
		 */
771
		public function get_active_extensions() {
772
			//should we not rather get back all plugins that are active?
773
			return get_option( FOOGALLERY_EXTENSIONS_ACTIVATED_OPTIONS_KEY, array() );
774
		}
775
776
		/**
777
		 * @TODO
778
		 * @return mixed|void
779
		 */
780
		public function get_error_extensions() {
781
			return get_option( FOOGALLERY_EXTENSIONS_ERRORS_OPTIONS_KEY, array() );
782
		}
783
784
		public function get_error_message( $slug ) {
785
			$error_extensions = $this->get_error_extensions();
786
			if ( array_key_exists( $slug, $error_extensions ) ) {
787
				return $error_extensions[ $slug ];
788
			}
789
			return '';
790
		}
791
792
		/**
793
		 * @TODO
794
		 * @param $extension
795
		 */
796
		private function add_to_activated_extensions( $extension ) {
797
			$slug = $extension['slug'];
798
			$active_extensions = $this->get_active_extensions();
799
			if ( !array_key_exists( $slug, $active_extensions ) ) {
800
				$active_extensions[ $slug ] = $extension['class'];
801
				update_option( FOOGALLERY_EXTENSIONS_ACTIVATED_OPTIONS_KEY, $active_extensions );
802
			}
803
		}
804
805
		/**
806
		 * @TODO
807
		 * @param $slug
808
		 */
809
		public function add_to_error_extensions( $slug, $error_message = '' ) {
810
			$error_extensions = $this->get_error_extensions();
811
812
			if ( empty($error_message) ) {
813
				$error_message = __( 'Error loading extension!', 'foogallery' );
814
			}
815
816
			if ( array_key_exists( $slug, $error_extensions ) &&
0 ignored issues
show
Unused Code introduced by
This if statement is empty and can be removed.

This check looks for the bodies of if statements that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.

These if bodies can be removed. If you have an empty if but statements in the else branch, consider inverting the condition.

if (rand(1, 6) > 3) {
//print "Check failed";
} else {
    print "Check succeeded";
}

could be turned into

if (rand(1, 6) <= 3) {
    print "Check succeeded";
}

This is much more concise to read.

Loading history...
817
				$error_message === $error_extensions[$slug]) {
818
				//do nothing!
819
			} else {
820
				$error_extensions[$slug] = $error_message;
821
				update_option( FOOGALLERY_EXTENSIONS_ERRORS_OPTIONS_KEY, $error_extensions );
822
			}
823
		}
824
825
		/**
826
		 * @TODO
827
		 * @param $slug
828
		 */
829
		private function remove_from_error_extensions( $slug ) {
830
			$error_extensions = $this->get_error_extensions();
831
			if ( array_key_exists( $slug, $error_extensions ) ) {
832
				unset( $error_extensions[ $slug ] );
833
				update_option( FOOGALLERY_EXTENSIONS_ERRORS_OPTIONS_KEY, $error_extensions );
834
			}
835
		}
836
837
		/**
838
		 * @TODO
839
		 */
840
		public function auto_activate_extensions() {
841
			foreach ( $this->get_all() as $extension ) {
842
				if ( true === foo_safe_get( $extension, 'activated_by_default' ) ) {
843
					//check to see if the extension is downloaded
844
					if ( $this->is_downloaded( $extension ) ) {
845
						$this->add_to_activated_extensions( $extension );
846
					}
847
				}
848
			}
849
		}
850
	}
851
}
852