Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
0.00% |
0 / 63 |
|
0.00% |
0 / 4 |
CRAP | |
0.00% |
0 / 1 |
SpecialORESModels | |
0.00% |
0 / 63 |
|
0.00% |
0 / 4 |
240 | |
0.00% |
0 / 1 |
__construct | |
0.00% |
0 / 3 |
|
0.00% |
0 / 1 |
2 | |||
execute | |
0.00% |
0 / 22 |
|
0.00% |
0 / 1 |
12 | |||
getFilterData | |
0.00% |
0 / 30 |
|
0.00% |
0 / 1 |
110 | |||
getFilterLabel | |
0.00% |
0 / 8 |
|
0.00% |
0 / 1 |
2 |
1 | <?php |
2 | |
3 | namespace ORES\Specials; |
4 | |
5 | use MediaWiki\Html\TemplateParser; |
6 | use MediaWiki\SpecialPage\SpecialPage; |
7 | use ORES\Storage\ModelLookup; |
8 | use ORES\Storage\ThresholdLookup; |
9 | |
10 | class SpecialORESModels extends SpecialPage { |
11 | |
12 | /** @var ModelLookup */ |
13 | private $modelLookup; |
14 | |
15 | /** @var ThresholdLookup */ |
16 | private $thresholdLookup; |
17 | |
18 | public function __construct( ModelLookup $modelLookup, ThresholdLookup $thresholdLookup ) { |
19 | parent::__construct( 'ORESModels' ); |
20 | $this->modelLookup = $modelLookup; |
21 | $this->thresholdLookup = $thresholdLookup; |
22 | } |
23 | |
24 | public function execute( $subPage = null ) { |
25 | parent::execute( $subPage ); |
26 | $this->addHelpLink( 'ORES' ); |
27 | |
28 | $models = []; |
29 | foreach ( $this->modelLookup->getModels() as $modelName => $modelData ) { |
30 | $filters = $this->getFilterData( $modelName ); |
31 | if ( $filters === false ) { |
32 | continue; |
33 | } |
34 | |
35 | $models[] = [ |
36 | 'model' => $modelName, |
37 | 'title' => $this->msg( "ores-rcfilters-$modelName-title" )->text(), |
38 | 'filters' => $filters |
39 | ]; |
40 | } |
41 | |
42 | $templateParser = new TemplateParser( dirname( __DIR__ ) . '/templates' ); |
43 | $this->getOutput()->addHTML( $templateParser->processTemplate( |
44 | 'SpecialORESModels', |
45 | [ |
46 | 'models' => $models, |
47 | 'header-filter' => $this->msg( 'ores-specialoresmodels-header-filter' )->text(), |
48 | 'header-thresholdrange' => $this->msg( 'ores-specialoresmodels-header-thresholdrange' )->text(), |
49 | ] |
50 | ) ); |
51 | $this->getOutput()->addModuleStyles( 'ext.ores.styles' ); |
52 | } |
53 | |
54 | private function getFilterData( $modelName ) { |
55 | $thresholdConfig = $this->getConfig()->get( 'OresFiltersThresholds' ); |
56 | $thresholdData = $this->thresholdLookup->getRawThresholdData( $modelName ); |
57 | $thresholds = $this->thresholdLookup->getThresholds( $modelName ); |
58 | if ( $thresholds === [] || $thresholdData === false ) { |
59 | return false; |
60 | } |
61 | if ( !in_array( $modelName, [ 'damaging', 'goodfaith', 'revertrisklanguageagnostic' ] ) ) { |
62 | return false; |
63 | } |
64 | |
65 | $filters = []; |
66 | foreach ( $thresholdConfig[$modelName] as $filterName => $filterMinMax ) { |
67 | if ( $filterMinMax === false ) { |
68 | continue; |
69 | } |
70 | |
71 | $min = isset( $thresholds[$filterName]['min'] ) ? |
72 | $this->getLanguage()->formatNum( $thresholds[$filterName]['min'] ) : |
73 | '???'; |
74 | $max = isset( $thresholds[$filterName]['max'] ) ? |
75 | $this->getLanguage()->formatNum( $thresholds[$filterName]['max'] ) : |
76 | '???'; |
77 | |
78 | $filters[] = [ |
79 | 'name' => $filterName, |
80 | 'label' => $this->getFilterLabel( $modelName, $filterName ), |
81 | 'threshold-min' => $min, |
82 | 'threshold-max' => $max, |
83 | ]; |
84 | } |
85 | // Sort the filters we know about in the proper order, put ones we don't know about at the end |
86 | uasort( $filters, static function ( $a, $b ) { |
87 | $knownFilters = [ 'likelygood', 'maybebad', 'likelybad', 'verylikelybad' ]; |
88 | $aIndex = array_search( $a['name'], $knownFilters ); |
89 | $bIndex = array_search( $b['name'], $knownFilters ); |
90 | return ( $aIndex !== false ? $aIndex : INF ) <=> ( $bIndex !== false ? $bIndex : INF ); |
91 | } ); |
92 | return $filters; |
93 | } |
94 | |
95 | /** |
96 | * Get the UI label for a filter as it appears in RecentChanges. |
97 | * @param string $modelName 'damaging' or 'goodfaith' |
98 | * @param string $filterName 'likelygood', 'maybebad', 'likelybad' or 'verylikelybad' |
99 | * @return string Filter label (plain text) |
100 | */ |
101 | private function getFilterLabel( $modelName, $filterName ) { |
102 | // TODO factor this out in ChangesListHooksHandler |
103 | $special = [ |
104 | 'goodfaith' => [ |
105 | 'likelygood' => 'ores-rcfilters-goodfaith-good-label', |
106 | 'likelybad' => 'ores-rcfilters-goodfaith-bad-label', |
107 | ] |
108 | ]; |
109 | $msgKey = $special[$modelName][$filterName] ?? "ores-rcfilters-$modelName-$filterName-label"; |
110 | return $this->msg( $msgKey )->text(); |
111 | } |
112 | |
113 | } |