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 — feature/gallery-template-clien... ( 29cf1c...2e8a82 )
by Brad
05:37 queued 02:47
created

find_active_wordpress_plugin()   B

Complexity

Conditions 5
Paths 3

Size

Total Lines 12
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 5
eloc 8
nc 3
nop 1
dl 0
loc 12
rs 8.8571
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
			//Our default gallery templates
139
			$extensions[] = array(
140
				'slug'        => 'default_templates',
141
				'class'       => 'FooGallery_Default_Templates_Extension',
142
				'categories'  => array( 'Featured', 'Free', ),
143
				'title'       => 'Default Templates',
144
				'description' => 'The bundled gallery templates.',
145
				'author'      => 'FooPlugins',
146
				'author_url'  => 'http://fooplugins.com',
147
				'thumbnail'   => '/assets/extension_bg.png',
148
				'tags'        => array( 'template', ),
149
				'source'      => 'bundled',
150
				'activated_by_default' => true,
151
			);
152
153
			$extensions[] =	array(
154
				'slug' => 'albums',
155
				'class' => 'FooGallery_Albums_Extension',
156
				'title' => 'Albums',
157
				'categories' =>	array( 'Featured', 'Free' ),
158
				'description' => 'Group your galleries into albums. Boom!',
159
				'html' => 'Group your galleries into albums. Boom!',
160
				'author' => 'FooPlugins',
161
				'author_url' => 'http://fooplugins.com',
162
				'thumbnail' => '/extensions/albums/foogallery-albums.png',
163
				'tags' => array( 'functionality' ),
164
				'source' => 'bundled'
165
			);
166
167
			//FooBox premium
168
			$extensions[] = array(
169
				'slug' => 'foobox',
170
				'class' => 'FooGallery_FooBox_Extension',
171
				'categories' => array( 'Featured', 'Premium' ),
172
				'file' => 'foobox-free.php',
173
				'title' => 'FooBox PRO',
174
				'description' => 'The best lightbox for WordPress just got even better!',
175
				'price' => '$27',
176
				'author' => 'FooPlugins',
177
				'author_url' => 'http://fooplugins.com',
178
				'thumbnail' => '/assets/extension_bg.png',
179
				'tags' => array( 'premium', 'lightbox', ),
180
				'source' => 'fooplugins',
181
				'download_button' =>
182
					array(
183
						'text' => 'Buy - $27',
184
						'target' => '_blank',
185
						'href' => 'http://fooplugins.com/plugins/foobox',
186
						'confirm' => false,
187
					),
188
				'activated_by_default' => true,
189
				'minimum_version' => '2.3.2',
190
				'remove_if_active' => array('foobox-image-lightbox')
191
			);
192
193
			//FooBox lightbox
194
			$extensions[] = array (
195
				'slug' => 'foobox-image-lightbox',
196
				'class' => 'FooGallery_FooBox_Free_Extension',
197
				'categories' => array( 'Featured', 'Free', ),
198
				'file' => 'foobox-free.php',
199
				'title' => 'FooBox FREE',
200
				'description' => 'The best lightbox for WordPress. Free',
201
				'author' => 'FooPlugins',
202
				'author_url' => 'http://fooplugins.com',
203
				'thumbnail' => '/assets/extension_bg.png',
204
				'tags' => array( 'lightbox' ),
205
				'source' => 'repo',
206
				'activated_by_default' => true,
207
				'minimum_version' => '1.0.2.1',
208
			);
209
210
			//The NextGen importer
211
			$extensions[] = array(
212
				'slug' => 'nextgen',
213
				'class' => 'FooGallery_Nextgen_Gallery_Importer_Extension',
214
				'categories' => array( 'Free' ),
215
				'title' => 'NextGen Importer',
216
				'description' => 'Imports all your existing NextGen galleries',
217
				'author' => 'FooPlugins',
218
				'author_url' => 'http://fooplugins.com',
219
				'thumbnail' => '/assets/extension_bg.png',
220
				'tags' => array( 'tools' ),
221
				'source' => 'bundled',
222
			);
223
224
			return $extensions;
225
		}
226
227
		/**
228
		 * @TODO
229
		 */
230
		private function determine_new_extensions() {
231
			$previous_slugs = get_option( FOOGALLERY_EXTENSIONS_SLUGS_OPTIONS_KEY );
232
			if ( $previous_slugs ) {
233
				//only do something if we have a previously saved array
234
				foreach ( $this->extensions as &$extension ) {
235
					if ( ! in_array( $extension['slug'], $previous_slugs ) ) {
236
						if ( ! isset( $extension['tags'] ) ) {
237
							$extension['tags'] = array();
238
						}
239
						array_unshift( $extension['tags'] , __( 'new', 'foogallery' ) );
240
					}
241
				}
242
			}
243
		}
244
245
		/**
246
		 * @TODO
247
		 */
248
		private function save_slugs_for_new_calculations() {
249
			if ( is_array( $this->extensions ) ) {
250
				$slugs = array();
251
				foreach ( $this->extensions as $extension ) {
252
					$slugs[] = $extension['slug'];
253
				}
254
				if ( count( $slugs ) > 0 ) {
255
					update_option( FOOGALLERY_EXTENSIONS_SLUGS_OPTIONS_KEY, $slugs );
256
				}
257
			}
258
		}
259
260
		/**
261
		 * Clears the cached list of extensions
262
		 */
