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 — develop ( 3bd383...ce1d31 )
by Brad
02:29
created

FooGallery_Extensions_API::is_downloaded()   B

Complexity

Conditions 5
Paths 6

Size

Total Lines 17
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 5
eloc 9
nc 6
nop 2
dl 0
loc 17
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
			return apply_filters('foogallery_extension_api_endpoint', $extension_url );
74
		}
75
76
		/**
77
		 * Reset all previous errors
78
		 */
79
		public function reset_errors() {
80
			delete_option( FOOGALLERY_EXTENSIONS_LOADING_ERRORS );
81
			delete_option( FOOGALLERY_EXTENSIONS_LOADING_ERRORS_RESPONSE );
82
		}
83
84
		/**
85
		 * Load all available extensions from the public endpoint and store in a transient for later use
86
		 */
87
		private function load_available_extensions() {
88
			if ( false === ( $this->extensions = get_transient( FOOGALLERY_EXTENSIONS_AVAILABLE_TRANSIENT_KEY ) ) ) {
89
90
				//clear any previous state
91
				$this->reset_errors();
92
				$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...
93
				$expires = 60 * 60 * 24; //1 day
94
95
				$extension_url = $this->get_extensions_endpoint();
96
97
				//fetch the data from our public list of extensions hosted on github
98
				$response = wp_remote_get( $extension_url, array( 'sslverify' => false ) );
99
100
				if( ! is_wp_error( $response ) ) {
101
102
					if ( $response['response']['code'] == 200 ) {
103
						$this->extensions = @json_decode( $response['body'], true );
104
105
						//if we got a valid list of extensions then calculate which are new and cache the result
106
						if ( is_array( $this->extensions ) ) {
107
							$this->determine_new_extensions( );
108
							$this->save_slugs_for_new_calculations();
109
						}
110
					}
111
				}
112
113
				if ( ! is_array( $this->extensions ) ) {
114
					//there was some problem getting a list of extensions. Could be a network error, or the extension json was malformed
115
					update_option( FOOGALLERY_EXTENSIONS_LOADING_ERRORS, true );
116
					update_option( FOOGALLERY_EXTENSIONS_LOADING_ERRORS_RESPONSE, $response );
117
					$this->extensions = $this->default_extenions_in_case_of_emergency();
118
					$expires = 5 * 60; //Only cache for 5 minutes if there are errors.
119
				}
120
121
				//Cache the result
122
				set_transient( FOOGALLERY_EXTENSIONS_AVAILABLE_TRANSIENT_KEY, $this->extensions, $expires );
123
			}
124
		}
125
126
		/**
127
		 * Get an array of default extensions.
128
		 * 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
129
		 *
130
		 * @return array
131
		 */
