Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
70.89% covered (warning)
70.89%
56 / 79
66.67% covered (warning)
66.67%
10 / 15
CRAP
0.00% covered (danger)
0.00%
0 / 1
BH_WP_Autologin_URLs
70.89% covered (warning)
70.89%
56 / 79
66.67% covered (warning)
66.67%
10 / 15
24.13
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
17 / 17
100.00% covered (success)
100.00%
1 / 1
1
 set_locale
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 setup_api
0.00% covered (danger)
0.00%
0 / 10
0.00% covered (danger)
0.00%
0 / 1
2
 define_admin_ui_hooks
100.00% covered (success)
100.00%
13 / 13
100.00% covered (success)
100.00%
1 / 1
1
 define_login_ui_hooks
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
1
 define_plugins_page_hooks
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
1
 define_plugin_installer_hooks
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 define_wp_mail_hooks
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 define_wp_login_hooks
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 define_cron_hooks
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
1
 define_woocommerce_admin_order_ui_hooks
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
1
 define_woocommerce_login_form_hooks
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
1
 define_logger_hooks
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 define_cli_hooks
0.00% covered (danger)
0.00%
0 / 7
0.00% covered (danger)
0.00%
0 / 1
12
 define_rest_api_hooks
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2/**
3 * The file that defines the core plugin class
4 *
5 * A class definition that includes attributes and functions used across both the
6 * public-facing side of the site and the admin area.
7 *
8 * @link       https://BrianHenry.ie
9 * @since      1.0.0
10 *
11 * @package    bh-wp-autologin-urls
12 */
13
14namespace BrianHenryIE\WP_Autologin_URLs;
15
16use BrianHenryIE\WP_Autologin_URLs\Admin\Plugin_Installer;
17use BrianHenryIE\WP_Autologin_URLs\Admin\User_Edit;
18use BrianHenryIE\WP_Autologin_URLs\Admin\Admin_Assets;
19use BrianHenryIE\WP_Autologin_URLs\Admin\Settings_Page;
20use BrianHenryIE\WP_Autologin_URLs\Admin\Plugins_Page;
21use BrianHenryIE\WP_Autologin_URLs\Admin\Users_List_Table;
22use BrianHenryIE\WP_Autologin_URLs\Logger\Klaviyo_Logs;
23use BrianHenryIE\WP_Autologin_URLs\Login\Login_Ajax;
24use BrianHenryIE\WP_Autologin_URLs\Login\Login_Assets;
25use BrianHenryIE\WP_Autologin_URLs\WooCommerce\Admin_Order_UI;
26use BrianHenryIE\WP_Autologin_URLs\WooCommerce\Login_Form;
27use BrianHenryIE\WP_Autologin_URLs\WP_Includes\CLI;
28use BrianHenryIE\WP_Autologin_URLs\WP_Includes\Cron;
29use BrianHenryIE\WP_Autologin_URLs\WP_Includes\I18n;
30use BrianHenryIE\WP_Autologin_URLs\WP_Includes\Login;
31use BrianHenryIE\WP_Autologin_URLs\WP_Includes\REST_API;
32use BrianHenryIE\WP_Autologin_URLs\WP_Includes\WP_Mail;
33use Exception;
34use Psr\Log\LoggerInterface;
35use WP_CLI;
36
37/**
38 * The core plugin class.
39 *
40 * This is used to define internationalization, admin-specific hooks, and
41 * public-facing site hooks.
42 *
43 * Also maintains the unique identifier of this plugin as well as the current
44 * version of the plugin.
45 */
46class BH_WP_Autologin_URLs {
47
48    /**
49     * Instance of PSR logger to record logins and issues.
50     *
51     * @var LoggerInterface
52     */
53    protected $logger;
54
55    /**
56     * Instance member of API class to expose to WordPress to allow users unhook actions.
57     *
58     * @var API_Interface
59     */
60    public $api;
61
62    /**
63     * Plugin settings as saved in the database.
64     *
65     * @var Settings_Interface
66     */
67    public $settings;
68
69    /**
70     * Define the core functionality of the plugin.
71     *
72     * Set the plugin name and the plugin version that can be used throughout the plugin.
73     * Load the dependencies, define the locale, and set the hooks for the admin area and
74     * the public-facing side of the site.
75     *
76     * @param API_Interface      $api The main plugin functions.
77     * @param Settings_Interface $settings The plugin settings.
78     * @param LoggerInterface    $logger PSR Logger.
79     *
80     * @since    1.0.0
81     */
82    public function __construct( API_Interface $api, Settings_Interface $settings, LoggerInterface $logger ) {
83
84        $this->api      = $api;
85        $this->settings = $settings;
86        $this->logger   = $logger;
87
88        $this->setup_api();
89
90        $this->set_locale();
91
92        $this->define_admin_ui_hooks();
93        $this->define_login_ui_hooks();
94
95        $this->define_plugins_page_hooks();
96        $this->define_plugin_installer_hooks();
97
98        $this->define_wp_mail_hooks();
99
100        $this->define_wp_login_hooks();
101
102        $this->define_cron_hooks();
103
104        $this->define_woocommerce_admin_order_ui_hooks();
105        $this->define_woocommerce_login_form_hooks();
106
107        $this->define_logger_hooks();
108
109        $this->define_cli_hooks();
110        $this->define_rest_api_hooks();
111    }
112
113    /**
114     * Define the locale for this plugin for internationalization.
115     *
116     * Uses the i18n class in order to set the domain and to register the hook
117     * with WordPress.
118     *
119     * @since    1.0.0
120     */
121    protected function set_locale(): void {
122
123        $plugin_i18n = new I18n();
124
125        add_action( 'init', array( $plugin_i18n, 'load_plugin_textdomain' ) );
126    }
127
128    /**
129     * Instantiates the API class for use by the wp_mail filtering class and makes it publicly available.
130     */
131    protected function setup_api(): void {
132
133        $plugin_api = $this->api;
134
135        add_filter( 'add_autologin_to_message', array( $plugin_api, 'add_autologin_to_message' ), 10, 2 );
136        add_filter( 'add_autologin_to_url', array( $plugin_api, 'add_autologin_to_url' ), 10, 2 );
137
138        add_action(
139            'plugins_loaded',
140            function () {
141                require_once dirname( __DIR__ ) . '/functions.php';
142            },
143            2
144        );
145    }
146
147    /**
148     * Register the hooks related to the admin area functionality
149     * of the plugin.
150     *
151     * @since    1.0.0
152     */
153    protected function define_admin_ui_hooks(): void {
154
155        $admin_assets = new Admin_Assets( $this->settings );
156
157        add_action( 'admin_enqueue_scripts', array( $admin_assets, 'enqueue_styles' ) );
158        add_action( 'admin_enqueue_scripts', array( $admin_assets, 'enqueue_scripts' ) );
159
160        $plugin_settings_page = new Settings_Page( $this->settings, $this->logger );
161
162        add_action( 'admin_menu', array( $plugin_settings_page, 'add_settings_page' ) );
163        add_action( 'admin_init', array( $plugin_settings_page, 'setup_sections' ) );
164        add_action( 'admin_init', array( $plugin_settings_page, 'setup_fields' ) );
165
166        $user_edit = new User_Edit( $this->api, $this->settings );
167        add_action( 'edit_user_profile', array( $user_edit, 'make_password_available_on_user_page' ), 1, 1 );
168        add_action( 'show_user_profile', array( $user_edit, 'make_password_available_on_user_page' ), 1, 1 );
169
170        $users_list_table = new Users_List_Table( $this->api, $this->settings );
171        add_filter( 'user_row_actions', array( $users_list_table, 'add_magic_email_link' ), 10, 2 );
172        add_action( 'admin_init', array( $users_list_table, 'send_magic_email_link' ) );
173    }
174
175    /**
176     * Hooks related to the wp-login.php UI.
177     */
178    protected function define_login_ui_hooks(): void {
179
180        $login_assets = new Login_Assets( $this->settings );
181
182        add_action( 'login_enqueue_scripts', array( $login_assets, 'enqueue_styles' ) );
183        add_action( 'login_enqueue_scripts', array( $login_assets, 'enqueue_scripts' ) );
184
185        $login_ajax = new Login_Ajax( $this->api, $this->logger );
186
187        add_action( 'wp_ajax_nopriv_bh_wp_autologin_urls_send_magic_link', array( $login_ajax, 'email_magic_link' ) );
188    }
189
190    /**
191     * Add a Settings link and a link to the plugin on GitHub.
192     */
193    protected function define_plugins_page_hooks(): void {
194
195        $plugins_page = new Plugins_Page( $this->settings );
196
197        $plugin_basename = $this->settings->get_plugin_basename();
198
199        add_filter( "plugin_action_links_{$plugin_basename}", array( $plugins_page, 'action_links' ), 10, 4 );
200        add_filter( 'plugin_row_meta', array( $plugins_page, 'row_meta' ), 20, 4 );
201    }
202
203    /**
204     * Add a Settings link and a link to "Plugin updated successfully." page that is displayed after updating.
205     */
206    protected function define_plugin_installer_hooks(): void {
207
208        $plugin_installer = new Plugin_Installer( $this->settings, $this->logger );
209
210        add_filter( 'install_plugin_complete_actions', array( $plugin_installer, 'add_settings_link' ), 10, 3 );
211    }
212
213    /**
214     * Register the hooks related to manipulating outgoing emails.
215     *
216     * @since    1.0.0
217     */
218    protected function define_wp_mail_hooks(): void {
219
220        $plugin_wp_mail = new WP_Mail( $this->api, $this->settings );
221
222        add_filter( 'wp_mail', array( $plugin_wp_mail, 'add_autologin_links_to_email' ), 3 );
223    }
224
225    /**
226     * Register the hooks related to the actual login functionality
227     * of the plugin.
228     *
229     * @since    1.0.0
230     */
231    protected function define_wp_login_hooks(): void {
232
233        $plugin_login = new Login( $this->api, $this->settings, $this->logger );
234
235        add_filter( 'determine_current_user', array( $plugin_login, 'process' ), 30 );
236    }
237
238    /**
239     * Register actions to schedule the cron job and to handle its execution.
240     */
241    protected function define_cron_hooks(): void {
242
243        $cron = new Cron( $this->api, $this->logger );
244
245        add_action( 'plugins_loaded', array( $cron, 'schedule_job' ) );
246        add_action( Cron::DELETE_EXPIRED_CODES_JOB_NAME, array( $cron, 'delete_expired_codes' ) );
247    }
248
249    /**
250     * Register the filter to add the autologin code to the "Customer payment page" link in the admin UI.
251     */
252    protected function define_woocommerce_admin_order_ui_hooks(): void {
253
254        $admin_order_ui = new Admin_Order_UI( $this->api, $this->settings );
255
256        add_filter( 'woocommerce_get_checkout_payment_url', array( $admin_order_ui, 'add_to_payment_url' ), 10, 2 );
257
258        add_filter( 'gettext_woocommerce', array( $admin_order_ui, 'remove_arrow_from_link_text' ), 10, 3 );
259
260        add_action( 'admin_enqueue_scripts', array( $admin_order_ui, 'enqueue_script' ) );
261        add_action( 'admin_enqueue_scripts', array( $admin_order_ui, 'enqueue_styles' ) );
262    }
263
264    /**
265     * Register the action for enqueuing the JavaScript to add the magic-link button to the WooCommerce login form.
266     */
267    protected function define_woocommerce_login_form_hooks(): void {
268
269        $login_form = new Login_Form( $this->settings );
270
271        add_action( 'woocommerce_before_customer_login_form', array( $login_form, 'enqueue_script' ) );
272        add_action( 'woocommerce_before_checkout_form', array( $login_form, 'enqueue_script' ) );
273    }
274
275    /**
276     * Register filters for augmenting the data printed on the logs table.
277     *
278     * @see wp-admin/admin.php?page=bh-wp-autologin-urls-logs
279     */
280    protected function define_logger_hooks(): void {
281
282        $klaviyo_logs = new Klaviyo_Logs();
283
284        add_filter( 'bh-wp-autologin-urls_bh_wp_logger_column', array( $klaviyo_logs, 'link_to_klaviyo_profile_search' ), 10, 5 );
285    }
286
287    /**
288     * Register actions for CLI commands.
289     */
290    protected function define_cli_hooks(): void {
291
292        if ( ! class_exists( WP_CLI::class ) ) {
293            return;
294        }
295
296        $cli = new CLI( $this->api );
297
298        try {
299            WP_CLI::add_command( 'autologin-urls get-url', array( $cli, 'add_autologin_to_url' ) );
300            WP_CLI::add_command( 'autologin-urls send-magic-link', array( $cli, 'send_magic_link' ) );
301        } catch ( Exception $e ) {
302            $this->logger->error( 'Failed to register WP CLI commands: ' . $e->getMessage(), array( 'exception' => $e ) );
303        }
304    }
305
306    protected function define_rest_api_hooks(): void {
307
308        $rest_api = new REST_API( $this->api );
309
310        add_action( 'rest_api_init', array( $rest_api, 'register_routes' ) );
311    }
312}