@@ -147,9 +147,14 @@ public function __construct(
147147 */
148148 public function validate (): ValidationResult
149149 {
150+ $ startTime = microtime (true );
151+
150152 $ result = new ValidationResult ($ this ->config ->isStrict ());
151153 $ this ->errorHandler = new ErrorHandler ($ result , $ this ->config ->isDebugEnabled ());
152154
155+ // Count main plugin
156+ $ result ->incrementPluginCount ();
157+
153158 // Validate the main plugin
154159 $ this ->validateSinglePlugin ($ this ->plugin );
155160
@@ -159,6 +164,12 @@ public function validate(): ValidationResult
159164 'Validating subplugins '
160165 );
161166
167+ // Record total processing time if debug enabled
168+ if ($ this ->config ->isDebugEnabled ()) {
169+ $ totalTime = microtime (true ) - $ startTime ;
170+ $ result ->setProcessingTime ($ totalTime );
171+ }
172+
162173 return $ result ;
163174 }
164175
@@ -181,11 +192,24 @@ private function validateSinglePlugin(Plugin $plugin): void
181192 $ this ->extractor = new StringExtractor ();
182193 $ this ->extractor ->setFileDiscovery ($ this ->fileDiscovery );
183194
195+ // Track debug information if enabled
196+ if ($ this ->config ->isDebugEnabled ()) {
197+ // Collect file discovery metrics
198+ $ fileMetrics = $ this ->fileDiscovery ->getPerformanceMetrics ();
199+ $ this ->errorHandler ->getResult ()->addFileCounts ($ fileMetrics ['file_types ' ]);
200+ $ this ->errorHandler ->getResult ()->addPhaseTime ('file_discovery_ ' . $ plugin ->component , $ fileMetrics ['discovery_time ' ]);
201+ }
202+
184203 // Get defined strings from language file
204+ $ phaseStart = microtime (true );
185205 $ definedStrings = $ this ->errorHandler ->safeExecute (
186206 fn () => $ this ->getDefinedStrings (),
187207 "Loading language file for {$ plugin ->component }"
188208 );
209+ if ($ this ->config ->isDebugEnabled ()) {
210+ $ this ->errorHandler ->getResult ()->addPhaseTime ('lang_loading_ ' . $ plugin ->component , microtime (true ) - $ phaseStart );
211+ $ this ->errorHandler ->getResult ()->addStringCounts (['defined_strings ' => count ($ definedStrings )]);
212+ }
189213
190214 // Basic validation - check if language file exists
191215 if (empty ($ definedStrings )) {
@@ -203,37 +227,66 @@ private function validateSinglePlugin(Plugin $plugin): void
203227 }
204228
205229 // Get plugin-specific requirements
230+ $ phaseStart = microtime (true );
206231 $ requirements = $ this ->errorHandler ->safeExecute (
207232 fn () => $ this ->requirementsResolver ->resolve ($ plugin , $ this ->moodle ->getBranch ()),
208233 "Resolving plugin requirements for {$ plugin ->component }"
209234 );
235+ if ($ this ->config ->isDebugEnabled ()) {
236+ $ this ->errorHandler ->getResult ()->addPhaseTime ('requirements_resolve_ ' . $ plugin ->component , microtime (true ) - $ phaseStart );
237+ }
210238
211239 if ($ requirements ) {
212240 // Validate required strings from requirements based on the plugin type.
241+ $ phaseStart = microtime (true );
213242 $ this ->errorHandler ->safeExecute (
214243 fn () => $ this ->validateRequiredStrings ($ requirements ->getRequiredStrings (), $ definedStrings ),
215244 "Validating required strings for {$ plugin ->component }"
216245 );
246+ if ($ this ->config ->isDebugEnabled ()) {
247+ $ this ->errorHandler ->getResult ()->addPhaseTime ('required_validation_ ' . $ plugin ->component , microtime (true ) - $ phaseStart );
248+ $ this ->errorHandler ->getResult ()->addStringCounts (['required_strings ' => count ($ requirements ->getRequiredStrings ())]);
249+ }
217250 }
218251
219252 // Run string checkers for database files and other sources.
253+ $ phaseStart = microtime (true );
220254 $ this ->errorHandler ->safeExecute (
221255 fn () => $ this ->runStringCheckers ($ definedStrings ),
222256 "Running string checkers for {$ plugin ->component }"
223257 );
258+ if ($ this ->config ->isDebugEnabled ()) {
259+ $ this ->errorHandler ->getResult ()->addPhaseTime ('checkers_ ' . $ plugin ->component , microtime (true ) - $ phaseStart );
260+ }
224261
225262 // Find and validate used strings in the plugin code.
263+ $ phaseStart = microtime (true );
226264 $ this ->errorHandler ->safeExecute (
227265 fn () => $ this ->validateUsedStrings ($ definedStrings ),
228266 "Validating used strings for {$ plugin ->component }"
229267 );
268+ if ($ this ->config ->isDebugEnabled ()) {
269+ $ this ->errorHandler ->getResult ()->addPhaseTime ('used_validation_ ' . $ plugin ->component , microtime (true ) - $ phaseStart );
270+
271+ // Collect string extraction metrics
272+ $ extractorMetrics = $ this ->extractor ->getPerformanceMetrics ();
273+ $ this ->errorHandler ->getResult ()->addStringCounts ([
274+ 'strings_extracted ' => $ extractorMetrics ['strings_extracted ' ],
275+ 'string_usages_found ' => $ extractorMetrics ['string_usages_found ' ],
276+ ]);
277+ $ this ->errorHandler ->getResult ()->addPhaseTime ('string_extraction_ ' . $ plugin ->component , $ extractorMetrics ['extraction_time ' ]);
278+ }
230279
231280 // Check for unused strings if requested.
232281 if ($ this ->config ->shouldCheckUnused ()) {
282+ $ phaseStart = microtime (true );
233283 $ this ->errorHandler ->safeExecute (
234284 fn () => $ this ->validateUnusedStrings ($ definedStrings , $ requirements ),
235285 "Checking for unused strings in {$ plugin ->component }"
236286 );
287+ if ($ this ->config ->isDebugEnabled ()) {
288+ $ this ->errorHandler ->getResult ()->addPhaseTime ('unused_validation_ ' . $ plugin ->component , microtime (true ) - $ phaseStart );
289+ }
237290 }
238291 } finally {
239292 // Restore original plugin and file discovery
@@ -255,6 +308,9 @@ private function validateSubplugins(): void
255308 }
256309
257310 foreach ($ subplugins as $ subplugin ) {
311+ // Count each subplugin
312+ $ this ->errorHandler ->getResult ()->incrementSubpluginCount ();
313+
258314 $ this ->errorHandler ->safeExecute (
259315 fn () => $ this ->validateSinglePlugin ($ subplugin ),
260316 "Validating subplugin {$ subplugin ->component }" ,
0 commit comments