Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
66.67% covered (warning)
66.67%
12 / 18
50.00% covered (danger)
50.00%
1 / 2
CRAP
0.00% covered (danger)
0.00%
0 / 1
SubpageUserImpactLookup
66.67% covered (warning)
66.67%
12 / 18
50.00% covered (danger)
50.00%
1 / 2
7.33
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 getUserImpact
62.50% covered (warning)
62.50%
10 / 16
0.00% covered (danger)
0.00%
0 / 1
6.32
1<?php
2
3namespace GrowthExperiments\UserImpact;
4
5use GrowthExperiments\Util;
6use MediaWiki\Content\JsonContent;
7use MediaWiki\Json\FormatJson;
8use MediaWiki\Page\WikiPageFactory;
9use MediaWiki\Title\TitleValue;
10use MediaWiki\User\UserIdentity;
11use Wikimedia\Rdbms\IDBAccessObject;
12
13/**
14 * Load user impact data from JSON stored at the page `User:<name>/userimpact.json`,
15 * and potentially fall back to another lookup mechanism if it doesn't exist.
16 */
17class SubpageUserImpactLookup implements UserImpactLookup {
18
19    use ExpensiveUserImpactFallbackTrait;
20
21    private const SUBPAGE_NAME = 'userimpact.json';
22
23    /** @var WikiPageFactory */
24    private $wikiPageFactory;
25
26    /** @var UserImpactLookup */
27    private $fallbackLookup;
28
29    /**
30     * @param WikiPageFactory $wikiPageFactory
31     * @param UserImpactLookup|null $fallbackLookup
32     */
33    public function __construct(
34        WikiPageFactory $wikiPageFactory,
35        ?UserImpactLookup $fallbackLookup = null
36    ) {
37        $this->wikiPageFactory = $wikiPageFactory;
38        $this->fallbackLookup = $fallbackLookup;
39    }
40
41    /** @inheritDoc */
42    public function getUserImpact( UserIdentity $user, int $flags = IDBAccessObject::READ_NORMAL ): ?UserImpact {
43        $subpageTitle = new TitleValue( NS_USER, $user->getName() . '/' . self::SUBPAGE_NAME );
44        $subpage = $this->wikiPageFactory->newFromLinkTarget( $subpageTitle );
45
46        if ( !$subpage->exists() ) {
47            return $this->fallbackLookup ? $this->fallbackLookup->getUserImpact( $user ) : null;
48        }
49        $content = $subpage->getContent();
50        if ( !( $content instanceof JsonContent ) ) {
51            Util::logText( 'Page User:' . $user->getName() . '/'
52                . self::SUBPAGE_NAME . ' has unexpected content model ' . $content->getModel() );
53            return null;
54        }
55
56        $dataStatus = FormatJson::parse( $content->getText(), FormatJson::FORCE_ASSOC );
57        if ( !$dataStatus->isOK() ) {
58            Util::logText( 'Invalid JSON content: '
59                . $dataStatus->getWikiText( false, false, 'en' ) );
60            return null;
61        }
62        $data = $dataStatus->getValue();
63
64        return UserImpact::newFromJsonArray( $data );
65    }
66
67}