PluginProbe
Plugin Detective – Troubleshooting Conflicts / 1.2.25
Plugin Detective – Troubleshooting Conflicts v1.2.25
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.25, at plugin-detective.php

399 lines 10.7 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
4 * Plugin URI: https://nsquared.io
5 * Description: Quickly troubleshoot & fix plugin conflicts
6 * Version: 1.2.25
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.25
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
40 /**
41 * Autoloads files with classes when needed.
42 *
43 * @since 0.0.0
44 * @param string $class_name Name of the class being requested.
45 */
46 function plugin_detective_autoload_classes( $class_name ) {
47
48 // If our class doesn't have our prefix, don't load it.
49 if ( 0 !== strpos( $class_name, 'PD_' ) ) {
50 return;
51 }
52
53 // Set up our filename.
54 $filename = strtolower( str_replace( '_', '-', substr( $class_name, strlen( 'PD_' ) ) ) );
55
56 // Include our file.
57 Plugin_Detective::include_file( 'includes/class-' . $filename );
58 }
59 spl_autoload_register( 'plugin_detective_autoload_classes' );
60
61 /**
62 * Main initiation class.
63 *
64 * @since 0.0.0
65 */
66 final class Plugin_Detective {
67
68 /**
69 * Current version.
70 *
71 * @var string
72 * @since 0.0.0
73 */
74 const VERSION = '1.2.25';
75
76 /**
77 * wp admin instance class
78 *
79 * @var string
80 * @since 0.0.0
81 */
82 protected $wp_admin = null;
83
84 /**
85 * URL of plugin directory.
86 *
87 * @var string
88 * @since 0.0.0
89 */
90 protected $url = '';
91
92 /**
93 * Path of plugin directory.
94 *
95 * @var string
96 * @since 0.0.0
97 */
98 protected $path = '';
99
100 /**
101 * Plugin basename.
102 *
103 * @var string
104 * @since 0.0.0
105 */
106 protected $basename = '';
107
108 /**
109 * Detailed activation error messages.
110 *
111 * @var array
112 * @since 0.0.0
113 */
114 protected $activation_errors = array();
115
116 /**
117 * Singleton instance of plugin.
118 *
119 * @var Plugin_Detective
120 * @since 0.0.0
121 */
122 protected static $single_instance = null;
123
124 /**
125 * Creates or returns an instance of this class.
126 *
127 * @since 0.0.0
128 * @return Plugin_Detective A single instance of this class.
129 */
130 public static function get_instance() {
131 if ( null === self::$single_instance ) {
132 self::$single_instance = new self();
133 }
134
135 return self::$single_instance;
136 }
137
138 /**
139 * Sets up our plugin.
140 *
141 * @since 0.0.0
142 */
143 protected function __construct() {
144 $this->basename = plugin_basename( __FILE__ );
145 $this->url = plugin_dir_url( __FILE__ );
146 $this->path = plugin_dir_path( __FILE__ );
147 }
148
149 /**
150 * Attach other plugin classes to the base plugin class.
151 *
152 * @since 0.0.0
153 */
154 public function plugin_classes() {
155 $this->wp_admin = new PD_Wp_Admin( $this );
156 } // END OF PLUGIN CLASSES FUNCTION
157
158 /**
159 * Add hooks and filters.
160 * Priority needs to be
161 * < 10 for CPT_Core,
162 * < 5 for Taxonomy_Core,
163 * and 0 for Widgets because widgets_init runs at init priority 1.
164 *
165 * @since 0.0.0
166 */
167 public function hooks() {
168 add_action( 'init', array( $this, 'init' ), 0 );
169 }
170
171 /**
172 * Activate the plugin.
173 *
174 * @since 0.0.0
175 */
176 public function _activate() {
177 // Bail early if requirements aren't met.
178 if ( ! $this->check_requirements() ) {
179 return;
180 }
181
182 // Make sure any rewrite functionality has been loaded.
183 flush_rewrite_rules();
184 }
185
186 /**
187 * Deactivate the plugin.
188 * Uninstall routines should be in uninstall.php.
189 *
190 * @since 0.0.0
191 */
192 public function _deactivate() {
193 // Add deactivation cleanup functionality here.
194 }
195
196 /**
197 * Init hooks
198 *
199 * @since 0.0.0
200 */
201 public function init() {
202
203 // Bail early if requirements aren't met.
204 if ( ! $this->check_requirements() ) {
205 return;
206 }
207
208 // Load translated strings for plugin.
209 load_plugin_textdomain( 'plugin-detective', false, dirname( $this->basename ) . '/languages/' );
210
211 // Initialize plugin classes.
212 $this->plugin_classes();
213 }
214
215 /**
216 * Check if the plugin meets requirements and
217 * disable it if they are not present.
218 *
219 * @since 0.0.0
220 *
221 * @return boolean True if requirements met, false if not.
222 */
223 public function check_requirements() {
224
225 // Bail early if plugin meets requirements.
226 if ( $this->meets_requirements() ) {
227 return true;
228 }
229
230 // Add a dashboard notice.
231 add_action( 'all_admin_notices', array( $this, 'requirements_not_met_notice' ) );
232
233 // Deactivate our plugin.
234 add_action( 'admin_init', array( $this, 'deactivate_me' ) );
235
236 // Didn't meet the requirements.
237 return false;
238 }
239
240 /**
241 * Deactivates this plugin, hook this function on admin_init.
242 *
243 * @since 0.0.0
244 */
245 public function deactivate_me() {
246
247 // We do a check for deactivate_plugins before calling it, to protect
248 // any developers from accidentally calling it too early and breaking things.
249 if ( function_exists( 'deactivate_plugins' ) ) {
250 deactivate_plugins( $this->basename );
251 }
252 }
253
254 /**
255 * Check that all plugin requirements are met.
256 *
257 * @since 0.0.0
258 *
259 * @return boolean True if requirements are met.
260 */
261 public function meets_requirements() {
262
263 // Do checks for required classes / functions or similar.
264 // Add detailed messages to $this->activation_errors array.
265 if ( defined( 'MULTISITE' ) && MULTISITE || ( function_exists( 'is_multsite' ) && is_multsite() ) ) {
266 $this->activation_errors[] = '<h3>Plugin Detective doesn\'t support multisite (yet)</h3>
267 <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>
268
269 <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>
270
271 <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>
272
273 <p>Would this just be a tool for you (the network admin)?<br />
274 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>
275
276 <p>Thanks,<br />
277 Nathan & Natalie</p>';
278 }
279
280 if ( !empty( $this->activation_errors ) ) {
281 return false;
282 }
283
284 return true;
285 }
286
287 /**
288 * Adds a notice to the dashboard if the plugin requirements are not met.
289 *
290 * @since 0.0.0
291 */
292 public function requirements_not_met_notice() {
293
294 // Compile default message.
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: ' . $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