132
		private function default_extenions_in_case_of_emergency() {
133
			$extensions = array();
134
135
			//Our default gallery templates
136
			$extensions[] = array(
137
				'slug'        => 'default_templates',
138
				'class'       => 'FooGallery_Default_Templates_Extension',
139
				'categories'  => array( 'Featured', 'Free', ),
140
				'title'       => 'Default Templates',
141
				'description' => 'The bundled gallery templates.',
142
				'author'      => 'FooPlugins',
143
				'author_url'  => 'http://fooplugins.com',
144
				'thumbnail'   => '/assets/extension_bg.png',
145
				'tags'        => array( 'template', ),
146
				'source'      => 'bundled',
147
				'activated_by_default' => true,
148
			);
149
150
			$extensions[] =	array(
151
				'slug' => 'albums',
152
				'class' => 'FooGallery_Albums_Extension',
153
				'title' => 'Albums',
154
				'categories' =>	array( 'Featured', 'Free' ),
155
				'description' => 'Group your galleries into albums. Boom!',
156
				'html' => 'Group your galleries into albums. Boom!',
157
				'author' => 'FooPlugins',
158
				'author_url' => 'http://fooplugins.com',
159
				'thumbnail' => '/extensions/albums/foogallery-albums.png',
160
				'tags' => array( 'functionality' ),
161
				'source' => 'bundled'
162
			);
163
164
			//FooBox premium
165
			$extensions[] = array(
166
				'slug' => 'foobox',
167
				'class' => 'FooGallery_FooBox_Extension',
168
				'categories' => array( 'Featured', 'Premium' ),
169
				'file' => 'foobox-free.php',
170
				'title' => 'FooBox PRO',
171
				'description' => 'The best lightbox for WordPress just got even better!',
172
				'price' => '$27',
173
				'author' => 'FooPlugins',
174
				'author_url' => 'http://fooplugins.com',
175
				'thumbnail' => '/assets/extension_bg.png',
176
				'tags' => array( 'premium', 'lightbox', ),
177
				'source' => 'fooplugins',
178
				'download_button' =>
179
					array(
180
						'text' => 'Buy - $27',
181
						'target' => '_blank',
182
						'href' => 'http://fooplugins.com/plugins/foobox',
183
						'confirm' => false,
184
					),
185
				'activated_by_default' => true,
186
				'minimum_version' => '2.3.2',
187
				'remove_if_active' => array('foobox-image-lightbox')
188
			);
189
190
			//FooBox lightbox
191
			$extensions[] = array (
192
				'slug' => 'foobox-image-lightbox',
193
				'class' => 'FooGallery_FooBox_Free_Extension',
194
				'categories' => array( 'Featured', 'Free', ),
195
				'file' => 'foobox-free.php',
196
				'title' => 'FooBox FREE',
197
				'description' => 'The best lightbox for WordPress. Free',
198
				'author' => 'FooPlugins',
199
				'author_url' => 'http://fooplugins.com',
200
				'thumbnail' => '/assets/extension_bg.png',
201
				'tags' => array( 'lightbox' ),
202
				'source' => 'repo',
203
				'activated_by_default' => true,
204
				'minimum_version' => '1.0.2.1',
205
			);
206
207
			//The NextGen importer
208
			$extensions[] = array(
209
				'slug' => 'nextgen',
210
				'class' => 'FooGallery_Nextgen_Gallery_Importer_Extension',
211
				'categories' => array( 'Free' ),
212
				'title' => 'NextGen Importer',
213
				'description' => 'Imports all your existing NextGen galleries',
214
				'author' => 'FooPlugins',
215
				'author_url' => 'http://fooplugins.com',
216
				'thumbnail' => '/assets/extension_bg.png',
217
				'tags' => array( 'tools' ),
218
				'source' => 'bundled',
219
			);
220
221
			return $extensions;
222
		}
223
224
		/**
225
		 * @TODO
226
		 */
227
		private function determine_new_extensions() {
228
			$previous_slugs = get_option( FOOGALLERY_EXTENSIONS_SLUGS_OPTIONS_KEY );
229
			if ( $previous_slugs ) {
230
				//only do something if we have a previously saved array
231
				foreach ( $this->extensions as &$extension ) {
232
					if ( ! in_array( $extension['slug'], $previous_slugs ) ) {
233
						if ( ! isset( $extension['tags'] ) ) {
234
							$extension['tags'] = array();
235
						}
236
						array_unshift( $extension['tags'] , __( 'new', 'foogallery' ) );
237
					}
238
				}
239
			}
240
		}
241
242
		/**
243
		 * @TODO
244
		 */
245
		private function save_slugs_for_new_calculations() {
246
			if ( is_array( $this->extensions ) ) {
247
				$slugs = array();
248
				foreach ( $this->extensions as $extension ) {
249
					$slugs[] = $extension['slug'];
250
				}
251
				if ( count( $slugs ) > 0 ) {
252
					update_option( FOOGALLERY_EXTENSIONS_SLUGS_OPTIONS_KEY, $slugs );
253
				}
254
			}
255
		}
256
257
		/**
258
		 * Clears the cached list of extensions
259
		 */
