Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 24
0.00% covered (danger)
0.00%
0 / 4
CRAP
0.00% covered (danger)
0.00%
0 / 1
SpecialEmailInvalidate
0.00% covered (danger)
0.00%
0 / 23
0.00% covered (danger)
0.00%
0 / 4
42
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
 doesWrites
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 execute
0.00% covered (danger)
0.00%
0 / 7
0.00% covered (danger)
0.00%
0 / 1
2
 attemptInvalidate
0.00% covered (danger)
0.00%
0 / 13
0.00% covered (danger)
0.00%
0 / 1
12
1<?php
2/**
3 * @license GPL-2.0-or-later
4 * @file
5 */
6
7namespace MediaWiki\Specials;
8
9use LogicException;
10use MediaWiki\Profiler\Profiler;
11use MediaWiki\SpecialPage\UnlistedSpecialPage;
12use MediaWiki\User\UserFactory;
13use Wikimedia\Rdbms\IDBAccessObject;
14use Wikimedia\ScopedCallback;
15
16/**
17 * Cancel an email confirmation using the e-mail confirmation code.
18 *
19 * @see SpecialConfirmEmail
20 * @ingroup SpecialPage
21 * @ingroup Auth
22 */
23class SpecialEmailInvalidate extends UnlistedSpecialPage {
24
25    private UserFactory $userFactory;
26
27    public function __construct( UserFactory $userFactory ) {
28        parent::__construct( 'Invalidateemail', 'editmyprivateinfo' );
29
30        $this->userFactory = $userFactory;
31    }
32
33    /** @inheritDoc */
34    public function doesWrites() {
35        return true;
36    }
37
38    /** @inheritDoc */
39    public function execute( $code ) {
40        // Ignore things like primary queries/connections on GET requests.
41        // It's very convenient to just allow formless link usage.
42        $trxProfiler = Profiler::instance()->getTransactionProfiler();
43
44        $this->setHeaders();
45        $this->checkReadOnly();
46        $this->checkPermissions();
47
48        $scope = $trxProfiler->silenceForScope( $trxProfiler::EXPECTATION_REPLICAS_ONLY );
49        $this->attemptInvalidate( $code );
50        ScopedCallback::consume( $scope );
51    }
52
53    /**
54     * Attempt to invalidate the user's email address and show success or failure
55     * as needed; if successful, link to main page
56     *
57     * @param string $code Confirmation code
58     */
59    private function attemptInvalidate( $code ) {
60        $user = $this->userFactory->newFromConfirmationCode(
61            (string)$code,
62            IDBAccessObject::READ_LATEST
63        );
64
65        if ( !is_object( $user ) ) {
66            $this->getOutput()->addWikiMsg( 'confirmemail_invalid' );
67
68            return;
69        }
70
71        $userLatest = $user->getInstanceFromPrimary() ?? throw new LogicException( 'No user' );
72        $userLatest->invalidateEmail();
73        $userLatest->saveSettings();
74        $this->getOutput()->addWikiMsg( 'confirmemail_invalidated' );
75
76        if ( !$this->getUser()->isRegistered() ) {
77            $this->getOutput()->returnToMain();
78        }
79    }
80}
81
82/** @deprecated class alias since 1.41 */
83class_alias( SpecialEmailInvalidate::class, 'SpecialEmailInvalidate' );