Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
44.44% covered (danger)
44.44%
32 / 72
25.00% covered (danger)
25.00%
1 / 4
CRAP
0.00% covered (danger)
0.00%
0 / 1
NewsletterDataUpdate
44.44% covered (danger)
44.44%
32 / 72
25.00% covered (danger)
25.00%
1 / 4
53.58
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
1
 getNewslettersWithNewsletterMainPage
0.00% covered (danger)
0.00%
0 / 12
0.00% covered (danger)
0.00%
0 / 1
2
 createNewNewsletterWithData
0.00% covered (danger)
0.00%
0 / 19
0.00% covered (danger)
0.00%
0 / 1
20
 doUpdate
76.32% covered (warning)
76.32%
29 / 38
0.00% covered (danger)
0.00%
0 / 1
10.08
1<?php
2
3namespace MediaWiki\Extension\Newsletter\Content;
4
5use MediaWiki\Deferred\DataUpdate;
6use MediaWiki\Extension\Newsletter\Newsletter;
7use MediaWiki\Extension\Newsletter\NewsletterStore;
8use MediaWiki\Extension\Newsletter\NewsletterValidator;
9use MediaWiki\Logger\LoggerFactory;
10use MediaWiki\MediaWikiServices;
11use MediaWiki\Title\Title;
12use MediaWiki\User\User;
13
14/**
15 * @license GPL-2.0-or-later
16 * @author tonythomas
17 */
18class NewsletterDataUpdate extends DataUpdate {
19
20    /** @var NewsletterContent */
21    private $content;
22    /** @var User Triggering user */
23    private $user;
24    /** @var Title */
25    private $title;
26
27    /**
28     * @param NewsletterContent $content
29     * @param Title $title
30     * @param User $user
31     *
32     * @todo User might be wrong if triggered from template edits etc.
33     */
34    public function __construct( NewsletterContent $content, Title $title, User $user ) {
35        $this->content = $content;
36        $this->user = $user;
37        $this->title = $title;
38    }
39
40    /**
41     * @param string $newNewsletterName
42     * @return int
43     */
44    protected function getNewslettersWithNewsletterMainPage( $newNewsletterName ) {
45        $dbr = MediaWikiServices::getInstance()->getDBLoadBalancer()->getConnection( DB_REPLICA );
46
47        return $dbr->newSelectQueryBuilder()
48            ->select( '*' )
49            ->from( 'nl_newsletters' )
50            ->where(
51                $dbr->expr( 'nl_name', '=', $newNewsletterName )->orExpr(
52                    $dbr->expr( 'nl_main_page_id', '=', $this->content->getMainPage()->getArticleID() )
53                        ->and( 'nl_active', '=', 1 )
54                )
55            )
56            ->caller( __METHOD__ )
57            ->fetchRowCount();
58    }
59
60    protected function createNewNewsletterWithData( NewsletterStore $store, $formData ) {
61        $newNewsletterName = $formData['Name'];
62        if ( $this->getNewslettersWithNewsletterMainPage( $newNewsletterName ) ) {
63            return false;
64        }
65
66        $validator = new NewsletterValidator( $formData );
67        $validation = $validator->validate( true );
68
69        if ( !$validation->isGood() ) {
70            // Invalid input was entered
71            return $validation;
72        }
73
74        $title = Title::makeTitleSafe( NS_NEWSLETTER, $newNewsletterName );
75        $newsletter = new Newsletter( 0,
76            $title->getText(),
77            $formData['Description'],
78            $formData['MainPage']->getArticleID()
79        );
80
81        $newsletterCreated = $store->addNewsletter( $newsletter );
82        if ( !$newsletterCreated ) {
83            return false;
84        }
85
86        $newsletter->subscribe( $this->user );
87        $store->addPublisher( $newsletter, [ $this->user->getId() ] );
88
89        return $newsletter;
90    }
91
92    public function doUpdate() {
93        $logger = LoggerFactory::getInstance( 'newsletter' );
94        $store = NewsletterStore::getDefaultInstance();
95        // We might have a situation when the newsletter is not created yet. Hence, we should add
96        // that to the database, and exit.
97        $newsletter = Newsletter::newFromName( $this->title->getText() );
98
99        $formData = [
100            'Name' => $this->title->getText(),
101            'Description' => $this->content->getDescription(),
102            'MainPage' => $this->content->getMainPage()
103        ];
104
105        if ( !$newsletter ) {
106            // Creating a new newsletter that newsletter is not in the
107            // database yet.
108            $newsletter = $this->createNewNewsletterWithData( $store, $formData );
109            if ( !$newsletter ) {
110                // Couldn't insert to the DB..
111                $logger->warning( 'newsletter-create-error' );
112                return;
113            }
114        }
115        // This was a possible edit to an existing newsletter.
116        $newsletterId = $newsletter->getId();
117
118        if ( $this->content->getDescription() != $newsletter->getDescription() ) {
119            $store->updateDescription( $newsletterId, $this->content->getDescription() );
120        }
121
122        $updatedMainPageId = $this->content->getMainPage()->getArticleID();
123        if ( $updatedMainPageId != $newsletter->getPageId() ) {
124            $store->updateMainPage( $newsletterId, $updatedMainPageId );
125        }
126
127        $updatedPublishers = array_map( [ User::class, 'newFromName' ], $this->content->getPublishers() );
128        $oldPublishersIds = $newsletter->getPublishers();
129        $updatedPublishersIds = [];
130
131        foreach ( $updatedPublishers as $user ) {
132            if ( $user instanceof User ) {
133                $updatedPublishersIds[] = $user->getId();
134            }
135        }
136        // Do the actual modifications now
137        $added = array_diff( $updatedPublishersIds, $oldPublishersIds );
138        $removed = array_diff( $oldPublishersIds, $updatedPublishersIds );
139
140        // Check if people have been added
141        if ( $added ) {
142            // Adds the new publishers to subscription list
143            $store->addSubscription( $newsletter, $added );
144            $store->addPublisher( $newsletter, $added );
145            $newsletter->notifyPublishers(
146                $added, $this->user, Newsletter::NEWSLETTER_PUBLISHERS_ADDED
147            );
148        }
149
150        // Check if people have been removed
151        if ( $removed ) {
152            $store->removePublisher( $newsletter, $removed );
153            $newsletter->notifyPublishers(
154                $removed, $this->user, Newsletter::NEWSLETTER_PUBLISHERS_REMOVED
155            );
156        }
157    }
158
159}