260
		public function clear_cached_extensions() {
261
			delete_transient( FOOGALLERY_EXTENSIONS_AVAILABLE_TRANSIENT_KEY );
262
		}
263
264
		/**
265
		 * Reload the extensions from the public endpoint
266
		 */
267
		public function reload() {
268
			$this->clear_cached_extensions();
269
			$this->load_available_extensions();
270
		}
271
272
		/**
273
		 * Get all loaded extensions
274
		 * @return array
275
		 */
276
		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...
277
278
			//check if we need to load
279
			if ( false === $this->extensions ) {
280
				$this->load_available_extensions();
281
			}
282
283
			//get any extra extensions from plugins
284
			$extra_extensions = apply_filters( 'foogallery_available_extensions', array() );
285
286
			if ( count( $extra_extensions ) > 0 ) {
287
				//get a list of slugs so we can determine duplicates!
288
				$this->extension_slugs = array();
289
				foreach ( $this->extensions as $extension ) {
290
					$this->extension_slugs[] = $extension['slug'];
291
				}
292
293
				//only add if not a duplicate
294
				foreach ( $extra_extensions as $extension ) {
295
					if ( ! in_array( $extension['slug'], $this->extension_slugs ) ) {
296
						$this->extensions[] = $extension;
297
					}
298
				}
299
			}
300
301
			return $this->extensions;
302
		}
303
304
305
		/**
306
		 * return a list of all extensions for the extension view.
307
		 * This list could be changed based on other plugin
308
		 */
309
		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...
310
			$all_extensions = $this->get_all();
311
			$extensions = array();
312
313
			//add all extensions to an array using the slug as the array key
314
			foreach ( $all_extensions as $extension ) {
315
316
				//remove any bundled extensions that are activated_by_default = true
317
				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...
318
					true === $extension['activated_by_default'] &&
319
					isset( $extension['source'] ) &&
320
					'bundled' === $extension['source']) {
321
					//do not include a bundled extension that is activated by default
322
				} else {
323
					$extensions[ $extension['slug'] ] = $extension;
324
				}
325
			}
326
327
			//loop through all active extensions and remove any other extensions if required based on the 'remove_if_active' property
328
			$active_extensions = $this->get_active_extensions();
329
330
			foreach ( $active_extensions as $active_extension => $active_extension_class ) {
331
				if ( array_key_exists( $active_extension, $extensions ) ) {
332
					$extension = $extensions[$active_extension];
333
334
					//check if we need to remove any other extensions from the list
335
					if ( isset( $extension['remove_if_active'] ) ) {
336
337
						foreach ( $extension['remove_if_active'] as $extension_slug_to_remove ) {
338
339
							if ( array_key_exists( $extension_slug_to_remove, $extensions ) ) {
340
								unset( $extensions[ $extension_slug_to_remove ] );
341
							}
342
						}
343
					}
344
				}
345
			}
346
347
			$extensions = apply_filters( 'foogallery_extensions_for_view', $extensions );
348
349
			return $extensions;
350
		}
351
		/**
352
		 * Get all loaded extensions slugs
353
		 * @return array
354
		 */
355
		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...
356
			//load all extensions first!
357
			$this->get_all();
358
359
			return $this->extension_slugs;
360
		}
361
362
		/**
363
		 * Returns a distinct array of categories that are used in the extensions
364
		 * @return mixed
365
		 */
366
		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...
367
			$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...
368
				'name' => __( 'All', 'foogallery' ),
369
			);
370
			$categories['activated'] = array(
371
				'name' => __( 'Active', 'foogallery' ),
372
			);
373
			$active = 0;
374
			foreach ( $this->get_all() as $extension ) {
375
				if ( $this->is_active( $extension['slug'] ) ) {
376
					$active++;
377
				}
378
				$category_names = $extension['categories'];
379
				foreach ( $category_names as $category_name ) {
380
					$category_slug = foo_convert_to_key( $category_name );
381
382
					if ( ! array_key_exists( $category_slug, $categories ) ) {
383
						$categories[ $category_slug ] = array(
384
							'name'  => $category_name,
385
						);
386
					}
387
				}
388
			}
