PluginProbe
WPO365 | SEAMLESS WORDPRESS + MICROSOFT INTEGRATION (WPO365 | LOGIN) / trunk
WPO365 | SEAMLESS WORDPRESS + MICROSOFT INTEGRATION (WPO365 | LOGIN) vtrunk
44.1 44.0 43.4 43.3 43.2 43.1 43.0 42.11 42.10 42.9 42.7 42.8 42.6 42.5 42.4 42.3 42.2 42.1 trunk 17.0 17.1 17.2 17.3 17.4 17.5 All 99 releases
wpo365-login / wpo365-login.php

wpo365-login.php in WPO365 | SEAMLESS WORDPRESS + MICROSOFT INTEGRATION (WPO365 | LOGIN) trunk, at wpo365-login.php

239 lines 7.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Plugin Name: WPO365 | LOGIN
4 * Plugin URI: https://wordpress.org/plugins/wpo365-login
5 * Description: Seamless Microsoft Entra | Ext. ID | B2C | M365 Integration for WordPress. For SSO, Mail, Roles, Access, Sync, Copilot, SharePoint, PowerBI.
6 * Version: 44.1
7 * Author: marco@wpo365.com
8 * Author URI: https://www.wpo365.com
9 * License: GPL2+
10 */
11
12 namespace Wpo;
13
14 require __DIR__ . '/vendor/autoload.php';
15
16 use Wpo\Core\Compatibility_Helpers;
17 use Wpo\Core\Globals;
18 use Wpo\Core\Wp_Hooks;
19
20 use Wpo\Services\Dependency_Service;
21 use Wpo\Services\Files_Service;
22 use Wpo\Services\Request_Service;
23 use Wpo\Services\Router_Service;
24 use Wpo\Services\Options_Service;
25
26 // Prevent public access to this script
27 defined( 'ABSPATH' ) || die();
28
29 if ( ! class_exists( '\Wpo\Login' ) ) {
30
31 class Login {
32
33 /**
34 *
35 * @var \Wpo\Services\Dependency_Service
36 */
37 private $dependencies;
38
39 public function __construct() {
40 $this->deactivation_hooks();
41 add_action( 'plugins_loaded', array( $this, 'init' ), 1 );
42 add_filter( 'cron_schedules', '\Wpo\Core\Cron_Helpers::add_cron_schedules', 10, 1 ); // phpcs:ignore
43 }
44
45 public function get_plugin_url() {
46 return plugin_dir_url( __FILE__ );
47 }
48
49 public function init() {
50 $skip_init = defined( 'WPO_AUTH_SCENARIO' ) && constant( 'WPO_AUTH_SCENARIO' ) === 'internet' && ! \is_admin();
51
52 if ( $skip_init ) {
53 add_action( 'login_init', array( $this, 'load' ), 1 );
54 add_action( 'init', '\Wpo\Services\Router_Service::add_sso_start_rewrite_rule' );
55 add_filter( 'query_vars', '\Wpo\Services\Router_Service::add_sso_start_query_var' );
56
57 // A direct hit on the custom login route (/wpo/login, /wpo/loggedout -
58 // premium-only, hence the class_exists guard) must also escape the early return
59 // below, the same way a direct hit on /wpo/sso/start already does - otherwise
60 // Login_Service_Provider::add_hooks() (and therefore Login_Router::handle_request(),
61 // the actual page renderer) would never run for those requests. Unlike the
62 // sso_start pair above, Login_Router::add_rewrite_rule()/add_loggedout_rewrite_rule()
63 // are NOT registered here too: they call Options_Service internally (via
64 // Login_Url_Service::should_use_builtin_loggedout_page()), which needs
65 // Globals::set_global_vars()/Options_Service::ensure_options_cache() to have
66 // already run - neither has, at this point, when $skip_init is about to return
67 // early. Registering them here would make them fire later anyway (WordPress's
68 // 'init' action runs regardless of $skip_init), hitting
69 // "Undefined global variable $WPO_CONFIG". They're only needed - and only safe to
70 // call - once $this->load() actually runs, which registers them itself via
71 // Wp_Hooks::add_wp_hooks() -> Login_Service_Provider::add_hooks(), early enough
72 // (still during 'plugins_loaded', before WordPress's own 'init' action fires) to
73 // take effect for the very same request.
74 $is_custom_login_route_endpoint = class_exists( '\Wpo\Login\Login_Router' ) && \Wpo\Login\Login_Router::detect_login_or_loggedout_endpoint();
75
76 if ( ! Router_Service::detect_sso_start_endpoint() && ! $is_custom_login_route_endpoint ) {
77 return;
78 }
79 }
80
81 $this->load();
82 }
83
84 public function load() {
85 Globals::set_global_vars( __FILE__, __DIR__ );
86 load_plugin_textdomain( 'wpo365-login', false, dirname( plugin_basename( __FILE__ ) ) . '/languages' );
87 $this->cache_dependencies();
88 Options_Service::ensure_options_cache();
89 Compatibility_Helpers::upgrade_actions();
90 $this->update_request_log();
91 Wp_Hooks::add_wp_hooks();
92 Wp_Hooks::add_wp_cli_commands();
93 $this->load_gutenberg_blocks();
94 $has_route = Router_Service::has_route();
95
96 if ( ! Options_Service::get_global_boolean_var( 'no_sso', false ) && ! $has_route ) {
97
98 // Note that login_init runs after init on the login page.
99 if ( doing_action( 'login_init' ) ) {
100 \Wpo\Services\Authentication_Service::authenticate_request();
101 } else {
102 add_action( 'init', '\Wpo\Services\Authentication_Service::authenticate_request', 1 );
103 }
104 }
105 }
106
107 /**
108 * @since 13.0
109 *
110 * To load the Gutenberg M365 blocks.
111 */
112 private function load_gutenberg_blocks() {
113 $apps = array(
114 'docs' => array(
115 'edition' => 'basic',
116 'load_front_end_assets' => true,
117 ),
118 );
119
120 $plugins_dir = __DIR__;
121 $plugins_url = \plugins_url() . '/' . basename( __DIR__ );
122
123 foreach ( $apps as $app => $settings ) {
124 new \Wpo\Blocks\Loader( $app, $settings['edition'], $plugins_dir, $plugins_url, $settings['load_front_end_assets'] );
125 }
126 }
127
128 private function cache_dependencies() {
129 $this->dependencies = Dependency_Service::get_instance();
130 $this->dependencies->add( 'Request_Service', Request_Service::get_instance( true ) );
131 $this->dependencies->add( 'Files_Service', Files_Service::get_instance() );
132 }
133
134 private function update_request_log() {
135 $request_service = Request_Service::get_instance();
136 $request = $request_service->get_request( $GLOBALS['WPO_CONFIG']['request_id'] );
137 $request_log = $request->get_item( 'request_log' );
138 $request_log['debug_log'] = Options_Service::get_global_boolean_var( 'debug_log', false );
139 $request->set_item( 'request_log', $request_log );
140 }
141
142 private function deactivation_hooks() {
143
144 if ( \class_exists( '\Wpo\Sync\Sync_Helpers' ) ) {
145 // Delete possible cron jobs
146 register_deactivation_hook(
147 __FILE__,
148 function () {
149 \Wpo\Sync\Sync_Helpers::get_scheduled_events( null, true );
150 }
151 );
152 }
153
154 if ( \class_exists( '\Wpo\Mail\Mail_Db' ) ) {
155 // Delete possible cron jobs
156 register_deactivation_hook(
157 __FILE__,
158 function () {
159 wp_clear_scheduled_hook( 'wpo_process_unsent_messages' );
160 Options_Service::add_update_option( 'mail_auto_retry', false );
161 }
162 );
163 }
164
165 // Delete the mail refresh token cron job
166 register_deactivation_hook(
167 __FILE__,
168 function () {
169 wp_clear_scheduled_hook( 'wpo365_get_mail_refresh_token' );
170 delete_site_transient( 'wpo365_get_mail_refresh_token_hook_ensured' );
171 }
172 );
173
174 register_deactivation_hook(
175 __FILE__,
176 function () {
177 global $wpdb;
178
179 $wpdb->query( // phpcs:ignore
180 $wpdb->prepare(
181 'DELETE FROM %i WHERE `meta_key` LIKE %s OR `meta_key` LIKE %s OR `meta_key` LIKE %s OR `meta_key` LIKE %s',
182 $wpdb->usermeta,
183 'wpo_access%',
184 'wpo_refresh%',
185 'WPO365_AUTH%',
186 'wpo_sync_users_%'
187 )
188 );
189
190 $wpdb->query( // phpcs:ignore
191 $wpdb->prepare(
192 'DELETE FROM %i WHERE `option_name` LIKE %s AND `option_name` != %s AND `option_name` != %s',
193 $wpdb->options,
194 '%wpo365%',
195 'wpo365_options',
196 'wpo365_mail_authorization'
197 )
198 );
199
200 $wpdb->query( // phpcs:ignore
201 $wpdb->prepare(
202 'DELETE FROM %i WHERE `option_name` = %s OR `option_name` = %s OR `option_name` = %s',
203 $wpdb->options,
204 'wpo_app_only_access_tokens',
205 'wpo365_x509_certificates',
206 'wpo_sync_v2_unscheduled'
207 )
208 );
209 }
210 );
211
212 // Flush rewrite rules for all sites so the /wpo/sso/start rule is removed.
213 register_deactivation_hook(
214 __FILE__,
215 function () {
216 if ( is_multisite() ) {
217 $site_ids = get_sites(
218 array(
219 'number' => 0,
220 'fields' => 'ids',
221 )
222 );
223
224 foreach ( $site_ids as $site_id ) {
225 switch_to_blog( $site_id );
226 flush_rewrite_rules( false );
227 restore_current_blog();
228 }
229 } else {
230 flush_rewrite_rules( false );
231 }
232 }
233 );
234 }
235 }
236 }
237
238 $wpo365_login = new Login();
239