Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
| Total | |
100.00% |
36 / 36 |
|
100.00% |
10 / 10 |
CRAP | |
100.00% |
1 / 1 |
| RunnerData | |
100.00% |
36 / 36 |
|
100.00% |
10 / 10 |
11 | |
100.00% |
1 / 1 |
| __construct | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
| record | |
100.00% |
11 / 11 |
|
100.00% |
1 / 1 |
2 | |||
| getMatchesMap | |
100.00% |
4 / 4 |
|
100.00% |
1 / 1 |
1 | |||
| getAllFilters | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
| getMatchedFilters | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
| getProfilingData | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
| getTotalRuntime | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
| getTotalConditions | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
| toArray | |
100.00% |
9 / 9 |
|
100.00% |
1 / 1 |
1 | |||
| fromArray | |
100.00% |
6 / 6 |
|
100.00% |
1 / 1 |
1 | |||
| 1 | <?php |
| 2 | |
| 3 | namespace MediaWiki\Extension\AbuseFilter; |
| 4 | |
| 5 | use LogicException; |
| 6 | use MediaWiki\Extension\AbuseFilter\Parser\RuleCheckerStatus; |
| 7 | |
| 8 | /** |
| 9 | * Mutable value class storing and accumulating information about filter matches and runtime |
| 10 | */ |
| 11 | class RunnerData { |
| 12 | |
| 13 | /** |
| 14 | * @param array<string,RuleCheckerStatus> $matchedFilters |
| 15 | * @param array<string,array{time: float, conds: int, result: bool}> $profilingData |
| 16 | * @param float $totalRuntime |
| 17 | * @param int $totalConditions |
| 18 | */ |
| 19 | public function __construct( |
| 20 | private array $matchedFilters = [], |
| 21 | private array $profilingData = [], |
| 22 | private float $totalRuntime = 0.0, |
| 23 | private int $totalConditions = 0 |
| 24 | ) { |
| 25 | } |
| 26 | |
| 27 | /** |
| 28 | * Record (memorize) data from a filter run |
| 29 | * |
| 30 | * @param int $filterID |
| 31 | * @param bool $global |
| 32 | * @param RuleCheckerStatus $status |
| 33 | * @param float $timeTaken |
| 34 | */ |
| 35 | public function record( int $filterID, bool $global, RuleCheckerStatus $status, float $timeTaken ): void { |
| 36 | $key = GlobalNameUtils::buildGlobalName( $filterID, $global ); |
| 37 | if ( array_key_exists( $key, $this->matchedFilters ) ) { |
| 38 | throw new LogicException( "Filter '$key' has already been recorded" ); |
| 39 | } |
| 40 | $this->matchedFilters[$key] = $status; |
| 41 | $this->profilingData[$key] = [ |
| 42 | 'time' => $timeTaken, |
| 43 | 'conds' => $status->getCondsUsed(), |
| 44 | 'result' => $status->getResult() |
| 45 | ]; |
| 46 | $this->totalRuntime += $timeTaken; |
| 47 | $this->totalConditions += $status->getCondsUsed(); |
| 48 | } |
| 49 | |
| 50 | /** |
| 51 | * Get information about filter matches in backwards compatible format |
| 52 | * @return array<string,bool> |
| 53 | */ |
| 54 | public function getMatchesMap(): array { |
| 55 | return array_map( |
| 56 | static fn ( RuleCheckerStatus $status ) => $status->getResult(), |
| 57 | $this->matchedFilters |
| 58 | ); |
| 59 | } |
| 60 | |
| 61 | /** |
| 62 | * @return string[] |
| 63 | */ |
| 64 | public function getAllFilters(): array { |
| 65 | return array_keys( $this->matchedFilters ); |
| 66 | } |
| 67 | |
| 68 | /** |
| 69 | * @return string[] |
| 70 | */ |
| 71 | public function getMatchedFilters(): array { |
| 72 | return array_keys( array_filter( $this->getMatchesMap() ) ); |
| 73 | } |
| 74 | |
| 75 | /** |
| 76 | * @return array[] |
| 77 | */ |
| 78 | public function getProfilingData(): array { |
| 79 | return $this->profilingData; |
| 80 | } |
| 81 | |
| 82 | public function getTotalRuntime(): float { |
| 83 | return $this->totalRuntime; |
| 84 | } |
| 85 | |
| 86 | public function getTotalConditions(): int { |
| 87 | return $this->totalConditions; |
| 88 | } |
| 89 | |
| 90 | /** |
| 91 | * Serialize data for edit stash |
| 92 | * @return array{matches:array<string,array>,runtime:float,condCount:int,profiling:array} |
| 93 | */ |
| 94 | public function toArray(): array { |
| 95 | return [ |
| 96 | 'matches' => array_map( |
| 97 | static fn ( RuleCheckerStatus $status ) => $status->toArray(), |
| 98 | $this->matchedFilters |
| 99 | ), |
| 100 | 'profiling' => $this->profilingData, |
| 101 | 'condCount' => $this->totalConditions, |
| 102 | 'runtime' => $this->totalRuntime, |
| 103 | ]; |
| 104 | } |
| 105 | |
| 106 | /** |
| 107 | * Deserialize data from edit stash |
| 108 | * @param array $value |
| 109 | * @return self |
| 110 | */ |
| 111 | public static function fromArray( array $value ): self { |
| 112 | return new self( |
| 113 | array_map( RuleCheckerStatus::fromArray( ... ), $value['matches'] ), |
| 114 | $value['profiling'], |
| 115 | $value['runtime'], |
| 116 | $value['condCount'] |
| 117 | ); |
| 118 | } |
| 119 | |
| 120 | } |