Connekt_Plugin_Installer::render_template()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 35

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 4
dl 0
loc 35
rs 9.36
c 0
b 0
f 0
1
<?php
2
/**
3
 * Connekt_Plugin_Installer
4
 *
5
 * This fork is cleaned up and improved of the original class.
6
 * Source: https://github.com/dcooney/wordpress-plugin-installer
7
 *
8
 * @author  Darren Cooney, Sébastien Dumont
9
 * @version 1.0.1
10
 */
11
12
// Exit if accessed directly.
13
if ( ! defined( 'ABSPATH' ) ) {
14
	exit;
15
}
16
17
if ( ! class_exists( 'Connekt_Plugin_Installer' ) ) {
18
19
	class Connekt_Plugin_Installer {
20
21
		public function start() {
22
			if ( ! defined( 'CNKT_INSTALLER_PATH' ) ) {
23
				// Update this constant to use outside the plugins directory
24
				define( 'CNKT_INSTALLER_PATH', plugins_url( '/', __FILE__ ) );
25
			}
26
27
			add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_scripts' ) ); // Enqueue scripts and Localize
28
			add_action( 'wp_ajax_cnkt_plugin_installer', array( $this, 'cnkt_plugin_installer' ) ); // Install plugin
29
			add_action( 'wp_ajax_cnkt_plugin_activation', array( $this, 'cnkt_plugin_activation' ) ); // Activate plugin
30
		} // END start()
31
32
		/**
33
		 * Initialize the display of the plugins.
34
		 *
35
		 * @access public
36
		 * @static
37
		 * @since  1.0
38
		 * @param  array $plugin Plugin data
0 ignored issues
show
Documentation introduced by
There is no parameter named $plugin. Did you maybe mean $plugins?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function. It has, however, found a similar but not annotated parameter which might be a good fit.

Consider the following example. The parameter $ireland is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $ireland
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was changed, but the annotation was not.

Loading history...
39
		 */
40
		public static function init( $plugins ) {
41
			?>
42
			<div class="cnkt-plugin-installer">
43
			<?php
44
			require_once( ABSPATH . 'wp-admin/includes/plugin-install.php' );
45
46
			foreach( $plugins as $plugin ) {
47
				$button_classes = 'install button';
48
				$button_text = __( 'Install Now', 'framework' );
49
50
				$api = plugins_api( 'plugin_information', array(
51
					'slug' => sanitize_file_name( $plugin['slug'] ),
52
					'fields' => array(
53
						'short_description' => true,
54
						'sections' => false,
55
						'requires' => false,
56
						'downloaded' => true,
57
						'last_updated' => false,
58
						'added' => false,
59
						'tags' => false,
60
						'compatibility' => false,
61
						'homepage' => false,
62
						'donate_link' => false,
63
						'icons' => true,
64
						'banners' => true,
65
					),
66
				) );
67
68
				if ( ! is_wp_error( $api ) ) { // confirm error free
69
					$main_plugin_file = Connekt_Plugin_Installer::get_plugin_file( $plugin['slug'] ); // Get main plugin file
70
71
					if ( self::check_file_extension( $main_plugin_file ) ) { // check file extension
72
						if ( is_plugin_active( $main_plugin_file ) ) {
73
								// plugin activation, confirmed!
74
								$button_classes = 'button disabled';
75
								$button_text = __( 'Activated', 'framework' );
76
						} else {
77
							// It's installed, let's activate it
78
							$button_classes = 'activate button button-primary';
79
							$button_text = __( 'Activate', 'framework' );
80
						}
81
					}
82
83
					// Send plugin data to template
84
					self::render_template( $plugin, $api, $button_text, $button_classes );
85
				}
86
			}
87
			?>
88
			</div>
89
			<?php
90
		} // END init()
91
92
		/**
93
		 * Render display template for each plugin.
94
		 *
95
		 * @access  public
96
		 * @static
97
		 * @since   1.0
98
		 * @version 1.0.1
99
		 * @param   array  $plugin         Original data passed to init()
100
		 * @param   array  $api            Results from plugins_api
101
		 * @param   string $button_text    Text for the button
102
		 * @param   string $button_classes Class names for the button
103
		 */
104
		public static function render_template( $plugin, $api, $button_text, $button_classes ) {
0 ignored issues
show
Unused Code introduced by
The parameter $plugin is not used and could be removed.

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

Loading history...
105
			?>
106
			<div class="wp-list-table widefat plugin-install">
107
				<div id="the-list">
108
					<div class="plugin-card plugin-card-<?php echo $api->slug; ?>">
109
						<div class="plugin-card-top">
110
							<div class="name column-name">
111
								<h3>
112
									<a class="thickbox open-plugin-details-modal" href="<?php echo add_query_arg( array( 'tab' => 'plugin-information', 'plugin' => $api->slug, 'TB_iframe' => 'true', 'width' => '772', 'height' => '906' ), admin_url('plugin-install.php') ); ?>">
113
										<?php echo $api->name; ?>
114
										<img class="plugin-icon" src="<?php echo $api->icons['2x']; ?>" alt="<?php echo $api->name; ?>">
115
									</a>
116
								</h3>
117
							</div>
118
119
							<div class="desc column-description">
120
								<p><?php echo $api->short_description; ?></p>
121
								<p class="authors">
122
									<cite>
123
										<?php printf( __( 'By %s', 'framework' ), $api->author ); ?>
124
									</cite>
125
								</p>
126
							</div>
127
						</div>	
128
129
						<div class="plugin-card-bottom">
130
							<a class="<?php echo $button_classes; ?>" data-slug="<?php echo $api->slug; ?>" data-name="<?php echo $api->name; ?>" href="<?php echo add_query_arg( array( 'action' => 'install-plugin', 'plugin' => $api->slug, '_wpnonce' => wp_create_nonce( 'install-plugin_' . $api->slug ) ), admin_url( 'update.php' ) ); ?>" aria-label="<?php echo sprintf( esc_html__( 'Install %1$s %2$s now', 'framework' ), $api->name, $api->version ); ?>"><?php echo $button_text; ?></a>
131
							<a class="button thickbox open-plugin-details-modal" href="<?php echo add_query_arg( array( 'tab' => 'plugin-information', 'plugin' => $api->slug, 'TB_iframe' => 'true', 'width' => '772', 'height' => '906' ), admin_url('plugin-install.php') ); ?>" aria-label="<?php echo sprintf( esc_html__( 'More information about %s', 'framework' ), $api->name ); ?>" data-title="<?php echo $api->name; ?>"><?php _e( 'More Details', 'frameworks' ); ?></a>
132
						</div>
133
					</div>
134
				</div>
135
			</div>
136
		</div>
137
		<?php
138
		} // END render_template()
139
140
		/**
141
		 * An Ajax method for installing plugin.
142
		 *
143
		 * @access public
144
		 * @since  1.0
145
		 * @return $json
146
		 */
147
		public function cnkt_plugin_installer() {
148
			if ( ! current_user_can( 'install_plugins' ) ) {
149
				wp_die( __( 'Sorry, you are not allowed to install plugins on this site.', 'framework' ) );
150
			}
151
152
			$nonce  = $_POST["nonce"];
153
			$plugin = $_POST["plugin"];
154
155
			// Check our nonce, if they don't match then bounce!
156
			if ( ! wp_verify_nonce( $nonce, 'cnkt_installer_nonce' ) ) {
157
				wp_die( __( 'Error - unable to verify nonce, please try again.', 'framework' ) );
158
			}
159
160
			// Include required libs for installation
161
			require_once( ABSPATH . 'wp-admin/includes/plugin-install.php' );
162
			require_once( ABSPATH . 'wp-admin/includes/class-wp-upgrader.php' );
163
			require_once( ABSPATH . 'wp-admin/includes/class-wp-ajax-upgrader-skin.php' );
164
			require_once( ABSPATH . 'wp-admin/includes/class-plugin-upgrader.php' );
165
166
			// Get Plugin Info
167
			$api = plugins_api( 'plugin_information',
168
				array(
169
					'slug' => $plugin,
170
					'fields' => array(
171
						'short_description' => false,
172
						'sections' => false,
173
						'requires' => false,
174
						'rating' => false,
175
						'ratings' => false,
176
						'downloaded' => false,
177
						'last_updated' => false,
178
						'added' => false,
179
						'tags' => false,
180
						'compatibility' => false,
181
						'homepage' => false,
182
						'donate_link' => false,
183
					),
184
				)
185
			);
186
187
			$skin     = new WP_Ajax_Upgrader_Skin();
188
			$upgrader = new Plugin_Upgrader( $skin );
189
			$upgrader->install( $api->download_link );
190
191
			if ( $api->name ) {
192
				$status = 'success';
193
				$msg = sprintf( __( 'Successfully installed the plugin %s.', 'framework' ), '<strong>' . $api->name . '</strong>' );
194
			} else {
195
				$status = 'failed';
196
				$msg = sprintf( __( 'There was an error installing the plugin %s.', 'framework' ), '<strong>' . $api->name . '</strong>' );
197
			}
198
199
			$json = array(
200
				'status' => $status,
201
				'msg'    => $msg,
202
			);
203
204
			wp_send_json($json);
205
		} // END cnkt_plugin_installer()
206
207
		/**
208
		 * Activate plugin via Ajax.
209
		 *
210
		 * @access public
211
		 * @since  1.0
212
		 * @return $json
213
		 */
214
		public function cnkt_plugin_activation(){
215
			if ( ! current_user_can( 'install_plugins' ) ) {
216
				wp_die( __( 'Sorry, you are not allowed to activate plugins on this site.', 'framework' ) );
217
			}
218
219
			$nonce  = $_POST["nonce"];
220
			$plugin = $_POST["plugin"];
221
222
			// Check our nonce, if they don't match then bounce!
223
			if ( ! wp_verify_nonce( $nonce, 'cnkt_installer_nonce' ) ) {
224
				die( __( 'Error - unable to verify nonce, please try again.', 'framework' ) );
225
			}
226
227
			// Include required libs for activation
228
			require_once( ABSPATH . 'wp-admin/includes/plugin-install.php' );
229
			require_once( ABSPATH . 'wp-admin/includes/class-wp-upgrader.php' );
230
			require_once( ABSPATH . 'wp-admin/includes/class-plugin-upgrader.php' );
231
232
			// Get Plugin Info
233
			$api = plugins_api( 'plugin_information',
234
				array(
235
					'slug' => $plugin,
236
					'fields' => array(
237
						'short_description' => false,
238
						'sections' => false,
239
						'requires' => false,
240
						'rating' => false,
241
						'ratings' => false,
242
						'downloaded' => false,
243
						'last_updated' => false,
244
						'added' => false,
245
						'tags' => false,
246
						'compatibility' => false,
247
						'homepage' => false,
248
						'donate_link' => false,
249
					),
250
				)
251
			);
252
253
			if ( $api->name ) {
254
				$main_plugin_file = Connekt_Plugin_Installer::get_plugin_file( $plugin );
255
				$status = 'success';
256
257
				if ( $main_plugin_file ) {
258
					activate_plugin( $main_plugin_file );
259
					$msg = sprintf( __( '%s successfully activated.', 'framework' ), $api->name );
260
				}
261
			} else {
262
				$status = 'failed';
263
				$msg    = sprintf( __( 'There was an error activating %s.', 'framework' ), $api->name );
264
			}
265
266
			$json = array(
267
				'status' => $status,
268
				'msg'    => $msg,
0 ignored issues
show
Bug introduced by
The variable $msg does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
269
			);
270
271
			wp_send_json( $json );
272
		} // END cnkt_plugin_activation()
273
274
		/**
275
		 * A method to get the main plugin file.
276
		 *
277
		 * @access public
278
		 * @static
279
		 * @since  1.0
280
		 * @param  string $plugin_slug The slug of the plugin
281
		 * @return $plugin_file
282
		 */
283
		public static function get_plugin_file( $plugin_slug ) {
284
			require_once( ABSPATH . '/wp-admin/includes/plugin.php' ); // Load plugin lib
285
286
			$plugins = get_plugins();
287
288
			foreach( $plugins as $plugin_file => $plugin_info ) {
289
				// Get the basename of the plugin e.g. [askismet]/askismet.php
290
				$slug = dirname( plugin_basename( $plugin_file ) );
291
292
				if ( $slug ) {
293
					if ( $slug == $plugin_slug ) {
294
						return $plugin_file; // If $slug = $plugin_name
295
					}
296
				}
297
			}
298
			return null;
299
		} // END get_plugin_file()
300
301
		/**
302
		 * A helper to check file extension
303
		 *
304
		 * @access public
305
		 * @since  1.0
306
		 * @param  string $filename The filename of the plugin
307
		 * @return boolean
308
		 */
309
		public static function check_file_extension( $filename ) {
310
			if ( substr( strrchr( $filename, '.' ), 1 ) === 'php' ) {
311
				// has .php exension
312
				return true;
313
			} else {
314
				// ./wp-content/plugins
315
				return false;
316
			}
317
		} // END check_file_extension()
318
319
		/**
320
		 * Enqueue admin scripts and scripts localization.
321
		 *
322
		 * @access  public
323
		 * @since   1.0
324
		 * @version 1.0.1
325
		 */
326
		public function enqueue_scripts() {
327
			// Thickbox
328
			wp_enqueue_script( 'thickbox' );
329
			wp_enqueue_style( 'thickbox' );
330
331
			wp_enqueue_script( 'plugin-installer', CNKT_INSTALLER_PATH. 'assets/installer.js', array( 'jquery' ));
332
			wp_localize_script( 'plugin-installer', 'cnkt_installer_localize', array(
333
				'ajax_url'      => admin_url( 'admin-ajax.php' ),
334
				'admin_nonce'   => wp_create_nonce( 'cnkt_installer_nonce' ),
335
				'install_now'   => __( 'Are you sure you want to install this plugin?', 'framework' ),
336
				'install_btn'   => __( 'Install Now', 'framework' ),
337
				'activate_btn'  => __( 'Activate', 'framework' ),
338
				'installed_btn' => __( 'Activated', 'framework' )
339
			) );
340
		}
341
	} // END enqueue_scripts()
342
343
	// Initialize
344
	$connekt_plugin_installer = new Connekt_Plugin_Installer();
345
	$connekt_plugin_installer->start();
346
}
347