389
			$categories['build_your_own'] = array(
390
				'name' => __( 'Build Your Own', 'foogallery' )
391
			);
392
			return apply_filters( 'foogallery_extension_categories', $categories );
393
		}
394
395
		/**
396
		 * @TODO
397
		 * @param $slug
398
		 *
399
		 * @return bool
400
		 */
401
		public function get_extension( $slug ) {
402
			foreach ( $this->get_all() as $extension ) {
403
				if ( $extension['slug'] === $slug ) {
404
					return $extension;
405
				}
406
			}
407
			return false;
408
		}
409
410
		/**
411
		 * @TODO
412
		 * @param $file
413
		 *
414
		 * @return bool
415
		 */
416
		public function get_extension_by_file( $file ) {
417
			$file = basename( $file ); //normalize to just the filename
418
419
			foreach ( $this->get_all() as $extension ) {
420
				if ( foo_safe_get( $extension, 'file' ) === $file ) {
421
					return $extension;
422
				}
423
			}
424
			return false;
425
		}
426
427
		/**
428
		 * @TODO
429
		 * @param      $slug
430
		 *
431
		 * @return bool
432
		 */
433
		public function is_active( $slug ) {
434
			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...
435
436
			//first check if the extension class was loaded into memory
437
			if ( $foogallery_extensions ) {
438
				if ( array_key_exists( $slug, $foogallery_extensions ) ) {
439
					return true;
440
				}
441
			}
442
443
			//if we cannot find the extension class in memory, then check to see if the extension plugin is activated
444
			$extension = $this->get_extension( $slug );
445
			$plugin = $this->find_wordpress_plugin( $extension );
446
			return $plugin && $plugin['active'];
447
		}
448
449
		/**
450
		 * @TODO
451
		 *
452
		 * @param bool $extension
453
		 *
454
		 * @param bool $slug
455
		 *
456
		 * @return bool
457
		 */
458
		public function is_downloaded( $extension = false, $slug = false ) {
459
			//allow you to pass in a slug rather
460
			if ( ! $extension && $slug !== false ) {
461
				$extension = $this->get_extension( $slug );
462
			}
463
			if ( $extension ) {
464
				//first check if the class exists
465
				if ( class_exists( $extension['class'] ) ) {
466
					return true;
467
				}
468
469
				//next fallback to see if a plugin exists that has the same file name
470
				$plugin = $this->find_wordpress_plugin( $extension );
471
				return false !== $plugin;
472
			}
473
			return false;
474
		}
475
476
		/**
477
		 * @TODO
478
		 * @param $slug
479
		 *
480
		 * @return bool
481
		 */
482
		public function has_errors( $slug ) {
483
			$error_extensions = $this->get_error_extensions();
484
485
			if ( $error_extensions ) {
486
				return array_key_exists( $slug, $error_extensions );
487
			}
488
			return false;
489
		}
490
491
		/**
492
		 * @TODO
493
		 * @param $plugin
494
		 */
495
		public function handle_wordpress_plugin_deactivation( $plugin ) {
496
			$extension = $this->get_extension_by_file( $plugin );
497
			if ( $extension ) {
498
				//we have found a matching extension
499
				$this->deactivate( $extension['slug'], false );
500
			}
501
		}
502
503
		/**
504
		 * @TODO
505
		 * @param $plugin
506
		 */
507
		public function handle_wordpress_plugin_activation( $plugin ) {
508
			$extension = $this->get_extension_by_file( $plugin );
509
			if ( $extension ) {
510
				//we have found a matching extension
511
				$this->activate( $extension['slug'], false );
512
			}
513
		}
