Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
81.08% covered (warning)
81.08%
30 / 37
50.00% covered (danger)
50.00%
1 / 2
CRAP
0.00% covered (danger)
0.00%
0 / 1
User_Finder_Factory
81.08% covered (warning)
81.08%
30 / 37
50.00% covered (danger)
50.00%
1 / 2
15.33
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
1
 get_user_finder
79.41% covered (warning)
79.41%
27 / 34
0.00% covered (danger)
0.00%
0 / 1
14.47
1<?php
2
3namespace BrianHenryIE\WP_Autologin_URLs\API\Integrations;
4
5use BrianHenryIE\WP_Autologin_URLs\API_Interface;
6use BrianHenryIE\WP_Autologin_URLs\Settings_Interface;
7use BrianHenryIE\WP_Autologin_URLs\API\User_Finder_Interface;
8use Psr\Log\LoggerInterface;
9use ReflectionClass;
10use Throwable;
11
12class User_Finder_Factory {
13
14    /**
15     * @var array<string, mixed>
16     */
17    protected array $dependencies = array();
18
19    public function __construct( API_Interface $api, Settings_Interface $settings, LoggerInterface $logger ) {
20        $this->dependencies[ LoggerInterface::class ]    = $logger;
21        $this->dependencies[ Settings_Interface::class ] = $settings;
22        $this->dependencies[ API_Interface::class ]      = $api;
23    }
24
25    public function get_user_finder(): ?User_Finder_Interface {
26
27        /**
28         * @var array<string|User_Finder_Interface> $integrations
29         */
30        $integrations = array(
31            Autologin_URLs::class,
32            Klaviyo::class,
33            MailPoet::class,
34            The_Newsletter_Plugin::class,
35        );
36
37        // TODO: Filter here to allow registering more.
38
39        foreach ( $integrations as $integration ) {
40
41            if ( $integration instanceof User_Finder_Interface ) {
42
43                $integration_instance = $integration;
44
45            } elseif ( is_string( $integration ) && class_exists( $integration ) ) {
46
47                $class = new ReflectionClass( $integration );
48
49                $constructor = $class->getConstructor();
50
51                $construct_params = array();
52
53                // This will be null if the object has no constructor, thus we have no parameters to look for/use.
54                if ( ! is_null( $constructor ) ) {
55
56                    $parameters = $constructor->getParameters();
57
58                    foreach ( $parameters as $reflection_parameter ) {
59
60                        $parameter_type = $reflection_parameter->getType()->getName();
61
62                        if ( isset( $this->dependencies[ $parameter_type ] ) ) {
63                            $construct_params[] = $this->dependencies[ $parameter_type ];
64                        } else {
65
66                            $default = $reflection_parameter->getDefaultValue();
67                            if ( $default ) {
68                                $construct_params[] = $default;
69                            } elseif ( $reflection_parameter->allowsNull() ) {
70                                $construct_params[] = null;
71                            } else {
72                                continue 2;
73                            }
74                            // TODO: Check for default / nullable.
75
76                        }
77                    }
78                }
79
80                try {
81                    /** @var User_Finder_Interface $integration */
82                    $integration_instance = new $integration( ...$construct_params );
83                } catch ( Throwable $exception ) {
84                    continue;
85                }
86
87                if ( ! ( $integration_instance instanceof User_Finder_Interface ) ) {
88                    continue;
89                }
90            } else {
91                // TODO: Log warning it was neither an instance, or an instantiable string.
92                continue;
93            }
94
95            if ( $integration_instance->is_querystring_valid() ) {
96                return $integration_instance;
97            }
98        }
99
100        return null;
101    }
102}