Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
59.09% |
13 / 22 |
|
80.00% |
4 / 5 |
CRAP | |
0.00% |
0 / 1 |
UserRegistrationLookup | |
59.09% |
13 / 22 |
|
80.00% |
4 / 5 |
16.85 | |
0.00% |
0 / 1 |
__construct | |
100.00% |
3 / 3 |
|
100.00% |
1 / 1 |
1 | |||
isRegistered | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
getProvider | |
100.00% |
8 / 8 |
|
100.00% |
1 / 1 |
3 | |||
getRegistration | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
getFirstRegistration | |
0.00% |
0 / 9 |
|
0.00% |
0 / 1 |
20 |
1 | <?php |
2 | |
3 | namespace MediaWiki\User\Registration; |
4 | |
5 | use InvalidArgumentException; |
6 | use MediaWiki\Config\ServiceOptions; |
7 | use MediaWiki\MainConfigNames; |
8 | use MediaWiki\MainConfigSchema; |
9 | use MediaWiki\User\UserIdentity; |
10 | use Wikimedia\ObjectFactory\ObjectFactory; |
11 | |
12 | /** |
13 | * @since 1.41 |
14 | */ |
15 | class UserRegistrationLookup { |
16 | |
17 | /** |
18 | * @internal for use in ServiceWiring |
19 | * @var string[] Config names to require |
20 | */ |
21 | public const CONSTRUCTOR_OPTIONS = [ |
22 | MainConfigNames::UserRegistrationProviders, |
23 | ]; |
24 | |
25 | /** @var array ObjectFactory specs indexed by provider name */ |
26 | private array $providersSpecs; |
27 | |
28 | /** @var IUserRegistrationProvider[] Constructed registration providers indexed by name */ |
29 | private array $providers = []; |
30 | |
31 | private ObjectFactory $objectFactory; |
32 | |
33 | public function __construct( |
34 | ServiceOptions $options, |
35 | ObjectFactory $objectFactory |
36 | ) { |
37 | $options->assertRequiredOptions( self::CONSTRUCTOR_OPTIONS ); |
38 | $this->providersSpecs = $options->get( MainConfigNames::UserRegistrationProviders ); |
39 | $this->objectFactory = $objectFactory; |
40 | } |
41 | |
42 | /** |
43 | * Is a registration provider registered? |
44 | * |
45 | * @see MainConfigSchema::UserRegistrationLookupProviders |
46 | * @param string $type |
47 | * @return bool |
48 | */ |
49 | public function isRegistered( string $type ): bool { |
50 | return array_key_exists( $type, $this->providersSpecs ); |
51 | } |
52 | |
53 | /** |
54 | * Construct a registration provider, if needed |
55 | * |
56 | * @param string $type |
57 | * @return IUserRegistrationProvider |
58 | */ |
59 | private function getProvider( string $type ): IUserRegistrationProvider { |
60 | if ( !$this->isRegistered( $type ) ) { |
61 | throw new InvalidArgumentException( 'Registration provider ' . $type . ' is not registered' ); |
62 | } |
63 | if ( !array_key_exists( $type, $this->providers ) ) { |
64 | $this->providers[$type] = $this->objectFactory->createObject( |
65 | $this->providersSpecs[$type], |
66 | [ 'assertClass' => IUserRegistrationProvider::class ] |
67 | ); |
68 | } |
69 | return $this->providers[$type]; |
70 | } |
71 | |
72 | /** |
73 | * @param UserIdentity $user User for which registration should be fetched. |
74 | * @param string $type Name of a registered registration provider |
75 | * @return string|null|false Registration timestamp, null if not available or false if it |
76 | * cannot be fetched (anonymous users, for example). |
77 | */ |
78 | public function getRegistration( |
79 | UserIdentity $user, |
80 | string $type = LocalUserRegistrationProvider::TYPE |
81 | ) { |
82 | return $this->getProvider( $type )->fetchRegistration( $user ); |
83 | } |
84 | |
85 | /** |
86 | * Find the first registration timestamp for a given user |
87 | * |
88 | * Note this invokes _all_ registered providers. |
89 | * |
90 | * @param UserIdentity $user |
91 | * @return string|null Earliest registration timestamp, null if not available. |
92 | */ |
93 | public function getFirstRegistration( UserIdentity $user ): ?string { |
94 | $registrationTimestampsUnix = []; |
95 | foreach ( $this->providersSpecs as $providerKey => $_ ) { |
96 | $registrationTimestampRaw = $this->getRegistration( $user, $providerKey ); |
97 | if ( !is_string( $registrationTimestampRaw ) ) { |
98 | // Provider was unable to return a registration timestamp for $providerKey, skip |
99 | // them. |
100 | continue; |
101 | } |
102 | $registrationTimestampsUnix[] = (int)wfTimestamp( TS_UNIX, $registrationTimestampRaw ); |
103 | } |
104 | |
105 | if ( $registrationTimestampsUnix === [] ) { |
106 | return null; |
107 | } |
108 | |
109 | return wfTimestamp( TS_MW, min( $registrationTimestampsUnix ) ); |
110 | } |
111 | } |