Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 11
0.00% covered (danger)
0.00%
0 / 2
CRAP
0.00% covered (danger)
0.00%
0 / 1
DbBackedLinkRecommendationProvider
0.00% covered (danger)
0.00%
0 / 11
0.00% covered (danger)
0.00%
0 / 2
20
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
2
 get
0.00% covered (danger)
0.00%
0 / 8
0.00% covered (danger)
0.00%
0 / 1
12
1<?php
2
3namespace GrowthExperiments\NewcomerTasks\AddLink;
4
5use GrowthExperiments\NewcomerTasks\TaskType\LinkRecommendationTaskType;
6use GrowthExperiments\NewcomerTasks\TaskType\TaskType;
7use MediaWiki\Linker\LinkTarget;
8use MediaWiki\Title\TitleFormatter;
9use StatusValue;
10use Wikimedia\Assert\Assert;
11
12/**
13 * A provider which reads the recommendation from the database. It is the caller's
14 * responsibility to make sure the recommendation has been stored there (this is
15 * usually done via refreshLinkRecommendations.php).
16 *
17 * Can fall back to a web service for convenience during debugging / local setups.
18 */
19class DbBackedLinkRecommendationProvider implements LinkRecommendationProvider {
20
21    /** @var LinkRecommendationStore */
22    private $linkRecommendationStore;
23
24    /** @var LinkRecommendationProvider|null */
25    private $fallbackProvider;
26
27    /** @var TitleFormatter */
28    private $titleFormatter;
29
30    /**
31     * @param LinkRecommendationStore $linkRecommendationStore
32     * @param LinkRecommendationProvider|null $fallbackProvider
33     * @param TitleFormatter $titleFormatter
34     */
35    public function __construct(
36        LinkRecommendationStore $linkRecommendationStore,
37        ?LinkRecommendationProvider $fallbackProvider,
38        TitleFormatter $titleFormatter
39    ) {
40        $this->linkRecommendationStore = $linkRecommendationStore;
41        $this->fallbackProvider = $fallbackProvider;
42        $this->titleFormatter = $titleFormatter;
43    }
44
45    /** @inheritDoc */
46    public function get( LinkTarget $title, TaskType $taskType ) {
47        Assert::parameterType( LinkRecommendationTaskType::class, $taskType, '$taskType' );
48        // Task type parameters are assumed to be mostly static. Invalidating the recommendations
49        // stored in the DB when the task type parameters change should be done manually
50        // via revalidateLinkRecommendations.php.
51        $linkRecommendation = $this->linkRecommendationStore->getByLinkTarget( $title );
52        if ( !$linkRecommendation ) {
53            if ( $this->fallbackProvider ) {
54                $linkRecommendation = $this->fallbackProvider->get( $title, $taskType );
55            } else {
56                // This can happen due to race conditions - the search index update is late so the
57                // user is sent to a task which has just been deleted from the DB. It could also be
58                // caused by errors in updating the index, which are important to monitor. So make
59                // this error non-fatal but track it via Util::STATSD_INCREMENTABLE_ERROR_MESSAGES.
60                $linkRecommendation = StatusValue::newGood()->error( 'growthexperiments-addlink-notinstore',
61                    $this->titleFormatter->getPrefixedText( $title ) );
62            }
63        }
64        return $linkRecommendation;
65    }
66
67}