514
515
		/**
516
		 * @TODO
517
		 * @param      $slug
518
		 * @param bool $deactivate_wordpress_plugin
519
		 * @param bool $error_loading
520
		 *
521
		 * @return array|mixed|void
522
		 */
523
		public function deactivate( $slug, $deactivate_wordpress_plugin = true, $error_loading = false ) {
524
			$extension = $this->get_extension( $slug );
525
			if ( $extension ) {
526
				if ( $deactivate_wordpress_plugin && 'bundled' !== foo_safe_get( $extension, 'source', false ) ) {
527
					$plugin = $this->find_wordpress_plugin( $extension );
528
					if ( $plugin ) {
529
						$failure = deactivate_plugins( $plugin['file'], true, false );
530
						if ( null !== $failure ) {
531
							return array(
532
								'message' => sprintf( __( 'The extension %s could NOT be deactivated!', 'foogallery' ), "<strong>{$extension['title']}</strong>" ),
533
								'type' => 'error'
534
							);
535
						}
536
					}
537
				}
538
539
				$active_extensions = $this->get_active_extensions();
540
				if ( array_key_exists( $slug, $active_extensions ) ) {
541
					unset( $active_extensions[ $slug ] );
542
					if ( empty($active_extensions) ) {
543
						delete_option( FOOGALLERY_EXTENSIONS_ACTIVATED_OPTIONS_KEY );
544
					} else {
545
						update_option( FOOGALLERY_EXTENSIONS_ACTIVATED_OPTIONS_KEY, $active_extensions );
546
					}
547
				}
548
549
				if ( $error_loading ) {
550
					$this->add_to_error_extensions( $slug );
551
				}
552
553
				//we are done, allow for extensions to do something after an extension is activated
554
				do_action( 'foogallery_extension_deactivated-' . $slug );
555
556
				return apply_filters( 'foogallery_extensions_deactivated_message-' . $slug, array(
557
					'message' => sprintf( __( 'The extension %s was successfully deactivated', 'foogallery' ), "<strong>{$extension['title']}</strong>" ),
558
					'type' => 'success',
559
				) );
560
			}
561
			return array(
562
				'message' => sprintf( __( 'Unknown extension : %s', 'foogallery' ), $slug ),
563
				'type' => 'error',
564
			);
565
		}
566
567
		/**
568
		 * @TODO
569
		 *
570
		 * @param      $slug
571
		 * @param bool $activate_wordpress_plugin
572
		 *
573
		 * @return array|mixed|void
574
		 */
575
		public function activate( $slug, $activate_wordpress_plugin = true ) {
576
			$extension = $this->get_extension( $slug );
577
			if ( $extension ) {
578
				//first remove it from our error list (if it was there before)
579
				$this->remove_from_error_extensions( $slug );
580
581
				if ( $activate_wordpress_plugin && 'bundled' !== foo_safe_get( $extension, 'source', false ) ) {
582
					//activate the plugin, WordPress style!
583
					$plugin = $this->find_wordpress_plugin( $extension );
584
585
					if ( $plugin ) {
586
587
						//check min version
588
						$minimum_version = foo_safe_get( $extension, 'minimum_version' );
589
						if ( !empty($minimum_version) ) {
590
							$actual_version = $plugin['plugin']['Version'];
591
							if ( version_compare( $actual_version, $minimum_version ) < 0 ) {
592
								$this->add_to_error_extensions( $slug, sprintf( __( 'Requires %s version %s','foogallery' ), $extension['title'], $minimum_version ) );
593
								return array(
594
									'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 ),
595
									'type' => 'error',
596
								);
597
							}
598
						}
599
600
						//try to activate the plugin
601
						$failure = activate_plugin( $plugin['file'], '', false, false );
602
						if ( null !== $failure ) {
603
							return array(
604
								'message' => sprintf( __( 'The extension %s could NOT be activated!', 'foogallery' ), "<strong>{$extension['title']}</strong>" ),
605
								'type' => 'error',
606
							);
607
						}
608
					}
609
				}
610
				//load an instance of the extension class into memory
611
				$loader = new FooGallery_Extensions_Loader();
612
				$loader->load_extension( $slug, foo_safe_get( $extension, 'class', false ) );
613
614
				//then add the extension to our saved option so that it can be loaded on startup
615
				$this->add_to_activated_extensions( $extension );
616
617
				//we are done, allow for extensions to do something after an extension is activated
618
				do_action( 'foogallery_extension_activated-' . $slug );
619
620
				//return our result
621
				return apply_filters( 'foogallery_extension_activated_message-' . $slug, array(
622
					'message' => sprintf( __( 'The extension %s was successfully activated', 'foogallery' ), "<strong>{$extension['title']}</strong>" ),
623
					'type' => 'success',
624
				) );
625
			}
626
			return array(
627
				'message' => sprintf( __( 'Unknown extension : %s', 'foogallery' ), $slug ),
628
				'type' => 'error',
629
			);
630
		}
