PluginProbe ʕ •ᴥ•ʔ
WP 2FA – Two-factor authentication for WordPress / 2.8.0
WP 2FA – Two-factor authentication for WordPress v2.8.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 / Fly-Out / class-flyout.php
wp-2fa / includes / classes / Admin / Fly-Out Last commit date
assets 1 year ago class-flyout.php 1 year ago index.php 1 year ago
class-flyout.php
293 lines
1 <?php
2 /**
3 * Responsible for fly-out menu shown on some of the plugin pages.
4 *
5 * @package wp2fa
6 * @subpackage flyout
7 *
8 * @since 2.8.0
9 *
10 * @copyright 2024 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 declare(strict_types=1);
17
18 namespace WP2FA\Admin\FlyOut;
19
20 // Exit if accessed directly.
21 if ( ! defined( 'ABSPATH' ) ) {
22 exit;
23 }
24
25 if ( ! class_exists( '\WP2FA\Admin\FlyOut\FlyOut' ) ) {
26 /**
27 * Generates fly-out menu on the plugin admin screen.
28 *
29 * @since 2.8.0
30 */
31 class FlyOut {
32
33 private const ENQUEUE_NAME = 'mlp_flyout';
34 private const CONFIG_TRANSIENT_NAME = \WP_2FA_PREFIX . 'flyout_config';
35
36 /**
37 * Array with the configuration of the fly-out menu
38 *
39 * @var array
40 *
41 * @since 2.8.0
42 */
43 private static $config = array();
44
45 /**
46 * Class cache for the current screen (if admin is on it)
47 *
48 * @var bool
49 *
50 * @since 2.8.0
51 */
52 private static $screen = null;
53
54 /**
55 * Inits the class and its hooks
56 *
57 * @return void
58 *
59 * @since 2.8.0
60 */
61 public static function init() {
62 if ( ! \is_admin() ) {
63 return;
64 } else {
65 self::load_config();
66 if ( ! empty( self::$config ) ) {
67 \add_action( 'admin_enqueue_scripts', array( __CLASS__, 'admin_enqueue_scripts' ) );
68 \add_action( 'admin_head', array( __CLASS__, 'admin_head' ) );
69 \add_action( 'admin_footer', array( __CLASS__, 'admin_footer' ) );
70 }
71 }
72 }
73
74 /**
75 * Loads the external config for processing
76 *
77 * @return void
78 *
79 * @since 2.8.0
80 */
81 public static function load_config() {
82 $config = array();
83
84 $config = self::read_remote_config();
85
86 if ( false === $config ) {
87 return;
88 }
89
90 $defaults = array(
91 'plugin_screen' => '',
92 'icon_border' => '#0000ff',
93 'icon_right' => '40px',
94 'icon_bottom' => '40px',
95 'icon_image' => '',
96 'icon_padding' => '2px',
97 'icon_size' => '55px',
98 'menu_accent_color' => '#ca4a1f',
99 'custom_css' => '',
100 'menu_items' => array(),
101 );
102
103 $config = array_merge( $defaults, (array) $config );
104 if ( ! is_array( $config['plugin_screen'] ) ) {
105 $config['plugin_screen'] = array( $config['plugin_screen'] );
106 }
107
108 self::$config = $config;
109 }
110
111 /**
112 * Checks the current screen and returns true if it is the plugin one
113 *
114 * @return boolean
115 *
116 * @since 2.8.0
117 */
118 public static function is_plugin_screen(): bool {
119
120 if ( \is_null( self::$screen ) ) {
121
122 $screen = \get_current_screen();
123 self::$screen = false;
124
125 if ( in_array( $screen->id, self::$config['plugin_screen'] ) ) {
126 self::$screen = true;
127 }
128 }
129
130 return self::$screen;
131 }
132
133 /**
134 * Loads the fly-out css and JS files
135 *
136 * @return void
137 *
138 * @since 2.8.0
139 */
140 public static function admin_enqueue_scripts() {
141 if ( false === self::is_plugin_screen() ) {
142 return;
143 }
144
145 \wp_enqueue_style(
146 self::ENQUEUE_NAME,
147 WP_2FA_URL . '/includes/classes/Admin/Fly-Out/assets/css/flyout.css',
148 array(),
149 WP_2FA_VERSION
150 );
151 \wp_enqueue_script(
152 self::ENQUEUE_NAME,
153 WP_2FA_URL . '/includes/classes/Admin/Fly-Out/assets/js/flyout.js',
154 array(),
155 WP_2FA_VERSION,
156 true
157 );
158 }
159
160 /**
161 * Writes additional custom code in the header of the page
162 *
163 * @return void
164 *
165 * @since 2.8.0
166 */
167 public static function admin_head() {
168 if ( false === self::is_plugin_screen() ) {
169 return;
170 }
171
172 $out = '<style type="text/css">';
173 $out .= '#mlp-flyout {
174 right: ' . \sanitize_text_field( self::$config['icon_right'] ) . ';
175 bottom: ' . \sanitize_text_field( self::$config['icon_bottom'] ) . ';
176 }';
177 $out .= '#mlp-flyout #mlp-elmnts-image-wrapper {
178 border: ' . \sanitize_text_field( self::$config['icon_border'] ) . ';
179 }';
180 $out .= '#mlp-flyout #mlp-elmnts-button img {
181 padding: ' . \sanitize_text_field( self::$config['icon_padding'] ) . ';
182 width: ' . \sanitize_text_field( self::$config['icon_size'] ) . ';
183 height: ' . \sanitize_text_field( self::$config['icon_size'] ) . ';
184 }';
185 $out .= '#mlp-flyout .mlp-elmnts-menu-item.accent {
186 background: ' . \sanitize_text_field( self::$config['menu_accent_color'] ) . ';
187 }';
188 $out .= \sanitize_text_field( self::$config['custom_css'] );
189 $out .= '</style>';
190
191 echo $out; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
192 }
193
194 /**
195 * Writes additional custom code in the footer of the page
196 *
197 * @return void
198 *
199 * @since 2.8.0
200 */
201 public static function admin_footer() {
202 if ( false === self::is_plugin_screen() ) {
203 return;
204 }
205
206 $out = '';
207 $icons_url = WP_2FA_URL . 'assets/images/';
208 $default_link_item = array(
209 'class' => '',
210 'href' => '#',
211 'target' => '_blank',
212 'label' => '',
213 'icon' => '',
214 'data' => '',
215 );
216
217 $out .= '<div id="mlp-overlay"></div>';
218
219 $out .= '<div id="mlp-flyout">';
220
221 $out .= '<a href="#" id="mlp-elmnts-button">';
222 $out .= '<span class="mlp-elmnts-label">Open Quick Links</span>';
223 $out .= '<span id="mlp-elmnts-image-wrapper">';
224 $out .= '<img src="' . esc_url( $icons_url . self::$config['icon_image'] ) . '" alt="Open Quick Links" title="Open Quick Links">';
225 $out .= '</span>';
226 $out .= '</a>';
227
228 $out .= '<div id="mlp-elmnts-menu">';
229 $i = 0;
230 foreach ( array_reverse( self::$config['menu_items'] ) as $item ) {
231 ++$i;
232 $item = array_merge( $default_link_item, $item );
233
234 if ( ! empty( $item['icon'] ) && substr( $item['icon'], 0, 9 ) != 'dashicons' ) {
235 $item['class'] .= ' mlp-elmnts-custom-icon';
236 $item['class'] = trim( $item['class'] );
237 }
238
239 $out .= '<a ' . $item['data'] . ' href="' . esc_url( $item['href'] ) . '" class="mlp-elmnts-menu-item mlp-elmnts-menu-item-' . $i . ' ' . esc_attr( $item['class'] ) . '" target="_blank">';
240 $out .= '<span class="mlp-elmnts-label visible">' . esc_html( $item['label'] ) . '</span>';
241 if ( substr( $item['icon'], 0, 9 ) == 'dashicons' ) {
242 $out .= '<span class="dashicons ' . sanitize_text_field( $item['icon'] ) . '"></span>';
243 } elseif ( ! empty( $item['icon'] ) ) {
244 $out .= '<span class="mlp-elmnts-icon"><img src="' . esc_url( $icons_url . $item['icon'] ) . '"></span>';
245 }
246 $out .= '</a>';
247 } // foreach
248 $out .= '</div>'; // #mlp-elmnts-menu
249
250 $out .= '</div>'; // #mlp-flyout
251
252 echo $out; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
253 }
254
255 /**
256 * Reads the config file remotely and sets 2 days transient for caching. If for some reason cant read the remote - false is returned
257 *
258 * @return bool|array
259 *
260 * @since 2.8.0
261 */
262 public static function read_remote_config() {
263 $config = \get_transient( self::CONFIG_TRANSIENT_NAME );
264
265 if ( false === $config || empty( $config ) ) {
266
267 $api_response = \wp_remote_request( 'https://melapress.com/downloads/plugins-files/wp-2fa-flyout-config.php', array() );
268
269 $response_code = \wp_remote_retrieve_response_code( $api_response );
270
271 if ( \is_wp_error( $api_response ) || 200 !== (int) $response_code ) {
272
273 return false;
274 } else {
275 $config = \wp_remote_retrieve_body( $api_response );
276
277 \set_transient( self::CONFIG_TRANSIENT_NAME, $config, \DAY_IN_SECONDS * 3 );
278
279 return \json_decode( $config, true );
280 }
281 }
282
283 $config = json_decode( $config, true );
284
285 if ( json_last_error() !== JSON_ERROR_NONE ) {
286 $config = false;
287 }
288
289 return $config;
290 }
291 }
292 }
293