PluginProbe
Plugin Detective – Troubleshooting Conflicts / 1.1.2
Plugin Detective – Troubleshooting Conflicts v1.1.2
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 / troubleshoot / includes / class-detective.php

class-detective.php in Plugin Detective – Troubleshooting Conflicts 1.1.2, at troubleshoot/includes/class-detective.php

231 lines 7.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Troubleshoot Detective.
4 *
5 * @since 0.0.0
6 * @package Troubleshoot
7 */
8
9 /**
10 * Troubleshoot Detective.
11 *
12 * @since 0.0.0
13 */
14 class PDT_Detective {
15 /**
16 * Parent plugin class.
17 *
18 * @since 0.0.0
19 *
20 * @var Troubleshoot
21 */
22 protected $plugin = null;
23
24 /**
25 * Constructor.
26 *
27 * @since 0.0.0
28 *
29 * @param Troubleshoot $plugin Main plugin object.
30 */
31 public function __construct( $plugin ) {
32 $this->plugin = $plugin;
33 $this->hooks();
34 }
35
36 /**
37 * Initiate our hooks.
38 *
39 * @since 0.0.0
40 */
41 public function hooks() {
42
43 }
44
45 public function review_case( $case ) {
46 $next = array();
47
48 if ( !is_array( $case ) ) {
49 return new WP_Error( 'empty_case' );
50 }
51
52 if ( empty( $case['clues'] ) ) {
53 $case['clues'] = array();
54 }
55 if ( empty( $case['culprits'] ) ) {
56 $case['culprits'] = array();
57 }
58
59 $case = $this->clear_the_interrogation_room( $case );
60
61 $procedure = array(
62 array( 'method' => 'clear_suspects_based_on_clues', ),
63 array( 'method' => 'name_required_plugins_as_culprits_based_on_broken_clue', ),
64 array( 'method' => 'name_culprit_if_there_is_only_one_suspect_in_a_failed_clue', ),
65 array( 'method' => 'interrogate_by_disabling_all_plugins_if_none_are_required', ),
66 array( 'method' => 'interrogate_required_plugins_if_they_arent_cleared_yet', ),
67
68 // array( 'method' => 'declare_unsolvable_if_every_suspect_is_cleared', ),
69 // array( 'method' => 'interrogate_one_at_a_time_after_ten_clues', ),
70 array( 'method' => 'interrogate_other_half_after_clue_with_broken_outcome', ),
71 array( 'method' => 'interrogate_random_half', ),
72 );
73
74 foreach ($procedure as $key => $step) {
75 $method = $step['method'];
76 $case = $this->$method( $case );
77
78 if ( !empty( $case['stage'] ) && in_array( $case['stage'], array( 'solved', 'unsolved' ) ) ) {
79 return $case;
80 }
81
82 if ( !empty( $case['suspects_under_interrogation'] ) ) {
83 if ( in_array( 'no_required_plugins', $case['suspects_under_interrogation'] ) ) {
84 $case['suspects_under_interrogation'] = array();
85 }
86
87 $case['suspects_under_interrogation'] = array_values( array_unique( array_merge( $case['required_plugins'], $case['suspects_under_interrogation'] ) ) );
88
89 return $case;
90 }
91 }
92
93 return $case;
94 }
95
96 public function clear_the_interrogation_room( $case ) {
97 $case['suspects_under_interrogation'] = array();
98 return $case;
99 }
100
101 public function name_required_plugins_as_culprits_based_on_broken_clue( $case ) {
102 // if ( empty( $case['required_plugins'] ) ) {
103 // return $case;
104 // }
105 foreach ($case['clues'] as $key => $clue) {
106
107 if ( $clue['outcome'] == 'broken' && count( $clue['active_plugins'] ) == count( $case['required_plugins'] ) ) {
108 if ( array_diff( $case['required_plugins'], $clue['active_plugins'] ) === array() ) {
109 // We got a broken result with only the required plugins active
110 $case['outcome'] = 'required_plugins_broken';
111 $case['stage'] = 'solved';
112 return $case;
113 }
114
115 }
116 }
117
118 return $case;
119 }
120
121 public function name_culprit_if_there_is_only_one_suspect_in_a_failed_clue( $case ) {
122 foreach ($case['clues'] as $key => $clue) {
123 if ( $clue['outcome'] == 'broken' && count( array_diff( $clue['active_plugins'], $case['required_plugins'] ) ) == 1 ) {
124 $case['culprits'] = array_values( array_unique( array_merge( $case['culprits'], array_diff( $clue['active_plugins'], $case['required_plugins'] ) ) ) );
125 $case['stage'] = 'solved';
126 $case['outcome'] = 'culprits_identified';
127 return $case;
128 }
129 }
130
131 return $case;
132 }
133
134 public function clear_suspects_based_on_clues( $case ) {
135 $case['cleared_suspects'] = array();
136 foreach ($case['clues'] as $key => $clue) {
137 if ( $clue['outcome'] != 'fixed' ) {
138 continue;
139 }
140
141 $case['cleared_suspects'] = array_merge( $case['cleared_suspects'], $clue['active_plugins'] );
142 }
143
144 $case['cleared_suspects'] = array_values( array_unique( $case['cleared_suspects'] ) );
145
146 return $case;
147 }
148
149 public function interrogate_by_disabling_all_plugins_if_none_are_required( $case ) {
150 if ( !empty( $case['required_plugins'] ) ) {
151 return $case; // this procedure is only used to disable all plugins if there are no required_plugins, so we can skip this procedure if there are required plugins
152 }
153
154 if ( !empty( $case['clues'] ) ) {
155 return $case; // this procedure should only run once... and it will always be the first clue, so if we already have a clue, we can skip this procedure
156 }
157
158 $case['required_plugins'] = array();
159 $case['suspects_under_interrogation'] = array( 'no_required_plugins' );
160
161 return $case;
162 }
163
164 public function interrogate_required_plugins_if_they_arent_cleared_yet( $case ) {
165 // Let's clear the required plugins by themselves first
166 if ( !empty( $case['required_plugins'] ) ) {
167 foreach ($case['required_plugins'] as $plugin_file ) {
168 if ( !in_array( $plugin_file, $case['cleared_suspects'] ) ) {
169 // This also accounts for someone going back and modifying their required_plugins after the case is already under way
170 $case['suspects_under_interrogation'] = $case['required_plugins'];
171 return $case; // Let's test all required plugins in one set (even if we're retesting one that was previously cleared)
172 }
173 }
174 }
175
176 return $case;
177 }
178
179 public function interrogate_other_half_after_clue_with_broken_outcome( $case ) {
180 // TODO: if last clue failed, do the other half of suspects
181 if ( empty( $case['clues'] ) ) {
182 return $case;
183 }
184
185 $last_clue = $case['clues'][count($case['clues'])-1];
186 if ( $last_clue['outcome'] != 'broken' ) {
187 return $case;
188 }
189
190 if ( count($case['clues'] ) >= 2 ) {
191 $second_to_last_clue = $case['clues'][count($case['clues'])-2];
192 if ( $second_to_last_clue['outcome'] == 'broken' ) {
193 // 2 bad clues in a row means there's something wrong
194 // (possibly multiple culprits, possibly human clue-entry error)
195 // regardless of cause, we don't want an infinite loop (swapping the same 2 sets over and over)
196 $third_to_last_clue = $case['clues'][count($case['clues'])-3];
197 if ( $third_to_last_clue['outcome'] == 'broken' ) {
198 $fourth_to_last_clue = $case['clues'][count($case['clues'])-4];
199 if ( $fourth_to_last_clue['outcome'] == 'broken' ) {
200 $fifth_to_last_clue = $case['clues'][count($case['clues'])-5];
201 if ( $fifth_to_last_clue['outcome'] == 'broken' ) {
202 // if we've had 5 broken ones in a row, something's wrong
203 $case['stage'] = 'unsolved';
204 $case['outcome'] = 'broken_loop';
205 return $case;
206 }
207 }
208 }
209
210 // we'll skip this procedure and let it be handled by randomness
211 return $case;
212 }
213
214 }
215
216 $case['suspects_under_interrogation'] = array_values( array_diff( array_keys( $case['all_suspects'] ), $last_clue['active_plugins'], $case['cleared_suspects'] ) );
217
218 return $case;
219 }
220
221 public function interrogate_random_half( $case ) {
222 $remaining_suspects = array_diff( array_keys( $case['all_suspects'] ), $case['cleared_suspects'] );
223 shuffle( $remaining_suspects );
224 $number_of_new_suspects_in_next_lineup = max( floor( count( $remaining_suspects ) / 2 ), 1 );
225 $new_suspects_in_next_lineup = array_slice( $remaining_suspects, 0, $number_of_new_suspects_in_next_lineup );
226
227 $case['suspects_under_interrogation'] = $new_suspects_in_next_lineup;
228 return $case;
229 }
230 }
231