Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 32
0.00% covered (danger)
0.00%
0 / 4
CRAP
0.00% covered (danger)
0.00%
0 / 1
ArticleChangedJob
0.00% covered (danger)
0.00%
0 / 32
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 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 newSpec
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
2
 run
0.00% covered (danger)
0.00%
0 / 15
0.00% covered (danger)
0.00%
0 / 1
30
 notify
0.00% covered (danger)
0.00%
0 / 10
0.00% covered (danger)
0.00%
0 / 1
2
1<?php
2
3namespace MediaWiki\Extension\Wikistories\Jobs;
4
5use MediaWiki\Config\Config;
6use MediaWiki\Extension\Notifications\Model\Event;
7use MediaWiki\Extension\Wikistories\Hooks\EchoNotificationsHandlers;
8use MediaWiki\Extension\Wikistories\PageLinksSearch;
9use MediaWiki\Extension\Wikistories\StoryContent;
10use MediaWiki\Extension\Wikistories\StoryContentAnalyzer;
11use MediaWiki\JobQueue\IJobSpecification;
12use MediaWiki\JobQueue\Job;
13use MediaWiki\JobQueue\JobSpecification;
14use MediaWiki\Page\WikiPageFactory;
15use MediaWiki\Registration\ExtensionRegistry;
16use MediaWiki\Revision\RevisionLookup;
17use MediaWiki\Title\Title;
18use MediaWiki\User\UserIdentity;
19
20class ArticleChangedJob extends Job {
21
22    private const COMMAND = 'ArticleChangedJob';
23
24    public function __construct(
25        string $command,
26        array $params,
27        private readonly RevisionLookup $revisionLookup,
28        private readonly StoryContentAnalyzer $analyzer,
29        private readonly WikiPageFactory $wikiPageFactory,
30        private readonly PageLinksSearch $pageLinksSearch,
31        private readonly Config $config,
32    ) {
33        parent::__construct( self::COMMAND, $params );
34        // Delay to let multiple edits be deduplicated
35        $params[ 'jobReleaseTimestamp' ] = time() + 60;
36    }
37
38    public static function newSpec( int $pageId ): IJobSpecification {
39        return new JobSpecification(
40            self::COMMAND,
41            [ 'article_id' => $pageId ],
42            [ 'removeDuplicates' => true ]
43        );
44    }
45
46    /**
47     * Run the job
48     *
49     * @return bool Success
50     */
51    public function run(): bool {
52        $notify = ExtensionRegistry::getInstance()->isLoaded( 'Echo' ) &&
53            $this->config->get( 'WikistoriesNotifyAboutStoryMaintenance' );
54        $articleId = $this->params[ 'article_id' ];
55        $rev = $this->revisionLookup->getRevisionByPageId( $articleId );
56        $agent = $rev->getUser();
57        $articleTitle = $rev->getPage()->getDBkey();
58        $pageIds = $this->pageLinksSearch->getPageLinks( $articleTitle, 99 );
59        foreach ( $pageIds as $pageId ) {
60            $page = $this->wikiPageFactory->newFromID( $pageId );
61            /** @var StoryContent $story */
62            $story = $page->getContent();
63            '@phan-var StoryContent $story';
64            if ( $notify && $this->analyzer->hasOutdatedText( $story ) ) {
65                $this->notify( $agent, $page->getTitle(), $articleTitle, $rev->getId() );
66            }
67            $page->doPurge();
68        }
69        return true;
70    }
71
72    private function notify( UserIdentity $agent, Title $storyTitle, string $articleTitle, int $revId ): void {
73        Event::create( [
74            'type' => EchoNotificationsHandlers::NOTIFICATION_TYPE,
75            'agent' => $agent,
76            'title' => $storyTitle,
77            'extra' => [
78                'articleTitle' => $articleTitle,
79                'articleRevId' => $revId,
80                'notifyAgent' => true,
81            ],
82        ] );
83    }
84}