263
		public function clear_cached_extensions() {
264
			delete_transient( FOOGALLERY_EXTENSIONS_AVAILABLE_TRANSIENT_KEY );
265
		}
266
267
		/**
268
		 * Reload the extensions from the public endpoint
269
		 */
270
		public function reload() {
271
			$this->clear_cached_extensions();
272
			$this->load_available_extensions();
273
		}
274
275
		/**
276
		 * Get all loaded extensions
277
		 * @return array
278
		 */
279
		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...
280
281
			//check if we need to load
282
			if ( false === $this->extensions ) {
283
				$this->load_available_extensions();
284
			}
285
286
			//get any extra extensions from plugins
287
			$extra_extensions = apply_filters( 'foogallery_available_extensions', array() );
288
289
			if ( count( $extra_extensions ) > 0 ) {
290
				//get a list of slugs so we can determine duplicates!
291
				$this->extension_slugs = array();
292
				foreach ( $this->extensions as $extension ) {
293
					$this->extension_slugs[] = $extension['slug'];
294
				}
295
296
				//only add if not a duplicate
297
				foreach ( $extra_extensions as $extension ) {
298
					if ( ! in_array( $extension['slug'], $this->extension_slugs ) ) {
299
						$this->extensions[] = $extension;
300
					}
301
				}
302
			}
303
304
			return $this->extensions;
305
		}
306
307
308
		/**
309
		 * return a list of all extensions for the extension view.
310
		 * This list could be changed based on other plugin
311
		 */
312
		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...
313
			$all_extensions = $this->get_all();
314
			$extensions = array();
315
			$active_extensions = array();
316
317
			//add all extensions to an array using the slug as the array key
318
			foreach ( $all_extensions as $extension ) {
319
320
				//remove any bundled extensions that are activated_by_default = true
321
				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...
322
					true === $extension['activated_by_default'] &&
323
					isset( $extension['source'] ) &&
324
					'bundled' === $extension['source']) {
325
					//do not include a bundled extension that is activated by default
326
				} else {
327
					$extensions[ $extension['slug'] ] = $extension;
328
				}
329
330
				//build up a list of active extensions
331
				if ( $this->is_active( $extension['slug'] ) ) {
332
					$active_extensions[$extension['slug']] = $extension;
333
				}
334
			}
335
336
			//loop through all active extensions and remove any other extensions if required based on the 'remove_if_active' property
337
			foreach ( $active_extensions as $active_extension_slug => $active_extension ) {
338
				//check if we need to remove any other extensions from the list
339
				if ( isset( $active_extension['remove_if_active'] ) ) {
340
341
					foreach ( $active_extension['remove_if_active'] as $extension_slug_to_remove ) {
342
						if ( array_key_exists( $extension_slug_to_remove, $extensions ) ) {
343
							unset( $extensions[ $extension_slug_to_remove ] );
344
						}
345
					}
346
				}
347
			}
348
349
			$extensions = apply_filters( 'foogallery_extensions_for_view', $extensions );
350
351
			return $extensions;
352
		}
353
		/**
354
		 * Get all loaded extensions slugs
355
		 * @return array
356
		 */
357
		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...
358
			//load all extensions first!
359
			$this->get_all();
360
361
			return $this->extension_slugs;
362
		}
363
364
		/**
365
		 * Returns a distinct array of categories that are used in the extensions
366
		 * @return mixed
367
		 */
368
		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...
369
			$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...
370
				'name' => __( 'All', 'foogallery' ),
371
			);
372
			$categories['activated'] = array(
373
				'name' => __( 'Active', 'foogallery' ),
374
			);
375
			$active = 0;
376
			foreach ( $this->get_all() as $extension ) {
377
				if ( $this->is_active( $extension['slug'] ) ) {
378
					$active++;
379
				}
380
				$category_names = $extension['categories'];
381
				foreach ( $category_names as $category_name ) {
382
					$category_slug = foo_convert_to_key( $category_name );
383
384
					if ( ! array_key_exists( $category_slug, $categories ) ) {
385
						$categories[ $category_slug ] = array(
386
							'name'  => $category_name,
387
						);
388
					}
389
				}
390
			}
391
			$categories['build_your_own'] = array(
392
				'name' => __( 'Build Your Own', 'foogallery' )
393
			);
394
			return apply_filters( 'foogallery_extension_categories', $categories );
395
		}
396
397
		/**
398
		 * @TODO
399
		 * @param $slug
400
		 *
401
		 * @return bool
402
		 */
403
		public function get_extension( $slug ) {
404
			foreach ( $this->get_all() as $extension ) {
405
				if ( $extension['slug'] === $slug ) {
406
					return $extension;
407
				}
408
			}
409
			return false;
410
		}
411
412
		/**
413
		 * @TODO
414
		 * @param $file
415
		 *
416
		 * @return bool
417
		 */
418
		public function get_extension_by_file( $file ) {
419
			$file = basename( $file ); //normalize to just the filename
420
421
			foreach ( $this->get_all() as $extension ) {
422
				if ( foo_safe_get( $extension, 'file' ) === $file ) {
423
					return $extension;
424
				}
425
			}
426
			return false;
427
		}
428
429
		/**
430
		 * @TODO
431
		 * @param      $slug
432
		 *
433
		 * @return bool
434
		 */
435
		public function is_active( $slug ) {
436
			global $foogallery_extensions;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

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