PluginProbe
Plugin Detective – Troubleshooting Conflicts / url-works
Plugin Detective – Troubleshooting Conflicts vurl-works
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 url-works, at plugin-detective.php

391 lines 10.6 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.3
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.1
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.1';
75
76 /**
77 * URL of plugin directory.
78 *
79 * @var string
80 * @since 0.0.0
81 */
82 protected $url = '';
83
84 /**
85 * Path of plugin directory.
86 *
87 * @var string
88 * @since 0.0.0
89 */
90 protected $path = '';
91
92 /**
93 * Plugin basename.
94 *
95 * @var string
96 * @since 0.0.0
97 */
98 protected $basename = '';
99
100 /**
101 * Detailed activation error messages.
102 *
103 * @var array
104 * @since 0.0.0
105 */
106 protected $activation_errors = array();
107
108 /**
109 * Singleton instance of plugin.
110 *
111 * @var Plugin_Detective
112 * @since 0.0.0
113 */
114 protected static $single_instance = null;
115
116 /**
117 * Creates or returns an instance of this class.
118 *
119 * @since 0.0.0
120 * @return Plugin_Detective A single instance of this class.
121 */
122 public static function get_instance() {
123 if ( null === self::$single_instance ) {
124 self::$single_instance = new self();
125 }
126
127 return self::$single_instance;
128 }
129
130 /**
131 * Sets up our plugin.
132 *
133 * @since 0.0.0
134 */
135 protected function __construct() {
136 $this->basename = plugin_basename( __FILE__ );
137 $this->url = plugin_dir_url( __FILE__ );
138 $this->path = plugin_dir_path( __FILE__ );
139 }
140
141 /**
142 * Attach other plugin classes to the base plugin class.
143 *
144 * @since 0.0.0
145 */
146 public function plugin_classes() {
147 $this->wp_admin = new PD_Wp_Admin( $this );
148 } // END OF PLUGIN CLASSES FUNCTION
149
150 /**
151 * Add hooks and filters.
152 * Priority needs to be
153 * < 10 for CPT_Core,
154 * < 5 for Taxonomy_Core,
155 * and 0 for Widgets because widgets_init runs at init priority 1.
156 *
157 * @since 0.0.0
158 */
159 public function hooks() {
160 add_action( 'init', array( $this, 'init' ), 0 );
161 }
162
163 /**
164 * Activate the plugin.
165 *
166 * @since 0.0.0
167 */
168 public function _activate() {
169 // Bail early if requirements aren't met.
170 if ( ! $this->check_requirements() ) {
171 return;
172 }
173
174 // Make sure any rewrite functionality has been loaded.
175 flush_rewrite_rules();
176 }
177
178 /**
179 * Deactivate the plugin.
180 * Uninstall routines should be in uninstall.php.
181 *
182 * @since 0.0.0
183 */
184 public function _deactivate() {
185 // Add deactivation cleanup functionality here.
186 }
187
188 /**
189 * Init hooks
190 *
191 * @since 0.0.0
192 */
193 public function init() {
194
195 // Bail early if requirements aren't met.
196 if ( ! $this->check_requirements() ) {
197 return;
198 }
199
200 // Load translated strings for plugin.
201 load_plugin_textdomain( 'plugin-detective', false, dirname( $this->basename ) . '/languages/' );
202
203 // Initialize plugin classes.
204 $this->plugin_classes();
205 }
206
207 /**
208 * Check if the plugin meets requirements and
209 * disable it if they are not present.
210 *
211 * @since 0.0.0
212 *
213 * @return boolean True if requirements met, false if not.
214 */
215 public function check_requirements() {
216
217 // Bail early if plugin meets requirements.
218 if ( $this->meets_requirements() ) {
219 return true;
220 }
221
222 // Add a dashboard notice.
223 add_action( 'all_admin_notices', array( $this, 'requirements_not_met_notice' ) );
224
225 // Deactivate our plugin.
226 add_action( 'admin_init', array( $this, 'deactivate_me' ) );
227
228 // Didn't meet the requirements.
229 return false;
230 }
231
232 /**
233 * Deactivates this plugin, hook this function on admin_init.
234 *
235 * @since 0.0.0
236 */
237 public function deactivate_me() {
238
239 // We do a check for deactivate_plugins before calling it, to protect
240 // any developers from accidentally calling it too early and breaking things.
241 if ( function_exists( 'deactivate_plugins' ) ) {
242 deactivate_plugins( $this->basename );
243 }
244 }
245
246 /**
247 * Check that all plugin requirements are met.
248 *
249 * @since 0.0.0
250 *
251 * @return boolean True if requirements are met.
252 */
253 public function meets_requirements() {
254
255 // Do checks for required classes / functions or similar.
256 // Add detailed messages to $this->activation_errors array.
257 if ( defined( 'MULTISITE' ) && MULTISITE || ( function_exists( 'is_multsite' ) && is_multsite() ) ) {
258 $this->activation_errors[] = '<h3>Plugin Detective doesn\'t support multisite (yet)</h3>
259 <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>
260
261 <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>
262
263 <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>
264
265 <p>Would this just be a tool for you (the network admin)?<br />
266 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>
267
268 <p>Thanks,<br />
269 Nathan & Natalie</p>';
270 }
271
272 if ( !empty( $this->activation_errors ) ) {
273 return false;
274 }
275
276 return true;
277 }
278
279 /**
280 * Adds a notice to the dashboard if the plugin requirements are not met.
281 *
282 * @since 0.0.0
283 */
284 public function requirements_not_met_notice() {
285
286 // Compile default message.
287 $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' ) );
288
289 // Default details to null.
290 $details = null;
291
292 // Add details if any exist.
293 if ( $this->activation_errors && is_array( $this->activation_errors ) ) {
294 $details = '<small>' . implode( '</small><br /><small>', $this->activation_errors ) . '</small>';
295 }
296
297 // Output errors.
298 ?>
299 <div id="message" class="error">
300 <p><?php echo wp_kses_post( $default_message ); ?></p>
301 <?php echo wp_kses_post( $details ); ?>
302 </div>
303 <?php
304 }
305
306 /**
307 * Magic getter for our object.
308 *
309 * @since 0.0.0
310 *
311 * @param string $field Field to get.
312 * @throws Exception Throws an exception if the field is invalid.
313 * @return mixed Value of the field.
314 */
315 public function __get( $field ) {
316 switch ( $field ) {
317 case 'version':
318 return self::VERSION;
319 case 'basename':
320 case 'url':
321 case 'path':
322 case 'wp_admin':
323 return $this->$field;
324 default:
325 throw new Exception( 'Invalid ' . __CLASS__ . ' property: ' . $field );
326 }
327 }
328
329 /**
330 * Include a file from the includes directory.
331 *
332 * @since 0.0.0
333 *
334 * @param string $filename Name of the file to be included.
335 * @return boolean Result of include call.
336 */
337 public static function include_file( $filename ) {
338 $file = self::dir( $filename . '.php' );
339 if ( file_exists( $file ) ) {
340 return include_once( $file );
341 }
342 return false;
343 }
344
345 /**
346 * This plugin's directory.
347 *
348 * @since 0.0.0
349 *
350 * @param string $path (optional) appended path.
351 * @return string Directory and path.
352 */
353 public static function dir( $path = '' ) {
354 static $dir;
355 $dir = $dir ? $dir : trailingslashit( dirname( __FILE__ ) );
356 return $dir . $path;
357 }
358
359 /**
360 * This plugin's url.
361 *
362 * @since 0.0.0
363 *
364 * @param string $path (optional) appended path.
365 * @return string URL and path.
366 */
367 public static function url( $path = '' ) {
368 static $url;
369 $url = $url ? $url : trailingslashit( plugin_dir_url( __FILE__ ) );
370 return $url . $path;
371 }
372 }
373
374 /**
375 * Grab the Plugin_Detective object and return it.
376 * Wrapper for Plugin_Detective::get_instance().
377 *
378 * @since 0.0.0
379 * @return Plugin_Detective Singleton instance of plugin class.
380 */
381 function plugin_detective() {
382 return Plugin_Detective::get_instance();
383 }
384
385 // Kick it off.
386 add_action( 'plugins_loaded', array( plugin_detective(), 'hooks' ) );
387
388 // Activation and deactivation.
389 register_activation_hook( __FILE__, array( plugin_detective(), '_activate' ) );
390 register_deactivation_hook( __FILE__, array( plugin_detective(), '_deactivate' ) );
391