Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 52
0.00% covered (danger)
0.00%
0 / 21
CRAP
0.00% covered (danger)
0.00%
0 / 1
Newsletter
0.00% covered (danger)
0.00%
0 / 52
0.00% covered (danger)
0.00%
0 / 21
870
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
 newFromID
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 newFromName
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getId
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 setId
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getName
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getDescription
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getPageId
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getSubscribers
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 getSubscribersCount
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getPublishers
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 isSubscribed
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 isPublisher
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 loadPublishers
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
6
 loadSubscribers
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
6
 subscribe
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
6
 unsubscribe
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
2
 canDelete
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
6
 canManage
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
6
 canRestore
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
6
 notifyPublishers
0.00% covered (danger)
0.00%
0 / 14
0.00% covered (danger)
0.00%
0 / 1
12
1<?php
2
3namespace MediaWiki\Extension\Newsletter;
4
5use EchoEvent;
6use MediaWiki\Permissions\Authority;
7use MediaWiki\Status\Status;
8use MediaWiki\User\User;
9use MediaWiki\User\UserIdentity;
10
11/**
12 * Class representing a newsletter
13 *
14 * @license GPL-2.0-or-later
15 * @author Addshore
16 * @author Glaisher
17 */
18class Newsletter {
19
20    public const NEWSLETTER_PUBLISHERS_ADDED = 'added';
21    public const NEWSLETTER_PUBLISHERS_REMOVED = 'removed';
22
23    /**
24     * @var int
25     */
26    private $id;
27
28    /**
29     * @var string
30     */
31    private $name;
32
33    /**
34     * @var string
35     */
36    private $description;
37
38    /**
39     * @var int
40     */
41    private $pageId;
42
43    /**
44     * @var array
45     */
46    private $publishers;
47
48    /**
49     * @var array
50     */
51    private $subscribers;
52
53    /**
54     * @param int|null $id
55     * @param string $name
56     * @param string $description
57     * @param int $pageId
58     */
59    public function __construct( $id, $name, $description, $pageId ) {
60        $this->id = (int)$id;
61        $this->name = $name;
62        $this->description = $description;
63        $this->pageId = (int)$pageId;
64    }
65
66    /**
67     * @param int $id
68     *
69     * @return Newsletter|null null if no newsletter exists with the provided id
70     */
71    public static function newFromID( $id ) {
72        return NewsletterStore::getDefaultInstance()
73            ->getNewsletter( $id );
74    }
75
76    /**
77     * Fetch a new newsletter instance from given name
78     *
79     * @param string $name
80     * @param bool $active
81     * @return Newsletter|null
82     */
83    public static function newFromName( $name, $active = true ) {
84        return NewsletterStore::getDefaultInstance()->getNewsletterFromName( $name, $active );
85    }
86
87    /**
88     * @return int|null
89     */
90    public function getId() {
91        return $this->id;
92    }
93
94    /**
95     * @param int $id
96     */
97    public function setId( $id ) {
98        $this->id = $id;
99    }
100
101    /**
102     * @return string
103     */
104    public function getName() {
105        return $this->name;
106    }
107
108    /**
109     * @return string
110     */
111    public function getDescription() {
112        return $this->description;
113    }
114
115    /**
116     * @return int
117     */
118    public function getPageId() {
119        return $this->pageId;
120    }
121
122    /**
123     * @return array
124     */
125    public function getSubscribers() {
126        $this->loadSubscribers();
127        return $this->subscribers;
128    }
129
130    /**
131     * @return int
132     */
133    public function getSubscribersCount(): int {
134        return NewsletterStore::getDefaultInstance()->getNewsletterSubscribersCount( $this->id );
135    }
136
137    /**
138     * @return array
139     */
140    public function getPublishers() {
141        $this->loadPublishers();
142        return $this->publishers;
143    }
144
145    /**
146     * @todo this is probably not scalable...
147     *
148     * @param UserIdentity $user
149     *
150     * @return bool
151     */
152    public function isSubscribed( UserIdentity $user ) {
153        $this->loadSubscribers();
154        return in_array( $user->getId(), $this->subscribers );
155    }
156
157    /**
158     * @param UserIdentity $user
159     *
160     * @return bool
161     */
162    public function isPublisher( UserIdentity $user ) {
163        $this->loadPublishers();
164        return in_array( $user->getId(), $this->publishers );
165    }
166
167    /**
168     * Load the publishers from the database if it has not been queried yet
169     */
170    private function loadPublishers() {
171        if ( $this->publishers === null ) {
172            // Not queried yet so let's do it now
173            $this->publishers = NewsletterStore::getDefaultInstance()
174                ->getPublishersFromID( $this->id );
175        }
176    }
177
178    /**
179     * Load the subscribers from the database if it has not been queried yet
180     */
181    private function loadSubscribers() {
182        if ( $this->subscribers === null ) {
183            // Not queried yet so let's do it now
184            $this->subscribers = NewsletterStore::getDefaultInstance()
185                ->getSubscribersFromID( $this->id );
186        }
187    }
188
189    /**
190     * Subscribe the specified user to this newsletter
191     *
192     * @param User $user
193     *
194     * @return Status
195     */
196    public function subscribe( User $user ) {
197        if ( $user->isAnon() ) {
198            // IPs are not allowed to subscribe
199            return Status::newFatal( 'newsletter-subscribe-ip-notallowed' );
200        }
201
202        $store = NewsletterStore::getDefaultInstance();
203        $store->addSubscription( $this, [ $user->getId() ] );
204        return Status::newGood();
205    }
206
207    /**
208     * Unsubscribe the specified user from this newsletter
209     *
210     * @param User $user
211     * @return Status
212     */
213    public function unsubscribe( User $user ) {
214        $store = NewsletterStore::getDefaultInstance();
215        $store->removeSubscription( $this, [ $user->getId() ] );
216        return Status::newGood();
217    }
218
219    /**
220     * Check whether the user is allowed to delete the newsletter.
221     *
222     * @param User $user
223     *
224     * @return bool
225     */
226    public function canDelete( User $user ) {
227        return $this->isPublisher( $user ) || $user->isAllowed( 'newsletter-delete' );
228    }
229
230    /**
231     * Check whether the user is allowed to manage the newsletter.
232     *
233     * The user is allowed to manage a newsletter if the user is a publisher of
234     * the newsletter, or if the user has the newsletter-manage right.
235     *
236     * @param Authority $user
237     *
238     * @return bool
239     */
240    public function canManage( Authority $user ) {
241        return $this->isPublisher( $user->getUser() ) || $user->isAllowed( 'newsletter-manage' );
242    }
243
244    /**
245     * Check whether the user is allowed to restore the newsletter.
246     *
247     * @param Authority $performer
248     *
249     * @return bool
250     */
251    public function canRestore( Authority $performer ) {
252        return $this->isPublisher( $performer->getUser() ) || $performer->isAllowed( 'newsletter-restore' );
253    }
254
255    /**
256     * Notify new/removed publishers
257     *
258     * @param array $affectedUsers
259     * @param User $agent the user initiating the request
260     * @param string $event select between added/removed
261     */
262    public function notifyPublishers( array $affectedUsers, User $agent, $event ) {
263        $notification = [
264            'extra' => [
265                'newsletter-name' => $this->getName(),
266                'newsletter-id' => $this->getId()
267            ],
268            'agent' => $agent
269        ];
270
271        if ( $event === self::NEWSLETTER_PUBLISHERS_ADDED ) {
272            $notification['type'] = 'newsletter-newpublisher';
273            $notification['extra']['new-publishers-id'] = $affectedUsers;
274        } elseif ( $event === self::NEWSLETTER_PUBLISHERS_REMOVED ) {
275            $notification['type'] = 'newsletter-delpublisher';
276            $notification['extra']['del-publishers-id'] = $affectedUsers;
277        }
278        EchoEvent::create( $notification );
279    }
280
281}