PluginProbe ʕ •ᴥ•ʔ
WP 2FA – Two-factor authentication for WordPress / 2.6.0
WP 2FA – Two-factor authentication for WordPress v2.6.0
4.0.0 1.7.1 2.0.0 2.0.1 2.1.0 2.2.0 2.2.1 2.3.0 2.4.0 2.4.1 2.4.2 2.5.0 2.6.0 2.6.1 2.6.2 2.6.3 2.6.4 2.7.0 2.8.0 2.9.0 2.9.1 2.9.2 2.9.3 3.0.0 3.0.1 3.1.0 3.1.1 3.1.1.2 trunk 1.2.0 1.3.0 1.4.0 1.4.1 1.4.2 1.5.0 1.5.1 1.5.2 1.6.0 1.6.1 1.6.2 1.7.0
wp-2fa / includes / classes / Admin / Helpers / class-wp-helper.php
wp-2fa / includes / classes / Admin / Helpers Last commit date
class-ajax-helper.php 2 years ago class-classes-helper.php 2 years ago class-file-writer.php 2 years ago class-methods-helper.php 2 years ago class-php-helper.php 2 years ago class-user-helper.php 2 years ago class-wp-helper.php 2 years ago index.php 2 years ago
class-wp-helper.php
340 lines
1 <?php
2 /**
3 * Responsible for the WP core functionalities.
4 *
5 * @package wp2fa
6 * @subpackage helpers
7 *
8 * @since 2.2.0
9 *
10 * @copyright %%YEAR%% Melapress
11 * @license https://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0
12 *
13 * @see https://wordpress.org/plugins/wp-2fa/
14 */
15
16 namespace WP2FA\Admin\Helpers;
17
18 defined( 'ABSPATH' ) || exit; // Exit if accessed directly.
19
20 /*
21 * WP helper class
22 */
23 if ( ! class_exists( '\WP2FA\Admin\Helpers\WP_Helper' ) ) {
24 /**
25 * All the WP functionality must go trough this class.
26 *
27 * @since 2.2.0
28 */
29 class WP_Helper {
30 /**
31 * Hold the user roles as array - Human readable is used for key of the array, and the internal role name is the value.
32 *
33 * @var array
34 *
35 * @since 2.2.0
36 */
37 private static $user_roles = array();
38
39 /**
40 * Hold the user roles as array - Internal role name is used for key of the array, and the human readable format is the value.
41 *
42 * @var array
43 *
44 * @since 2.2.0
45 */
46 private static $user_roles_wp = array();
47
48 /**
49 * Keeps the value of the multisite install of the WP.
50 *
51 * @var bool
52 *
53 * @since 2.2.0
54 */
55 private static $is_multisite = null;
56
57 /**
58 * Holds array with all the sites in multisite WP installation.
59 *
60 * @var array
61 */
62 private static $sites = array();
63
64 /**
65 * Inits the class, and fires all the necessarily methods.
66 *
67 * @return void
68 *
69 * @since 2.2.0
70 */
71 public static function init() {
72 if ( self::is_multisite() ) {
73 \add_action( 'network_admin_notices', array( __CLASS__, 'show_critical_admin_notice' ) );
74 } else {
75 \add_action( 'admin_notices', array( __CLASS__, 'show_critical_admin_notice' ) );
76 }
77 }
78
79 /**
80 * Checks if specific role exists.
81 *
82 * @param string $role - The name of the role to check.
83 *
84 * @since 2.2.0
85 */
86 public static function is_role_exists( string $role ): bool {
87 self::set_roles();
88
89 if ( in_array( $role, self::$user_roles, true ) ) {
90 return true;
91 }
92
93 return false;
94 }
95
96 /**
97 * Returns the currently available WP roles - the Human readable format is the key.
98 *
99 * @return array
100 *
101 * @since 2.2.0
102 */
103 public static function get_roles() {
104 self::set_roles();
105
106 return self::$user_roles;
107 }
108
109 /**
110 * Returns the currently available WP roles.
111 *
112 * @return array
113 *
114 * @since 2.2.0
115 */
116 public static function get_roles_wp() {
117 if ( empty( self::$user_roles_wp ) ) {
118 self::set_roles();
119 self::$user_roles_wp = array_flip( self::$user_roles );
120 }
121
122 return self::$user_roles_wp;
123 }
124
125 /**
126 * Shows critical notices to the admin.
127 *
128 * @return void
129 *
130 * @since 2.2.0
131 */
132 public static function show_critical_admin_notice() {
133 if ( User_Helper::is_admin() ) {
134 /*
135 * Gives the ability to show notices to the admins
136 */
137 \do_action( WP_2FA_PREFIX . 'critical_notice' );
138 }
139 }
140
141 /**
142 * Check is this is a multisite setup.
143 *
144 * @return bool
145 *
146 * @since 2.2.0
147 */
148 public static function is_multisite() {
149 if ( null === self::$is_multisite ) {
150 self::$is_multisite = function_exists( 'is_multisite' ) && is_multisite();
151 }
152
153 return self::$is_multisite;
154 }
155
156 /**
157 * Collects all the sites from multisite WP installation.
158 *
159 * @since 2.5.0
160 */
161 public static function get_multi_sites(): array {
162 if ( self::is_multisite() ) {
163 if ( empty( self::$sites ) ) {
164 self::$sites = \get_sites();
165 }
166
167 return self::$sites;
168 }
169
170 return array();
171 }
172
173 /**
174 * Calculating the signature.
175 *
176 * @param array $data - Array with data to create a signature for.
177 *
178 * @since 2.2.2
179 */
180 public static function calculate_api_signature( array $data ): string {
181 $now = new \DateTime( 'now', new \DateTimeZone( 'UTC' ) );
182 $nonce = $now->getTimestamp();
183
184 $pk_hash = hash( 'sha512', $data['license_key'] . '|' . $nonce );
185 $authentication_string = base64_encode( $pk_hash . '|' . $nonce );
186
187 return $authentication_string;
188 }
189
190 /**
191 * Checks if that is the WP login page or not.
192 *
193 * @return bool
194 *
195 * @since 2.4.1
196 */
197 public static function is_wp_login() {
198 $abs_path = str_replace( array( '\\', '/' ), DIRECTORY_SEPARATOR, ABSPATH );
199
200 if ( function_exists( 'is_account_page' ) && is_account_page() ) {
201 // The user is on the WooCommerce login page.
202
203 return true;
204 }
205
206 return ( in_array( $abs_path . 'wp-login.php', get_included_files() ) || in_array( $abs_path . 'wp-register.php', get_included_files() ) ) || ( isset( $GLOBALS['pagenow'] ) && 'wp-login.php' === $GLOBALS['pagenow'] ) || '/wp-login.php' == $_SERVER['PHP_SELF'];
207 }
208
209 /**
210 * Check whether we are on an admin and plugin page.
211 *
212 * @since 2.4.1
213 *
214 * @param array|string $slug ID(s) of a plugin page. Possible values: 'general', 'logs', 'about' or array of them.
215 *
216 * @return bool
217 */
218 public static function is_admin_page( $slug = array() ) { // phpcs:ignore Generic.Metrics.NestingLevel.MaxExceeded
219 // phpcs:ignore WordPress.Security.NonceVerification.Recommended
220 $cur_page = isset( $_GET['page'] ) ? sanitize_key( $_GET['page'] ) : '';
221 $check = WP_2FA_PREFIX_PAGE;
222
223 return \is_admin() && ( false !== strpos( $cur_page, $check ) );
224 }
225
226 /**
227 * Remove all non-WP Mail SMTP plugin notices from our plugin pages.
228 *
229 * @since 2.4.1
230 */
231 public static function hide_unrelated_notices() {
232 // Bail if we're not on our screen or page.
233 if ( ! self::is_admin_page() ) {
234 return;
235 }
236
237 self::remove_unrelated_actions( 'user_admin_notices' );
238 self::remove_unrelated_actions( 'admin_notices' );
239 self::remove_unrelated_actions( 'all_admin_notices' );
240 self::remove_unrelated_actions( 'network_admin_notices' );
241 }
242
243 /**
244 * Creates a nonce for HTML field by given name.
245 *
246 * @param string $nonce_name -The name of the nonce to create.
247 *
248 * @return string
249 *
250 * @since 2.6.0
251 */
252 public static function create_data_nonce( string $nonce_name ): string {
253 return ' data-nonce="' . \esc_attr( \wp_create_nonce( $nonce_name ) ) . '"';
254 }
255
256 /**
257 * Extracts the domain part of the given string.
258 *
259 * @param string $url_to_check - The URL string to be checked.
260 *
261 * @return string
262 *
263 * @since 2.6.0
264 */
265 public static function extract_domain( string $url_to_check ): string {
266 // get the full domain.
267 // $urlparts = parse_url( \site_url() );.
268
269 if ( false !== strpos( $url_to_check, '@' ) ) {
270 $domain = \explode( '@', $url_to_check )[1];
271
272 return $domain;
273 }
274 $urlparts = parse_url( $url_to_check );
275 $domain = $urlparts ['host'];
276
277 // get the TLD and domain.
278 $domainparts = explode( '.', $domain );
279 $domain = $domainparts[ count( $domainparts ) - 2 ] . '.' . $domainparts[ count( $domainparts ) - 1 ];
280
281 return $domain;
282 }
283
284 /**
285 * Remove all non-WP Mail SMTP notices from the our plugin pages based on the provided action hook.
286 *
287 * @since 2.4.1
288 *
289 * @param string $action The name of the action.
290 */
291 private static function remove_unrelated_actions( $action ) {
292 global $wp_filter;
293
294 if ( empty( $wp_filter[ $action ]->callbacks ) || ! is_array( $wp_filter[ $action ]->callbacks ) ) {
295 return;
296 }
297
298 foreach ( $wp_filter[ $action ]->callbacks as $priority => $hooks ) {
299 foreach ( $hooks as $name => $arr ) {
300 if (
301 ( // Cover object method callback case.
302 is_array( $arr['function'] ) &&
303 isset( $arr['function'][0] ) &&
304 is_object( $arr['function'][0] ) &&
305 false !== strpos( ( get_class( $arr['function'][0] ) ), 'WP2FA' )
306 ) ||
307 ( // Cover class static method callback case.
308 ! empty( $name ) &&
309 false !== strpos( ( $name ), 'WP2FA' )
310 )
311 ) {
312 continue;
313 }
314
315 unset( $wp_filter[ $action ]->callbacks[ $priority ][ $name ] );
316 }
317 }
318 }
319
320 /**
321 * Sets the internal variable with all the existing WP roles.
322 *
323 * @return void
324 *
325 * @since 2.2.0
326 */
327 private static function set_roles() {
328 if ( empty( self::$user_roles ) ) {
329 global $wp_roles;
330
331 if ( null === $wp_roles ) {
332 wp_roles();
333 }
334
335 self::$user_roles = array_flip( $wp_roles->get_names() );
336 }
337 }
338 }
339 }
340