631
632
		/**
633
		 * @TODO
634
		 * @param boolean $extension
635
		 *
636
		 * @return array|bool
637
		 */
638
		private function find_wordpress_plugin( $extension ) {
639
			$plugins = get_plugins();
640
			foreach ( $plugins as $plugin_file => $plugin ) {
641
				if ( isset($extension['file']) && foo_ends_with( $plugin_file, $extension['file'] ) ) {
642
					return array(
643
						'file' => $plugin_file,
644
						'plugin' => $plugin,
645
						'active' => is_plugin_active( $plugin_file ),
646
					);
647
				}
648
			}
649
			return false;
650
		}
651
652
		/**
653
		 * @TODO
654
		 * @param $slug
655
		 *
656
		 * @return array|mixed|void
657
		 */
658
		public function download( $slug ) {
659
			$extension = $this->get_extension( $slug );
660
			if ( $extension ) {
661
662
				//we need some files!
663
				require_once ABSPATH . 'wp-admin/includes/plugin-install.php'; // plugins_api calls
664
				require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php'; // Plugin_Upgrader class
665
				require_once FOOGALLERY_PATH . 'includes/admin/class-silent-installer-skin.php'; //our silent installer skin
666
667
				$download_link = isset( $extension['download_link'] ) ? $extension['download_link'] : false;
668
669
				if ( 'repo' === $extension['source'] ) {
670
					$plugins_api = plugins_api( 'plugin_information', array( 'slug' => $slug, 'fields' => array( 'sections' => false ) ) );
671
672
					if ( is_wp_error( $plugins_api ) ) {
673
						return array(
674
							'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 ) ),
675
							'type' => 'error',
676
						);
677
					}
678
679
					//get the download link from the API call
680
					if ( isset( $plugins_api->download_link ) ) {
681
						$download_link = $plugins_api->download_link;
682
					}
683
				}
684
685
				//check we have something to download
686
				if ( empty( $download_link ) ) {
687
					return array(
688
						'message' => sprintf( __( 'The extension %s has no download link!', 'foogallery' ), $slug ),
689
						'type' => 'error',
690
					);
691
				}
692
693
				$skin = new FooGallery_Silent_Installer_Skin();
694
695
				//instantiate Plugin_Upgrader
696
				$upgrader = new Plugin_Upgrader( $skin );
697
698
				$upgrader->install( $download_link );
699
700
				if ( 'process_failed' === $skin->feedback ) {
701
					$error_message = is_wp_error( $skin->result ) ? $skin->result->get_error_message() : __( 'Unknown!', 'foogallery' );
702
703
					//save the error message for the extension
704
					$this->add_to_error_extensions( $slug, sprintf( __('Could not be downloaded! Error : %s', 'foogallery' ), $error_message ) );
705
706
					//we had an error along the way
707
					return apply_filters( 'foogallery_extensions_download_failure-' . $slug, array(
708
						'message' => sprintf( __( 'The extension %s could NOT be downloaded! Error : %s', 'foogallery' ), "<strong>{$extension['title']}</strong>", $error_message ),
709
						'type' => 'error'
710
					) );
711
				}
712
713
				//return our result
714
				return apply_filters( 'foogallery_extensions_download_success-' . $slug, array(
715
					'message' => sprintf( __( 'The extension %s was successfully downloaded and can now be activated. %s', 'foogallery' ),
716
						"<strong>{$extension['title']}</strong>",
717
						'<a href="' . esc_url( add_query_arg( array(
718
								'action' => 'activate',
719
								'extension' => $slug, ) ) ) . '">' . __( 'Activate immediately', 'foogallery' ) . '</a>'
720
					),
721
					'type' => 'success',
722
				) );
723
			}
724
			return array(
725
				'message' => sprintf( __( 'Unknown extension : %s', 'foogallery' ), $slug ),
726
				'type' => 'error',
727
			);
728
		}
