assertRequiredOptions( self::CONSTRUCTOR_OPTIONS ); $this->options = $options; $this->userRegistrationLookup = $userRegistrationLookup; } /** * Does the option support conditional defaults? * * @param string $option * @return bool */ public function hasConditionalDefault( string $option ): bool { return array_key_exists( $option, $this->options->get( MainConfigNames::ConditionalUserOptions ) ); } /** * Get all conditionally default user options * * @return string[] */ public function getConditionallyDefaultOptions(): array { return array_keys( $this->options->get( MainConfigNames::ConditionalUserOptions ) ); } /** * Get the conditional default for user and option * * @param string $optionName * @param UserIdentity $userIdentity * @return mixed|null The default value if set, or null if it cannot be determined * conditionally (default from DefaultOptionsLookup should be used in that case). */ public function getOptionDefaultForUser( string $optionName, UserIdentity $userIdentity ) { $conditionalDefaults = $this->options ->get( MainConfigNames::ConditionalUserOptions )[$optionName] ?? []; foreach ( $conditionalDefaults as $conditionalDefault ) { // At the zeroth index of the conditional case, the intended value is found; the rest // of the array are conditions, which are evaluated in checkConditionsForUser(). $value = array_shift( $conditionalDefault ); if ( $this->checkConditionsForUser( $userIdentity, $conditionalDefault ) ) { return $value; } } return null; } /** * Are ALL conditions satisfied for the given user? * * @param UserIdentity $userIdentity * @param array $conditions * @return bool */ private function checkConditionsForUser( UserIdentity $userIdentity, array $conditions ): bool { foreach ( $conditions as $condition ) { if ( !$this->checkConditionForUser( $userIdentity, $condition ) ) { return false; } } return true; } /** * Is ONE condition satisfied for the given user? * * @param UserIdentity $userIdentity * @param array|int $cond Either [ CUDCOND_*, args ] or CUDCOND_*, depending on whether the * condition has any arguments. * @return bool */ private function checkConditionForUser( UserIdentity $userIdentity, $cond ): bool { if ( !is_array( $cond ) ) { $cond = [ $cond ]; } if ( $cond === [] ) { throw new InvalidArgumentException( 'Empty condition' ); } $condName = array_shift( $cond ); switch ( $condName ) { case CUDCOND_AFTER: $registration = $this->userRegistrationLookup->getRegistration( $userIdentity ); if ( $registration === null || $registration === false ) { return false; } return ( (int)ConvertibleTimestamp::convert( TS_UNIX, $registration ) - (int)ConvertibleTimestamp::convert( TS_UNIX, $cond[0] ) ) > 0; default: throw new InvalidArgumentException( 'Unsupported condition ' . $condName ); } } }