Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 23
0.00% covered (danger)
0.00%
0 / 4
CRAP
0.00% covered (danger)
0.00%
0 / 1
LinkRecommendationHelper
0.00% covered (danger)
0.00%
0 / 23
0.00% covered (danger)
0.00%
0 / 4
72
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
2
 getLinkRecommendation
0.00% covered (danger)
0.00%
0 / 10
0.00% covered (danger)
0.00%
0 / 1
20
 deleteLinkRecommendation
0.00% covered (danger)
0.00%
0 / 7
0.00% covered (danger)
0.00%
0 / 1
6
 configError
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
1<?php
2
3namespace GrowthExperiments\NewcomerTasks\AddLink;
4
5use GrowthExperiments\ErrorException;
6use GrowthExperiments\NewcomerTasks\ConfigurationLoader\ConfigurationLoader;
7use GrowthExperiments\NewcomerTasks\TaskType\LinkRecommendationTaskType;
8use GrowthExperiments\NewcomerTasks\TaskType\LinkRecommendationTaskTypeHandler;
9use GrowthExperiments\Util;
10use GrowthExperiments\WikiConfigException;
11use MediaWiki\Deferred\DeferredUpdates;
12use MediaWiki\Linker\LinkTarget;
13use MediaWiki\Page\ProperPageIdentity;
14use StatusValue;
15
16/**
17 * Shared functionality for various classes that consume link recommendations.
18 */
19class LinkRecommendationHelper {
20
21    /** @var ConfigurationLoader */
22    private $configurationLoader;
23
24    /** @var LinkRecommendationProvider */
25    private $linkRecommendationProvider;
26
27    /** @var LinkRecommendationStore */
28    private $linkRecommendationStore;
29
30    /** @var callable */
31    private $cirrusSearchFactory;
32
33    /**
34     * @param ConfigurationLoader $configurationLoader
35     * @param LinkRecommendationProvider $linkRecommendationProvider
36     * @param LinkRecommendationStore $linkRecommendationStore
37     * @param callable $cirrusSearchFactory A factory method returning a CirrusSearch instance.
38     */
39    public function __construct(
40        ConfigurationLoader $configurationLoader,
41        LinkRecommendationProvider $linkRecommendationProvider,
42        LinkRecommendationStore $linkRecommendationStore,
43        callable $cirrusSearchFactory
44    ) {
45        $this->configurationLoader = $configurationLoader;
46        $this->linkRecommendationProvider = $linkRecommendationProvider;
47        $this->linkRecommendationStore = $linkRecommendationStore;
48        $this->cirrusSearchFactory = $cirrusSearchFactory;
49    }
50
51    /**
52     * Return the link recommendation stored for the given title.
53     * Returns null when all links of the recommendation are invalid.
54     * @param LinkTarget $title
55     * @return LinkRecommendation|null
56     * @throws ErrorException
57     */
58    public function getLinkRecommendation( LinkTarget $title ): ?LinkRecommendation {
59        $taskTypeId = LinkRecommendationTaskTypeHandler::TASK_TYPE_ID;
60        $taskType = $this->configurationLoader->getTaskTypes()[$taskTypeId] ?? null;
61        if ( !$taskType ) {
62            throw $this->configError( "No such task type: $taskTypeId" );
63        } elseif ( !$taskType instanceof LinkRecommendationTaskType ) {
64            throw $this->configError( "Not a link recommendation task type: $taskTypeId" );
65        }
66        $linkRecommendation = $this->linkRecommendationProvider->get( $title, $taskType );
67        if ( $linkRecommendation instanceof StatusValue ) {
68            throw new ErrorException( $linkRecommendation );
69        }
70        return $linkRecommendation;
71    }
72
73    /**
74     * Delete recommendations for a given page from the database and optionally from the search index.
75     * @param ProperPageIdentity $pageIdentity
76     * @param bool $deleteFromSearchIndex
77     */
78    public function deleteLinkRecommendation(
79        ProperPageIdentity $pageIdentity,
80        bool $deleteFromSearchIndex
81    ): void {
82        DeferredUpdates::addCallableUpdate( function () use ( $pageIdentity ) {
83            $this->linkRecommendationStore->deleteByPageIds( [ $pageIdentity->getId() ] );
84        } );
85        if ( $deleteFromSearchIndex ) {
86            $cirrusSearch = ( $this->cirrusSearchFactory )();
87            $cirrusSearch->resetWeightedTags( $pageIdentity,
88                LinkRecommendationTaskTypeHandler::WEIGHTED_TAG_PREFIX );
89        }
90    }
91
92    /**
93     * @param string $errorMessage
94     * @return ErrorException
95     */
96    private function configError( string $errorMessage ): ErrorException {
97        Util::logException( new WikiConfigException( $errorMessage ) );
98        return new ErrorException( StatusValue::newFatal( 'rawmessage', $errorMessage ) );
99    }
100
101}