Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
91.18% covered (success)
91.18%
31 / 34
77.78% covered (warning)
77.78%
7 / 9
CRAP
0.00% covered (danger)
0.00%
0 / 1
ActorStoreFactory
91.18% covered (success)
91.18%
31 / 34
77.78% covered (warning)
77.78%
7 / 9
17.20
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
8 / 8
100.00% covered (success)
100.00%
1 / 1
1
 getActorNormalization
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getActorNormalizationForImport
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getActorStore
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getActorStoreForImport
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getActorStoreForUndelete
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getStore
88.24% covered (warning)
88.24%
15 / 17
0.00% covered (danger)
0.00%
0 / 1
7.08
 getUserIdentityLookup
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getLoadBalancerForTable
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
3
1<?php
2/**
3 * @license GPL-2.0-or-later
4 * @file
5 */
6
7namespace MediaWiki\User;
8
9use MediaWiki\Block\HideUserUtils;
10use MediaWiki\Config\ServiceOptions;
11use MediaWiki\DAO\WikiAwareEntity;
12use MediaWiki\MainConfigNames;
13use MediaWiki\User\TempUser\TempUserConfig;
14use Psr\Log\LoggerInterface;
15use Wikimedia\Rdbms\ILBFactory;
16use Wikimedia\Rdbms\ILoadBalancer;
17
18/**
19 * ActorStore factory for any wiki domain.
20 *
21 * @since 1.36
22 * @ingroup User
23 */
24class ActorStoreFactory {
25
26    /** @internal */
27    public const CONSTRUCTOR_OPTIONS = [
28        MainConfigNames::SharedDB,
29        MainConfigNames::SharedTables,
30    ];
31
32    private ILBFactory $loadBalancerFactory;
33    private UserNameUtils $userNameUtils;
34    private TempUserConfig $tempUserConfig;
35    private LoggerInterface $logger;
36    private HideUserUtils $hideUserUtils;
37
38    /** @var string|false */
39    private $sharedDB;
40
41    /** @var string[] */
42    private $sharedTables;
43
44    /** @var ActorStore[] */
45    private $storeCache = [];
46
47    /**
48     * @param ServiceOptions $options
49     * @param ILBFactory $loadBalancerFactory
50     * @param UserNameUtils $userNameUtils
51     * @param TempUserConfig $tempUserConfig
52     * @param LoggerInterface $logger
53     * @param HideUserUtils $hideUserUtils
54     */
55    public function __construct(
56        ServiceOptions $options,
57        ILBFactory $loadBalancerFactory,
58        UserNameUtils $userNameUtils,
59        TempUserConfig $tempUserConfig,
60        LoggerInterface $logger,
61        HideUserUtils $hideUserUtils
62    ) {
63        $options->assertRequiredOptions( self::CONSTRUCTOR_OPTIONS );
64        $this->loadBalancerFactory = $loadBalancerFactory;
65        $this->sharedDB = $options->get( MainConfigNames::SharedDB );
66        $this->sharedTables = $options->get( MainConfigNames::SharedTables );
67        $this->userNameUtils = $userNameUtils;
68        $this->tempUserConfig = $tempUserConfig;
69        $this->logger = $logger;
70        $this->hideUserUtils = $hideUserUtils;
71    }
72
73    /**
74     * @param string|false $wikiId
75     * @return ActorNormalization
76     */
77    public function getActorNormalization( $wikiId = WikiAwareEntity::LOCAL ): ActorNormalization {
78        return $this->getActorStore( $wikiId );
79    }
80
81    /**
82     * @since 1.42
83     * @param string|false $wikiId
84     * @return ActorNormalization
85     */
86    public function getActorNormalizationForImport(
87        $wikiId = WikiAwareEntity::LOCAL
88    ): ActorNormalization {
89        return $this->getActorStoreForImport( $wikiId );
90    }
91
92    /**
93     * @param string|false $wikiId
94     * @return ActorStore
95     */
96    public function getActorStore( $wikiId = WikiAwareEntity::LOCAL ): ActorStore {
97        return $this->getStore( $wikiId, false );
98    }
99
100    /**
101     * @since 1.42
102     * @param string|false $wikiId
103     * @return ActorStore
104     */
105    public function getActorStoreForImport( $wikiId = WikiAwareEntity::LOCAL ): ActorStore {
106        return $this->getStore( $wikiId, true );
107    }
108
109    /**
110     * @since 1.43
111     * @param string|false $wikiId
112     * @return ActorStore
113     */
114    public function getActorStoreForUndelete( $wikiId = WikiAwareEntity::LOCAL ): ActorStore {
115        return $this->getStore( $wikiId, true );
116    }
117
118    /**
119     * @param string|false $wikiId
120     * @param bool $allowingIpActorCreation
121     * @return ActorStore
122     */
123    private function getStore( $wikiId, bool $allowingIpActorCreation ): ActorStore {
124        // During the transition from User, we still have old User objects
125        // representing users from a different wiki, so we still have IDatabase::getDomainId
126        // passed as $wikiId, so we need to remap it back to LOCAL.
127        if ( is_string( $wikiId ) && $this->loadBalancerFactory->getLocalDomainID() === $wikiId ) {
128            $wikiId = WikiAwareEntity::LOCAL;
129        }
130
131        $storeCacheKey = ( $allowingIpActorCreation ? 'allowing-ip-actor-creation-' : '' ) .
132            ( $wikiId === WikiAwareEntity::LOCAL ? 'LOCAL' : $wikiId );
133
134        if ( !isset( $this->storeCache[$storeCacheKey] ) ) {
135            $store = new ActorStore(
136                $this->getLoadBalancerForTable( 'actor', $wikiId ),
137                $this->userNameUtils,
138                $this->tempUserConfig,
139                $this->logger,
140                $this->hideUserUtils,
141                $wikiId
142            );
143            if ( $allowingIpActorCreation ) {
144                $store->setAllowCreateIpActors( true );
145            }
146            $this->storeCache[$storeCacheKey] = $store;
147        }
148        return $this->storeCache[$storeCacheKey];
149    }
150
151    /**
152     * @param string|false $wikiId
153     * @return UserIdentityLookup
154     */
155    public function getUserIdentityLookup(
156        $wikiId = WikiAwareEntity::LOCAL
157    ): UserIdentityLookup {
158        return $this->getActorStore( $wikiId );
159    }
160
161    /**
162     * Returns a load balancer for the database that has the $table
163     * for the given $wikiId.
164     *
165     * @param string $table
166     * @param string|false $wikiId
167     * @return ILoadBalancer
168     */
169    private function getLoadBalancerForTable(
170        string $table,
171        $wikiId = WikiAwareEntity::LOCAL
172    ): ILoadBalancer {
173        if ( $this->sharedDB && in_array( $table, $this->sharedTables ) ) {
174            // The main LB is already properly set up for shared databases early in Setup.php
175            return $this->loadBalancerFactory->getMainLB();
176        }
177        return $this->loadBalancerFactory->getMainLB( $wikiId );
178    }
179}