729
730
		/**
731
		 * @TODO
732
		 * @return mixed|void
733
		 */
734
		public function get_active_extensions() {
735
			return get_option( FOOGALLERY_EXTENSIONS_ACTIVATED_OPTIONS_KEY, array() );
736
		}
737
738
		/**
739
		 * @TODO
740
		 * @return mixed|void
741
		 */
742
		public function get_error_extensions() {
743
			return get_option( FOOGALLERY_EXTENSIONS_ERRORS_OPTIONS_KEY, array() );
744
		}
745
746
		public function get_error_message( $slug ) {
747
			$error_extensions = $this->get_error_extensions();
748
			if ( array_key_exists( $slug, $error_extensions ) ) {
749
				return $error_extensions[ $slug ];
750
			}
751
			return '';
752
		}
753
754
		/**
755
		 * @TODO
756
		 * @param $extension
757
		 */
758
		private function add_to_activated_extensions( $extension ) {
759
			$slug = $extension['slug'];
760
			$active_extensions = $this->get_active_extensions();
761
			if ( !array_key_exists( $slug, $active_extensions ) ) {
762
				$active_extensions[ $slug ] = $extension['class'];
763
				update_option( FOOGALLERY_EXTENSIONS_ACTIVATED_OPTIONS_KEY, $active_extensions );
764
			}
765
		}
766
767
		/**
768
		 * @TODO
769
		 * @param $slug
770
		 */
771
		public function add_to_error_extensions( $slug, $error_message = '' ) {
772
			$error_extensions = $this->get_error_extensions();
773
774
			if ( empty($error_message) ) {
775
				$error_message = __( 'Error loading extension!', 'foogallery' );
776
			}
777
778
			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...
779
				$error_message === $error_extensions[$slug]) {
780
				//do nothing!
781
			} else {
782
				$error_extensions[$slug] = $error_message;
783
				update_option( FOOGALLERY_EXTENSIONS_ERRORS_OPTIONS_KEY, $error_extensions );
784
			}
785
		}
786
787
		/**
788
		 * @TODO
789
		 * @param $slug
790
		 */
791
		private function remove_from_error_extensions( $slug ) {
792
			$error_extensions = $this->get_error_extensions();
793
			if ( array_key_exists( $slug, $error_extensions ) ) {
794
				unset( $error_extensions[ $slug ] );
795
				update_option( FOOGALLERY_EXTENSIONS_ERRORS_OPTIONS_KEY, $error_extensions );
796
			}
797
		}
798
799
		/**
800
		 * @TODO
801
		 */
802
		public function auto_activate_extensions() {
803
			foreach ( $this->get_all() as $extension ) {
804
				if ( true === foo_safe_get( $extension, 'activated_by_default' ) ) {
805
					//check to see if the extension is downloaded
806
					if ( $this->is_downloaded( $extension ) ) {
807
						$this->add_to_activated_extensions( $extension );
808
					}
809
				}
810
			}
811
		}
812
	}
813
}
814