Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 27
0.00% covered (danger)
0.00%
0 / 2
CRAP
0.00% covered (danger)
0.00%
0 / 1
EventGateImageSuggestionFeedbackUpdater
0.00% covered (danger)
0.00%
0 / 27
0.00% covered (danger)
0.00%
0 / 2
30
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 update
0.00% covered (danger)
0.00%
0 / 25
0.00% covered (danger)
0.00%
0 / 1
20
1<?php
2
3namespace GrowthExperiments\NewcomerTasks\AddImage\EventBus;
4
5use Exception;
6use MediaWiki\Deferred\DeferredUpdates;
7use MediaWiki\Extension\EventBus\EventBusFactory;
8use MediaWiki\Page\WikiPageFactory;
9use MediaWiki\Utils\MWTimestamp;
10use MediaWiki\WikiMap\WikiMap;
11
12/**
13 * Create and send event to EventGate when image suggestions are accepted, rejected or invalidated.
14 */
15class EventGateImageSuggestionFeedbackUpdater {
16
17    private const STREAM = 'mediawiki.image_suggestions_feedback';
18    private const STREAM_VERSION = '2.1.0';
19    private const SCHEMA = '/mediawiki/page/image-suggestions-feedback/' . self::STREAM_VERSION;
20
21    private EventBusFactory $eventBusFactory;
22    private WikiPageFactory $wikiPageFactory;
23
24    /**
25     * @param EventBusFactory $eventBusFactory
26     * @param WikiPageFactory $wikiPageFactory
27     */
28    public function __construct( EventBusFactory $eventBusFactory, WikiPageFactory $wikiPageFactory ) {
29        $this->eventBusFactory = $eventBusFactory;
30        $this->wikiPageFactory = $wikiPageFactory;
31    }
32
33    /**
34     * Create an event and send it via EventBus.
35     *
36     * @param int $articleId The article ID associated with the image recommendation.
37     * @param int $userId The user ID performing the accept/reject/invalidate action.
38     * @param bool|null $accepted True if accepted, false if rejected, null if invalidating for
39     * other reasons (e.g. image exists on page when user visits it)
40     * @param string $filename The filename, without the File: prefix
41     * @param string|null $sectionTitle Title of the section the suggestion is for
42     * @param int|null $sectionNumber Number of the section the suggestion is for
43     * @param array|null $rejectionReasons List of rejection reasons. See
44     *   AddImageSubmissionHandler::REJECTION_REASONS
45     * @throws Exception
46     */
47    public function update(
48        int $articleId,
49        int $userId,
50        ?bool $accepted,
51        string $filename,
52        ?string $sectionTitle,
53        ?int $sectionNumber,
54        ?array $rejectionReasons = []
55    ): void {
56        $eventBus = $this->eventBusFactory->getInstanceForStream( self::STREAM );
57        $eventFactory = $eventBus->getFactory();
58        $attrs = [
59            'wiki' => WikiMap::getCurrentWikiId(),
60            'page_id' => $articleId,
61            'filename' => $filename,
62            'user_id' => $userId,
63            'is_accepted' => $accepted === true,
64            'is_rejected' => $accepted === false,
65            'dt' => MWTimestamp::now( TS_ISO_8601 ),
66            'origin_wiki' => 'commonswiki'
67        ];
68        if ( $rejectionReasons ) {
69            $attrs['rejection_reasons'] = $rejectionReasons;
70        }
71        if ( $sectionTitle !== null ) {
72            $attrs['section_title'] = $sectionTitle;
73        }
74        if ( $sectionNumber !== null ) {
75            $attrs['section_ordinal'] = $sectionNumber;
76        }
77        $event = $eventFactory->createEvent(
78            $this->wikiPageFactory->newFromID( $articleId )->getTitle()->getCanonicalURL(),
79            self::SCHEMA,
80            self::STREAM,
81            $attrs
82        );
83        DeferredUpdates::addCallableUpdate( fn () => $eventBus->send( [ $event ] ) );
84    }
85
86}