PluginProbe
Plugin Detective – Troubleshooting Conflicts / 1.2.31
Plugin Detective – Troubleshooting Conflicts v1.2.31
1.2.33 1.2.32 1.2.31 1.1.1 1.1.2 1.1.3 1.1.4 1.1.5 1.1.6 1.1.7 1.1.8 1.1.9 1.2 1.2.1 1.2.10 1.2.12 1.2.13 1.2.14 1.2.16 1.2.19 1.2.20 1.2.22 1.2.23 1.2.24 1.2.25 All 53 releases
plugin-detective / plugin-detective.php

plugin-detective.php in Plugin Detective – Troubleshooting Conflicts 1.2.31, at plugin-detective.php

399 lines 10.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Plugin Name: Plugin Detective - Troubleshooting Conflicts
4 * Plugin URI: https://nsquared.io
5 * Description: Quickly troubleshoot & fix plugin conflicts
6 * Version: 1.2.31
7 * Author: NSquared
8 * Donate link: https://nsquared.io
9 * License: GPLv2
10 * Text Domain: plugin-detective
11 * Domain Path: /languages
12 *
13 * @link https://nsquared.io
14 *
15 * @package Plugin_Detective
16 * @version 1.2.31
17 *
18 * Built using generator-plugin-wp (https://github.com/WebDevStudios/generator-plugin-wp)
19 */
20
21 /**
22 * Copyright (c) 2018 NSquared (email : support@nsqua.red)
23 *
24 * This program is free software; you can redistribute it and/or modify
25 * it under the terms of the GNU General Public License, version 2 or, at
26 * your discretion, any later version, as published by the Free
27 * Software Foundation.
28 *
29 * This program is distributed in the hope that it will be useful,
30 * but WITHOUT ANY WARRANTY; without even the implied warranty of
31 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
32 * GNU General Public License for more details.
33 *
34 * You should have received a copy of the GNU General Public License
35 * along with this program; if not, write to the Free Software
36 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
37 */
38
39 // Prevent direct access to this file.
40 defined( 'ABSPATH' ) || exit;
41
42 /**
43 * Autoloads files with classes when needed.
44 *
45 * @since 0.0.0
46 * @param string $class_name Name of the class being requested.
47 */
48 function plugin_detective_autoload_classes( $class_name ) {
49
50 // If our class doesn't have our prefix, don't load it.
51 if ( 0 !== strpos( $class_name, 'PD_' ) ) {
52 return;
53 }
54
55 // Set up our filename.
56 $filename = strtolower( str_replace( '_', '-', substr( $class_name, strlen( 'PD_' ) ) ) );
57
58 // Include our file.
59 Plugin_Detective::include_file( 'includes/class-' . $filename );
60 }
61 spl_autoload_register( 'plugin_detective_autoload_classes' );
62
63 /**
64 * Main initiation class.
65 *
66 * @since 0.0.0
67 */
68 final class Plugin_Detective {
69
70 /**
71 * Current version.
72 *
73 * @var string
74 * @since 0.0.0
75 */
76 const VERSION = '1.2.31';
77
78 /**
79 * wp admin instance class
80 *
81 * @var string
82 * @since 0.0.0
83 */
84 protected $wp_admin = null;
85
86 /**
87 * URL of plugin directory.
88 *
89 * @var string
90 * @since 0.0.0
91 */
92 protected $url = '';
93
94 /**
95 * Path of plugin directory.
96 *
97 * @var string
98 * @since 0.0.0
99 */
100 protected $path = '';
101
102 /**
103 * Plugin basename.
104 *
105 * @var string
106 * @since 0.0.0
107 */
108 protected $basename = '';
109
110 /**
111 * Detailed activation error messages.
112 *
113 * @var array
114 * @since 0.0.0
115 */
116 protected $activation_errors = array();
117
118 /**
119 * Singleton instance of plugin.
120 *
121 * @var Plugin_Detective
122 * @since 0.0.0
123 */
124 protected static $single_instance = null;
125
126 /**
127 * Creates or returns an instance of this class.
128 *
129 * @since 0.0.0
130 * @return Plugin_Detective A single instance of this class.
131 */
132 public static function get_instance() {
133 if ( null === self::$single_instance ) {
134 self::$single_instance = new self();
135 }
136
137 return self::$single_instance;
138 }
139
140 /**
141 * Sets up our plugin.
142 *
143 * @since 0.0.0
144 */
145 protected function __construct() {
146 $this->basename = plugin_basename( __FILE__ );
147 $this->url = plugin_dir_url( __FILE__ );
148 $this->path = plugin_dir_path( __FILE__ );
149 }
150
151 /**
152 * Attach other plugin classes to the base plugin class.
153 *
154 * @since 0.0.0
155 */
156 public function plugin_classes() {
157 $this->wp_admin = new PD_Wp_Admin( $this );
158 } // END OF PLUGIN CLASSES FUNCTION
159
160 /**
161 * Add hooks and filters.
162 * Priority needs to be
163 * < 10 for CPT_Core,
164 * < 5 for Taxonomy_Core,
165 * and 0 for Widgets because widgets_init runs at init priority 1.
166 *
167 * @since 0.0.0
168 */
169 public function hooks() {
170 add_action( 'init', array( $this, 'init' ), 0 );
171 }
172
173 /**
174 * Activate the plugin.
175 *
176 * @since 0.0.0
177 */
178 public function _activate() {
179 // Bail early if requirements aren't met.
180 if ( ! $this->check_requirements() ) {
181 return;
182 }
183
184 // Make sure any rewrite functionality has been loaded.
185 flush_rewrite_rules();
186 }
187
188 /**
189 * Deactivate the plugin.
190 * Uninstall routines should be in uninstall.php.
191 *
192 * @since 0.0.0
193 */
194 public function _deactivate() {
195 // Add deactivation cleanup functionality here.
196 }
197
198 /**
199 * Init hooks
200 *
201 * @since 0.0.0
202 */
203 public function init() {
204
205 // Bail early if requirements aren't met.
206 if ( ! $this->check_requirements() ) {
207 return;
208 }
209
210 // Initialize plugin classes.
211 $this->plugin_classes();
212 }
213
214 /**
215 * Check if the plugin meets requirements and
216 * disable it if they are not present.
217 *
218 * @since 0.0.0
219 *
220 * @return boolean True if requirements met, false if not.
221 */
222 public function check_requirements() {
223
224 // Bail early if plugin meets requirements.
225 if ( $this->meets_requirements() ) {
226 return true;
227 }
228
229 // Add a dashboard notice.
230 add_action( 'all_admin_notices', array( $this, 'requirements_not_met_notice' ) );
231
232 // Deactivate our plugin.
233 add_action( 'admin_init', array( $this, 'deactivate_me' ) );
234
235 // Didn't meet the requirements.
236 return false;
237 }
238
239 /**
240 * Deactivates this plugin, hook this function on admin_init.
241 *
242 * @since 0.0.0
243 */
244 public function deactivate_me() {
245
246 // We do a check for deactivate_plugins before calling it, to protect
247 // any developers from accidentally calling it too early and breaking things.
248 if ( function_exists( 'deactivate_plugins' ) ) {
249 deactivate_plugins( $this->basename );
250 }
251 }
252
253 /**
254 * Check that all plugin requirements are met.
255 *
256 * @since 0.0.0
257 *
258 * @return boolean True if requirements are met.
259 */
260 public function meets_requirements() {
261
262 // Do checks for required classes / functions or similar.
263 // Add detailed messages to $this->activation_errors array.
264 if ( defined( 'MULTISITE' ) && MULTISITE || ( function_exists( 'is_multsite' ) && is_multsite() ) ) {
265 $this->activation_errors[] = '<h3>Plugin Detective doesn\'t support multisite (yet)</h3>
266 <p>Unfortunately we don\'t support multisite yet. We wanted to get Plugin Detective out there for people to use as soon as possible, but there’s a good amount of work to do before it will support multisite. As you may know, multisite can get a bit complicated.</p>
267
268 <p>With a single install, it’s easy to determine which plugins are active and manipulate them. With a multisite, there are network-activated plugins and plugins at the site level. And theoretically Plugin Detective could be run the whole network, or just looking at a single site. And there are permission differences between a network admin and a site admin. So it will take some work for us to support all that. We want to see how much interest there is in supporting multisite, and get some feedback from multisite users to understand what would be most useful for them and how they’d use it.</p>
269
270 <p><strong>If you\'re reading this, you likely want to use Plugin Detective to troubleshoot multisite installs. Please send us an email</strong> (<a href="mailto:support@tylerdigital.com">support@tylerdigital.com</a>) to let us know you\'re interested and answer a few questions to help us build this the right way:</p>
271
272 <p>Would this just be a tool for you (the network admin)?<br />
273 Or would you want your site admins to be able to run it (and I assume they could only test their site-activated plugins, not disable any that you’ve network-activated?)</p>
274
275 <p>Thanks,<br />
276 Nathan & Natalie</p>';
277 }
278
279 if ( !empty( $this->activation_errors ) ) {
280 return false;
281 }
282
283 return true;
284 }
285
286 /**
287 * Adds a notice to the dashboard if the plugin requirements are not met.
288 *
289 * @since 0.0.0
290 */
291 public function requirements_not_met_notice() {
292
293 // Compile default message.
294 /* translators: %s: URL of the WordPress plugins admin page. */
295 $default_message = sprintf( __( 'Plugin Detective is missing requirements and has been <a href="%s">deactivated</a>. Please make sure all requirements are available.', 'plugin-detective' ), admin_url( 'plugins.php' ) );
296
297 // Default details to null.
298 $details = null;
299
300 // Add details if any exist.
301 if ( $this->activation_errors && is_array( $this->activation_errors ) ) {
302 $details = '<small>' . implode( '</small><br /><small>', $this->activation_errors ) . '</small>';
303 }
304
305 // Output errors.
306 ?>
307 <div id="message" class="error">
308 <p><?php echo wp_kses_post( $default_message ); ?></p>
309 <?php echo wp_kses_post( $details ); ?>
310 </div>
311 <?php
312 }
313
314 /**
315 * Magic getter for our object.
316 *
317 * @since 0.0.0
318 *
319 * @param string $field Field to get.
320 * @throws Exception Throws an exception if the field is invalid.
321 * @return mixed Value of the field.
322 */
323 public function __get( $field ) {
324 switch ( $field ) {
325 case 'version':
326 return self::VERSION;
327 case 'basename':
328 case 'url':
329 case 'path':
330 case 'wp_admin':
331 return $this->$field;
332 default:
333 throw new Exception( 'Invalid ' . __CLASS__ . ' property: ' . esc_html( $field ) );
334 }
335 }
336
337 /**
338 * Include a file from the includes directory.
339 *
340 * @since 0.0.0
341 *
342 * @param string $filename Name of the file to be included.
343 * @return boolean Result of include call.
344 */
345 public static function include_file( $filename ) {
346 $file = self::dir( $filename . '.php' );
347 if ( file_exists( $file ) ) {
348 return include_once( $file );
349 }
350 return false;
351 }
352
353 /**
354 * This plugin's directory.
355 *
356 * @since 0.0.0
357 *
358 * @param string $path (optional) appended path.
359 * @return string Directory and path.
360 */
361 public static function dir( $path = '' ) {
362 static $dir;
363 $dir = $dir ? $dir : trailingslashit( dirname( __FILE__ ) );
364 return $dir . $path;
365 }
366
367 /**
368 * This plugin's url.
369 *
370 * @since 0.0.0
371 *
372 * @param string $path (optional) appended path.
373 * @return string URL and path.
374 */
375 public static function url( $path = '' ) {
376 static $url;
377 $url = $url ? $url : trailingslashit( plugin_dir_url( __FILE__ ) );
378 return $url . $path;
379 }
380 }
381
382 /**
383 * Grab the Plugin_Detective object and return it.
384 * Wrapper for Plugin_Detective::get_instance().
385 *
386 * @since 0.0.0
387 * @return Plugin_Detective Singleton instance of plugin class.
388 */
389 function plugin_detective() {
390 return Plugin_Detective::get_instance();
391 }
392
393 // Kick it off.
394 add_action( 'plugins_loaded', array( plugin_detective(), 'hooks' ) );
395
396 // Activation and deactivation.
397 register_activation_hook( __FILE__, array( plugin_detective(), '_activate' ) );
398 register_deactivation_hook( __FILE__, array( plugin_detective(), '_deactivate' ) );
399