PluginProbe
Sessions / 2.13.1
Sessions v2.13.1
2.1.0 2.10.0 2.11.0 2.12.0 2.13.0 2.13.1 2.13.2 2.13.3 2.14.0 2.2.0 2.3.0 2.3.1 2.4.0 2.4.1 2.5.0 2.6.0 2.6.1 2.6.2 2.7.0 2.8.0 2.9.0 2.9.1 3.0.0 3.1.0 3.1.1 All 39 releases
sessions / admin / class-sessions-admin.php

class-sessions-admin.php in Sessions 2.13.1, at admin/class-sessions-admin.php

977 lines 43.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * The admin-specific functionality of the plugin.
4 *
5 * @package Plugin
6 * @author Pierre Lannoy <https://pierre.lannoy.fr/>.
7 * @since 1.0.0
8 */
9
10 namespace POSessions\Plugin;
11
12 use POSessions\Plugin\Feature\Analytics;
13 use POSessions\Plugin\Feature\AnalyticsFactory;
14 use POSessions\System\Assets;
15 use POSessions\System\Environment;
16
17 use POSessions\System\Role;
18 use POSessions\System\Option;
19 use POSessions\System\Form;
20 use POSessions\System\Blog;
21 use POSessions\System\Date;
22 use POSessions\System\Timezone;
23 use POSessions\System\GeoIP;
24 use POSessions\Plugin\Feature\LimiterTypes;
25 use PerfOpsOne\Menus;
26 use PerfOpsOne\AdminBar;
27 use POSessions\System\Statistics;
28
29 /**
30 * The admin-specific functionality of the plugin.
31 *
32 * @package Plugin
33 * @author Pierre Lannoy <https://pierre.lannoy.fr/>.
34 * @since 1.0.0
35 */
36 class Sessions_Admin {
37
38 /**
39 * The assets manager that's responsible for handling all assets of the plugin.
40 *
41 * @since 1.0.0
42 * @access protected
43 * @var Assets $assets The plugin assets manager.
44 */
45 protected $assets;
46
47 /**
48 * Initialize the class and set its properties.
49 *
50 * @since 1.0.0
51 */
52 public function __construct() {
53 $this->assets = new Assets();
54 }
55
56 /**
57 * Register the stylesheets for the admin area.
58 *
59 * @since 1.0.0
60 */
61 public function enqueue_styles() {
62 $this->assets->register_style( POSE_ASSETS_ID, POSE_ADMIN_URL, 'css/sessions.min.css' );
63 $this->assets->register_style( 'pose-daterangepicker', POSE_ADMIN_URL, 'css/daterangepicker.min.css' );
64 $this->assets->register_style( 'pose-switchery', POSE_ADMIN_URL, 'css/switchery.min.css' );
65 $this->assets->register_style( 'pose-tooltip', POSE_ADMIN_URL, 'css/tooltip.min.css' );
66 $this->assets->register_style( 'pose-chartist', POSE_ADMIN_URL, 'css/chartist.min.css' );
67 $this->assets->register_style( 'pose-chartist-tooltip', POSE_ADMIN_URL, 'css/chartist-plugin-tooltip.min.css' );
68 }
69
70 /**
71 * Register the JavaScript for the admin area.
72 *
73 * @since 1.0.0
74 */
75 public function enqueue_scripts() {
76 $this->assets->register_script( POSE_ASSETS_ID, POSE_ADMIN_URL, 'js/sessions.min.js', [ 'jquery' ] );
77 $this->assets->register_script( 'pose-moment-with-locale', POSE_ADMIN_URL, 'js/moment-with-locales.min.js', [ 'jquery' ] );
78 $this->assets->register_script( 'pose-daterangepicker', POSE_ADMIN_URL, 'js/daterangepicker.min.js', [ 'jquery' ] );
79 $this->assets->register_script( 'pose-switchery', POSE_ADMIN_URL, 'js/switchery.min.js', [ 'jquery' ] );
80 $this->assets->register_script( 'pose-chartist', POSE_ADMIN_URL, 'js/chartist.min.js', [ 'jquery' ] );
81 $this->assets->register_script( 'pose-chartist-tooltip', POSE_ADMIN_URL, 'js/chartist-plugin-tooltip.min.js', [ 'pose-chartist' ] );
82 }
83
84 /**
85 * Init PerfOps admin menus.
86 *
87 * @param array $perfops The already declared menus.
88 * @return array The completed menus array.
89 * @since 1.0.0
90 */
91 public function init_perfopsone_admin_menus( $perfops ) {
92 if ( Role::SUPER_ADMIN === Role::admin_type() || Role::SINGLE_ADMIN === Role::admin_type() ) {
93 $perfops['analytics'][] = [
94 'name' => esc_html_x( 'Sessions', 'Common name - not the name of the plugin.', 'sessions' ),
95 /* translators: as in the sentence "View sessions and accounts activity on your network." or "View sessions and accounts activity on your website." */
96 'description' => sprintf( esc_html__( 'View sessions and accounts activity on your %s.', 'sessions' ), Environment::is_wordpress_multisite() ? esc_html__( 'network', 'sessions' ) : esc_html__( 'website', 'sessions' ) ),
97 'icon_callback' => [ \POSessions\Plugin\Core::class, 'get_base64_logo' ],
98 'slug' => 'pose-viewer',
99 'page_title' => esc_html__( 'Sessions Analytics', 'sessions' ),
100 'menu_title' => esc_html_x( 'Sessions', 'Common name - not the name of the plugin.', 'sessions' ),
101 'capability' => 'manage_options',
102 'callback' => [ $this, 'get_viewer_page' ],
103 'plugin' => POSE_SLUG,
104 'activated' => Option::network_get( 'analytics' ),
105 'remedy' => esc_url( admin_url( 'admin.php?page=pose-settings&tab=misc' ) ),
106 ];
107 $perfops['tools'][] = [
108 'name' => esc_html_x( 'Sessions', 'Common name - not the name of the plugin.', 'sessions' ),
109 /* translators: as in the sentence "Browse and manage active sessions on your network." or "Browse and manage active sessions on your website." */
110 'description' => sprintf( esc_html__( 'Browse and manage active sessions on your %s.', 'sessions' ), Environment::is_wordpress_multisite() ? esc_html__( 'network', 'sessions' ) : esc_html__( 'website', 'sessions' ) ),
111 'icon_callback' => [ \POSessions\Plugin\Core::class, 'get_base64_logo' ],
112 'slug' => 'pose-manager',
113 'page_title' => esc_html__( 'Active Sessions Management', 'sessions' ),
114 'menu_title' => esc_html_x( 'Sessions', 'Common name - not the name of the plugin.', 'sessions' ),
115 'capability' => 'manage_options',
116 'callback' => [ $this, 'get_manager_page' ],
117 'plugin' => POSE_SLUG,
118 'activated' => true,
119 'remedy' => '',
120 ];
121 $perfops['settings'][] = [
122 'name' => POSE_PRODUCT_NAME,
123 'description' => '',
124 'icon_callback' => [ \POSessions\Plugin\Core::class, 'get_base64_logo' ],
125 'slug' => 'pose-settings',
126 /* translators: as in the sentence "Sessions Settings" or "WordPress Settings" */
127 'page_title' => sprintf( esc_html__( '%s Settings', 'sessions' ), POSE_PRODUCT_NAME ),
128 'menu_title' => POSE_PRODUCT_NAME,
129 'capability' => 'manage_options',
130 'callback' => [ $this, 'get_settings_page' ],
131 'plugin' => POSE_SLUG,
132 'version' => POSE_VERSION,
133 'activated' => true,
134 'remedy' => '',
135 'statistics' => [ '\POSessions\System\Statistics', 'sc_get_raw' ],
136 ];
137 }
138 return $perfops;
139 }
140
141 /**
142 * Dispatch the items in the settings menu.
143 *
144 * @since 2.0.0
145 */
146 public function finalize_admin_menus() {
147 Menus::finalize();
148 }
149
150 /**
151 * Removes unneeded items from the settings menu.
152 *
153 * @since 2.0.0
154 */
155 public function normalize_admin_menus() {
156 Menus::normalize();
157 }
158
159 /**
160 * Set the items in the settings menu.
161 *
162 * @since 1.0.0
163 */
164 public function init_admin_menus() {
165 add_filter( 'init_perfopsone_admin_menus', [ $this, 'init_perfopsone_admin_menus' ] );
166 Menus::initialize();
167 AdminBar::initialize();
168 }
169
170 /**
171 * Initializes settings sections.
172 *
173 * @since 1.0.0
174 */
175 public function init_settings_sections() {
176 add_settings_section( 'pose_plugin_features_section', esc_html__( 'Plugin Features', 'sessions' ), [ $this, 'plugin_features_section_callback' ], 'pose_plugin_features_section' );
177 add_settings_section( 'pose_plugin_messages_section', esc_html__( 'Plugin Behaviour', 'sessions' ), [ $this, 'plugin_messages_section_callback' ], 'pose_plugin_messages_section' );
178 add_settings_section( 'pose_plugin_options_section', esc_html__( 'Plugin options', 'sessions' ), [ $this, 'plugin_options_section_callback' ], 'pose_plugin_options_section' );
179 add_settings_section( 'pose_plugin_roles_section', '', [ $this, 'plugin_roles_section_callback' ], 'pose_plugin_roles_section' );
180 if ( apply_filters( 'perfopsone_show_advanced', false ) ) {
181 add_settings_section( 'pose_plugin_advanced_section', esc_html__( 'Plugin advanced options', 'sessions' ), [ $this, 'plugin_advanced_section_callback' ], 'pose_plugin_advanced_section' );
182 }
183 }
184
185 /**
186 * Add links in the "Actions" column on the plugins view page.
187 *
188 * @param string[] $actions An array of plugin action links. By default this can include 'activate',
189 * 'deactivate', and 'delete'.
190 * @param string $plugin_file Path to the plugin file relative to the plugins directory.
191 * @param array $plugin_data An array of plugin data. See `get_plugin_data()`.
192 * @param string $context The plugin context. By default this can include 'all', 'active', 'inactive',
193 * 'recently_activated', 'upgrade', 'mustuse', 'dropins', and 'search'.
194 * @return array Extended list of links to print in the "Actions" column on the Plugins page.
195 * @since 1.0.0
196 */
197 public function add_actions_links( $actions, $plugin_file, $plugin_data, $context ) {
198 $actions[] = sprintf( '<a href="%s">%s</a>', esc_url( admin_url( 'admin.php?page=pose-settings' ) ), esc_html__( 'Settings', 'sessions' ) );
199 if ( Option::network_get( 'analytics' ) ) {
200 $actions[] = sprintf( '<a href="%s">%s</a>', esc_url( admin_url( 'admin.php?page=pose-viewer' ) ), esc_html__( 'Statistics', 'sessions' ) );
201 }
202 return $actions;
203 }
204
205 /**
206 * Add links in the "Description" column on the plugins view page.
207 *
208 * @param array $links List of links to print in the "Description" column on the Plugins page.
209 * @param string $file Path to the plugin file relative to the plugins directory.
210 * @return array Extended list of links to print in the "Description" column on the Plugins page.
211 * @since 1.0.0
212 */
213 public function add_row_meta( $links, $file ) {
214 if ( 0 === strpos( $file, POSE_SLUG . '/' ) ) {
215 $links[] = '<a href="https://wordpress.org/support/plugin/' . POSE_SLUG . '/">' . __( 'Support', 'sessions' ) . '</a>';
216 }
217 return $links;
218 }
219
220 /**
221 * Get the content of the viewer page.
222 *
223 * @since 1.0.0
224 */
225 public function get_viewer_page() {
226 $analytics = AnalyticsFactory::get_analytics();
227 include POSE_ADMIN_DIR . 'partials/sessions-admin-view-analytics.php';
228 }
229
230 /**
231 * Get the content of the manager page.
232 *
233 * @since 1.0.0
234 */
235 public function get_manager_page() {
236 include POSE_ADMIN_DIR . 'partials/sessions-admin-tools.php';
237 }
238
239 /**
240 * Get the content of the settings page.
241 *
242 * @since 1.0.0
243 */
244 public function get_settings_page() {
245 if ( ! ( $tab = filter_input( INPUT_GET, 'tab' ) ) ) {
246 $tab = filter_input( INPUT_POST, 'tab' );
247 }
248 if ( ! ( $action = filter_input( INPUT_GET, 'action' ) ) ) {
249 $action = filter_input( INPUT_POST, 'action' );
250 }
251 $nonce = filter_input( INPUT_GET, 'nonce' );
252 if ( $action && $tab ) {
253 switch ( $tab ) {
254 case 'misc':
255 switch ( $action ) {
256 case 'do-save':
257 if ( Role::SUPER_ADMIN === Role::admin_type() || Role::SINGLE_ADMIN === Role::admin_type() ) {
258 if ( ! empty( $_POST ) && array_key_exists( 'submit', $_POST ) ) {
259 $this->save_options();
260 } elseif ( ! empty( $_POST ) && array_key_exists( 'reset-to-defaults', $_POST ) ) {
261 $this->reset_options();
262 }
263 }
264 break;
265 case 'install-decalog':
266 if ( class_exists( 'PerfOpsOne\Installer' ) && $nonce && wp_verify_nonce( $nonce, $action ) ) {
267 $result = \PerfOpsOne\Installer::do( 'decalog', true );
268 if ( '' === $result ) {
269 add_settings_error( 'sessions_no_error', '', esc_html__( 'Plugin successfully installed and activated with default settings.', 'sessions' ), 'info' );
270 } else {
271 add_settings_error( 'sessions_install_error', '', sprintf( esc_html__( 'Unable to install or activate the plugin. Error message: %s.', 'sessions' ), $result ), 'error' );
272 }
273 }
274 break;
275 case 'install-podd':
276 if ( class_exists( 'PerfOpsOne\Installer' ) && $nonce && wp_verify_nonce( $nonce, $action ) ) {
277 $result = \PerfOpsOne\Installer::do( 'device-detector', true );
278 if ( '' === $result ) {
279 add_settings_error( 'sessions_no_error', '', esc_html__( 'Plugin successfully installed and activated with default settings.', 'sessions' ), 'info' );
280 } else {
281 add_settings_error( 'sessions_install_error', '', sprintf( esc_html__( 'Unable to install or activate the plugin. Error message: %s.', 'sessions' ), $result ), 'error' );
282 }
283 }
284 break;
285 case 'install-iplocator':
286 if ( class_exists( 'PerfOpsOne\Installer' ) && $nonce && wp_verify_nonce( $nonce, $action ) ) {
287 $result = \PerfOpsOne\Installer::do( 'ip-locator', true );
288 if ( '' === $result ) {
289 add_settings_error( 'sessions_no_error', '', esc_html__( 'Plugin successfully installed and activated with default settings.', 'sessions' ), 'info' );
290 } else {
291 add_settings_error( 'sessions_install_error', '', sprintf( esc_html__( 'Unable to install or activate the plugin. Error message: %s.', 'sessions' ), $result ), 'error' );
292 }
293 }
294 break;
295 }
296 break;
297 case 'roles':
298 switch ( $action ) {
299 case 'do-save':
300 $this->save_roles_options();
301 break;
302 }
303 break;
304 }
305 }
306 include POSE_ADMIN_DIR . 'partials/sessions-admin-settings-main.php';
307 }
308
309 /**
310 * Save the core plugin options.
311 *
312 * @since 1.0.0
313 */
314 private function save_roles_options() {
315 if ( ! empty( $_POST ) ) {
316 if ( array_key_exists( '_wpnonce', $_POST ) && wp_verify_nonce( $_POST['_wpnonce'], 'pose-plugin-options' ) ) {
317 $settings = Option::roles_get();
318 foreach ( Role::get_all() as $role => $detail ) {
319 foreach ( Option::$specific as $spec ) {
320 if ( array_key_exists( 'pose_plugin_roles_' . $spec . '_' . $role, $_POST ) ) {
321 $settings[ $role ][ $spec ] = filter_input( INPUT_POST, 'pose_plugin_roles_' . $spec . '_' . $role );
322 }
323 }
324 }
325 Option::roles_set( $settings );
326 $message = esc_html__( 'Plugin settings have been saved.', 'sessions' );
327 $message .= '<br/>' . esc_html__( 'Note these settings will only affect new sessions.', 'sessions' );
328 $message .= ' ' . esc_html__( 'For immediate implementation for all accounts, you must delete all active sessions.', 'sessions' );
329 $code = 0;
330 add_settings_error( 'pose_no_error', $code, $message, 'updated' );
331 \DecaLog\Engine::eventsLogger( POSE_SLUG )->info( 'Plugin settings updated.', [ 'code' => $code ] );
332 } else {
333 $message = esc_html__( 'Plugin settings have not been saved. Please try again.', 'sessions' );
334 $code = 2;
335 add_settings_error( 'pose_nonce_error', $code, $message, 'error' );
336 \DecaLog\Engine::eventsLogger( POSE_SLUG )->warning( 'Plugin settings not updated.', [ 'code' => $code ] );
337 }
338 }
339 }
340
341 /**
342 * Save the plugin options.
343 *
344 * @since 1.0.0
345 */
346 private function save_options() {
347 if ( ! empty( $_POST ) ) {
348 if ( array_key_exists( '_wpnonce', $_POST ) && wp_verify_nonce( $_POST['_wpnonce'], 'pose-plugin-options' ) ) {
349 Option::network_set( 'use_cdn', array_key_exists( 'pose_plugin_options_usecdn', $_POST ) ? (bool) filter_input( INPUT_POST, 'pose_plugin_options_usecdn' ) : false );
350 Option::network_set( 'display_nag', array_key_exists( 'pose_plugin_options_nag', $_POST ) ? (bool) filter_input( INPUT_POST, 'pose_plugin_options_nag' ) : false );
351 Option::network_set( 'analytics', array_key_exists( 'pose_plugin_features_analytics', $_POST ) ? (bool) filter_input( INPUT_POST, 'pose_plugin_features_analytics' ) : false );
352 Option::network_set( 'metrics', array_key_exists( 'pose_plugin_features_metrics', $_POST ) ? (bool) filter_input( INPUT_POST, 'pose_plugin_features_metrics' ) : false );
353 Option::network_set( 'forceip', array_key_exists( 'pose_plugin_features_forceip', $_POST ) ? (bool) filter_input( INPUT_POST, 'pose_plugin_features_forceip' ) : false );
354 Option::network_set( 'killonreset', array_key_exists( 'pose_plugin_features_killonreset', $_POST ) ? (bool) filter_input( INPUT_POST, 'pose_plugin_features_killonreset' ) : false );
355 Option::network_set( 'followip', array_key_exists( 'pose_plugin_features_followip', $_POST ) ? (bool) filter_input( INPUT_POST, 'pose_plugin_features_followip' ) : false );
356 Option::network_set( 'history', array_key_exists( 'pose_plugin_features_history', $_POST ) ? (string) filter_input( INPUT_POST, 'pose_plugin_features_history', FILTER_SANITIZE_NUMBER_INT ) : Option::network_get( 'history' ) );
357 Option::network_set( 'rolemode', array_key_exists( 'pose_plugin_features_rolemode', $_POST ) ? (string) filter_input( INPUT_POST, 'pose_plugin_features_rolemode', FILTER_SANITIZE_NUMBER_INT ) : Option::network_get( 'rolemode' ) );
358 Option::network_set( 'bad_ip_message', array_key_exists( 'pose_plugin_messages_bad_ip_message', $_POST ) ? (string) filter_input( INPUT_POST, 'pose_plugin_messages_bad_ip_message', FILTER_SANITIZE_FULL_SPECIAL_CHARS ) : Option::network_get( 'bad_ip_message' ) );
359 Option::network_set( 'blocked_message', array_key_exists( 'pose_plugin_messages_blocked_message', $_POST ) ? (string) filter_input( INPUT_POST, 'pose_plugin_messages_blocked_message', FILTER_SANITIZE_FULL_SPECIAL_CHARS ) : Option::network_get( 'blocked_message' ) );
360 Option::network_set( 'fallback', array_key_exists( 'pose_plugin_messages_fallback', $_POST ) ? (string) filter_input( INPUT_POST, 'pose_plugin_messages_fallback', FILTER_SANITIZE_URL ) : Option::network_get( 'fallback' ) );
361 Option::network_set( 'zk_semaphore', array_key_exists( 'pose_plugin_advanced_zk_semaphore', $_POST ) ? (string) filter_input( INPUT_POST, 'pose_plugin_advanced_zk_semaphore', FILTER_SANITIZE_NUMBER_INT ) : Option::network_get( 'zk_semaphore' ) );
362 Option::network_set( 'zk_cycle', array_key_exists( 'pose_plugin_advanced_zk_cycle', $_POST ) ? (string) filter_input( INPUT_POST, 'pose_plugin_advanced_zk_cycle', FILTER_SANITIZE_NUMBER_INT ) : Option::network_get( 'zk_cycle' ) );
363 Option::network_set( 'zk_tsize', array_key_exists( 'pose_plugin_advanced_zk_tsize', $_POST ) ? (string) filter_input( INPUT_POST, 'pose_plugin_advanced_zk_tsize', FILTER_SANITIZE_NUMBER_INT ) : Option::network_get( 'zk_tsize' ) );
364 Option::network_set( 'buffer_limit', array_key_exists( 'pose_plugin_advanced_buffer_limit', $_POST ) ? (string) filter_input( INPUT_POST, 'pose_plugin_advanced_buffer_limit', FILTER_SANITIZE_NUMBER_INT ) : Option::network_get( 'buffer_limit' ) );
365 $message = esc_html__( 'Plugin settings have been saved.', 'sessions' );
366 $code = 0;
367 add_settings_error( 'pose_no_error', $code, $message, 'updated' );
368 \DecaLog\Engine::eventsLogger( POSE_SLUG )->info( 'Plugin settings updated.', [ 'code' => $code ] );
369 } else {
370 $message = esc_html__( 'Plugin settings have not been saved. Please try again.', 'sessions' );
371 $code = 2;
372 add_settings_error( 'pose_nonce_error', $code, $message, 'error' );
373 \DecaLog\Engine::eventsLogger( POSE_SLUG )->warning( 'Plugin settings not updated.', [ 'code' => $code ] );
374 }
375 }
376 }
377
378 /**
379 * Reset the plugin options.
380 *
381 * @since 1.0.0
382 */
383 private function reset_options() {
384 if ( ! empty( $_POST ) ) {
385 if ( array_key_exists( '_wpnonce', $_POST ) && wp_verify_nonce( $_POST['_wpnonce'], 'pose-plugin-options' ) ) {
386 Option::reset_to_defaults();
387 $message = esc_html__( 'Plugin settings have been reset to defaults.', 'sessions' );
388 $code = 0;
389 add_settings_error( 'pose_no_error', $code, $message, 'updated' );
390 \DecaLog\Engine::eventsLogger( POSE_SLUG )->info( 'Plugin settings reset to defaults.', [ 'code' => $code ] );
391 } else {
392 $message = esc_html__( 'Plugin settings have not been reset to defaults. Please try again.', 'sessions' );
393 $code = 2;
394 add_settings_error( 'pose_nonce_error', $code, $message, 'error' );
395 \DecaLog\Engine::eventsLogger( POSE_SLUG )->warning( 'Plugin settings not reset to defaults.', [ 'code' => $code ] );
396 }
397 }
398 }
399
400 /**
401 * Callback for plugin advanced section.
402 *
403 * @since 1.0.0
404 */
405 public function plugin_advanced_section_callback() {
406 $form = new Form();
407 add_settings_field(
408 'pose_plugin_advanced_buffer_limit',
409 'List size',
410 [ $form, 'echo_field_input_integer' ],
411 'pose_plugin_advanced_section',
412 'pose_plugin_advanced_section',
413 [
414 'id' => 'pose_plugin_advanced_buffer_limit',
415 'value' => Option::network_get( 'buffer_limit' ),
416 'min' => 1000,
417 'max' => 200000,
418 'step' => 1000,
419 'description' => 'List size, in number of items.',
420 'full_width' => true,
421 'enabled' => true,
422 ]
423 );
424 register_setting( 'pose_plugin_advanced_section', 'pose_plugin_advanced_buffer_limit' );
425 add_settings_field(
426 'pose_plugin_advanced_zk_tsize',
427 'Zookeeper size',
428 [ $form, 'echo_field_input_integer' ],
429 'pose_plugin_advanced_section',
430 'pose_plugin_advanced_section',
431 [
432 'id' => 'pose_plugin_advanced_zk_tsize',
433 'value' => Option::network_get( 'zk_tsize' ),
434 'min' => 10,
435 'max' => 1000,
436 'step' => 10,
437 'description' => 'Batch size, in number of items.',
438 'full_width' => true,
439 'enabled' => true,
440 ]
441 );
442 register_setting( 'pose_plugin_advanced_section', 'pose_plugin_advanced_zk_tsize' );
443 add_settings_field(
444 'pose_plugin_advanced_zk_semaphore',
445 'Zookeeper semaphore',
446 [ $form, 'echo_field_input_integer' ],
447 'pose_plugin_advanced_section',
448 'pose_plugin_advanced_section',
449 [
450 'id' => 'pose_plugin_advanced_zk_semaphore',
451 'value' => Option::network_get( 'zk_semaphore' ),
452 'min' => 300,
453 'max' => 1800,
454 'step' => 60,
455 'description' => 'Semaphore auto release, in seconds.',
456 'full_width' => true,
457 'enabled' => true,
458 ]
459 );
460 register_setting( 'pose_plugin_advanced_section', 'pose_plugin_advanced_zk_semaphore' );
461 add_settings_field(
462 'pose_plugin_advanced_zk_cycle',
463 'Zookeeper cycle',
464 [ $form, 'echo_field_input_integer' ],
465 'pose_plugin_advanced_section',
466 'pose_plugin_advanced_section',
467 [
468 'id' => 'pose_plugin_advanced_zk_cycle',
469 'value' => Option::network_get( 'zk_cycle' ),
470 'min' => 60,
471 'max' => 1800,
472 'step' => 30,
473 'description' => 'Cycle duration, in seconds. Must be less than semaphore value.',
474 'full_width' => true,
475 'enabled' => true,
476 ]
477 );
478 register_setting( 'pose_plugin_advanced_section', 'pose_plugin_advanced_zk_cycle' );
479 }
480
481 /**
482 * Callback for plugin options section.
483 *
484 * @since 1.0.0
485 */
486 public function plugin_options_section_callback() {
487 $form = new Form();
488 if ( \DecaLog\Engine::isDecalogActivated() ) {
489 $help = '<img style="width:16px;vertical-align:text-bottom;" src="' . \Feather\Icons::get_base64( 'thumbs-up', 'none', '#00C800' ) . '" />&nbsp;';
490 $help .= sprintf( esc_html__( 'Your site is currently using %s.', 'sessions' ), '<em>' . \DecaLog\Engine::getVersionString() . '</em>' );
491 } else {
492 $help = '<img style="width:16px;vertical-align:text-bottom;" src="' . \Feather\Icons::get_base64( 'alert-triangle', 'none', '#FF8C00' ) . '" />&nbsp;';
493 $help .= sprintf( esc_html__( 'Your site does not use any logging plugin. To log all events triggered in Sessions, I recommend you to install the excellent (and free) %s. But it is not mandatory.', 'sessions' ), '<a href="https://wordpress.org/plugins/decalog/">DecaLog</a>' );
494 if ( class_exists( 'PerfOpsOne\Installer' ) && ! Environment::is_wordpress_multisite() ) {
495 $help .= '<br/><a href="' . wp_nonce_url( admin_url( 'admin.php?page=pose-settings&tab=misc&action=install-decalog' ), 'install-decalog', 'nonce' ) . '" class="poo-button-install"><img style="width:16px;vertical-align:text-bottom;" src="' . \Feather\Icons::get_base64( 'download-cloud', 'none', '#FFFFFF', 3 ) . '" />&nbsp;&nbsp;' . esc_html__('Install It Now', 'sessions' ) . '</a>';
496 }
497 }
498 add_settings_field(
499 'pose_plugin_options_logger',
500 esc_html__( 'Logging', 'sessions' ),
501 [ $form, 'echo_field_simple_text' ],
502 'pose_plugin_options_section',
503 'pose_plugin_options_section',
504 [
505 'text' => $help,
506 ]
507 );
508 register_setting( 'pose_plugin_options_section', 'pose_plugin_options_logger' );
509 if ( class_exists( 'PODeviceDetector\API\Device' ) ) {
510 $help = '<img style="width:16px;vertical-align:text-bottom;" src="' . \Feather\Icons::get_base64( 'thumbs-up', 'none', '#00C800' ) . '" />&nbsp;';
511 $help .= sprintf( esc_html__( 'Your site is currently using %s.', 'sessions' ), '<em>Device Detector v' . PODD_VERSION . '</em>' );
512 } else {
513 $help = '<img style="width:16px;vertical-align:text-bottom;" src="' . \Feather\Icons::get_base64( 'alert-triangle', 'none', '#FF8C00' ) . '" />&nbsp;';
514 $help .= sprintf( esc_html__( 'Your site does not use any device detection mechanism. To allow device differentiation in Sessions, I recommend you to install the excellent (and free) %s. But it is not mandatory.', 'sessions' ), '<a href="https://wordpress.org/plugins/device-detector/">Device Detector</a>' );
515 if ( class_exists( 'PerfOpsOne\Installer' ) && ! Environment::is_wordpress_multisite() ) {
516 $help .= '<br/><a href="' . wp_nonce_url( admin_url( 'admin.php?page=pose-settings&tab=misc&action=install-podd' ), 'install-podd', 'nonce' ) . '" class="poo-button-install"><img style="width:16px;vertical-align:text-bottom;" src="' . \Feather\Icons::get_base64( 'download-cloud', 'none', '#FFFFFF', 3 ) . '" />&nbsp;&nbsp;' . esc_html__('Install It Now', 'sessions' ) . '</a>';
517 }
518 }
519 add_settings_field(
520 'pose_plugin_options_podd',
521 __( 'Device detection', 'sessions' ),
522 [ $form, 'echo_field_simple_text' ],
523 'pose_plugin_options_section',
524 'pose_plugin_options_section',
525 [
526 'text' => $help,
527 ]
528 );
529 register_setting( 'pose_plugin_options_section', 'pose_plugin_options_podd' );
530 $geo_ip = new GeoIP();
531 if ( $geo_ip->is_installed() ) {
532 $help = '<img style="width:16px;vertical-align:text-bottom;" src="' . \Feather\Icons::get_base64( 'thumbs-up', 'none', '#00C800' ) . '" />&nbsp;';
533 $help .= sprintf( esc_html__( 'Your site is currently using %s.', 'sessions' ), '<em>' . $geo_ip->get_full_name() . '</em>' );
534 } else {
535 $help = '<img style="width:16px;vertical-align:text-bottom;" src="' . \Feather\Icons::get_base64( 'alert-triangle', 'none', '#FF8C00' ) . '" />&nbsp;';
536 $help .= sprintf( esc_html__( 'Your site does not use any IP geographic information plugin. To allow country differentiation in Sessions, I recommend you to install the excellent (and free) %s. But it is not mandatory.', 'sessions' ), '<a href="https://wordpress.org/plugins/ip-locator/">IP Locator</a>' );
537 if ( class_exists( 'PerfOpsOne\Installer' ) && ! Environment::is_wordpress_multisite() ) {
538 $help .= '<br/><a href="' . wp_nonce_url( admin_url( 'admin.php?page=pose-settings&tab=misc&action=install-iplocator' ), 'install-iplocator', 'nonce' ) . '" class="poo-button-install"><img style="width:16px;vertical-align:text-bottom;" src="' . \Feather\Icons::get_base64( 'download-cloud', 'none', '#FFFFFF', 3 ) . '" />&nbsp;&nbsp;' . esc_html__('Install It Now', 'sessions' ) . '</a>';
539 }
540 }
541 add_settings_field(
542 'pose_plugin_options_geoip',
543 __( 'IP information', 'sessions' ),
544 [ $form, 'echo_field_simple_text' ],
545 'pose_plugin_options_section',
546 'pose_plugin_options_section',
547 [
548 'text' => $help,
549 ]
550 );
551 register_setting( 'pose_plugin_options_section', 'pose_plugin_options_geoip' );
552 add_settings_field(
553 'pose_plugin_options_usecdn',
554 esc_html__( 'Resources', 'sessions' ),
555 [ $form, 'echo_field_checkbox' ],
556 'pose_plugin_options_section',
557 'pose_plugin_options_section',
558 [
559 'text' => esc_html__( 'Use public CDN', 'sessions' ),
560 'id' => 'pose_plugin_options_usecdn',
561 'checked' => Option::network_get( 'use_cdn' ),
562 'description' => esc_html__( 'If checked, Sessions will use a public CDN (jsDelivr) to serve scripts and stylesheets.', 'sessions' ),
563 'full_width' => false,
564 'enabled' => true,
565 ]
566 );
567 register_setting( 'pose_plugin_options_section', 'pose_plugin_options_usecdn' );
568 add_settings_field(
569 'pose_plugin_options_nag',
570 esc_html__( 'Admin notices', 'sessions' ),
571 [ $form, 'echo_field_checkbox' ],
572 'pose_plugin_options_section',
573 'pose_plugin_options_section',
574 [
575 'text' => esc_html__( 'Display', 'sessions' ),
576 'id' => 'pose_plugin_options_nag',
577 'checked' => Option::network_get( 'display_nag' ),
578 'description' => esc_html__( 'Allows Sessions to display admin notices throughout the admin dashboard.', 'sessions' ) . '<br/>' . esc_html__( 'Note: Sessions respects DISABLE_NAG_NOTICES flag.', 'sessions' ),
579 'full_width' => false,
580 'enabled' => true,
581 ]
582 );
583 register_setting( 'pose_plugin_options_section', 'pose_plugin_options_nag' );
584 }
585
586 /**
587 * Get the available history retentions.
588 *
589 * @return array An array containing the history modes.
590 * @since 1.0.0
591 */
592 protected function get_retentions_array() {
593 $result = [];
594 for ( $i = 1; $i < 7; $i++ ) {
595 // phpcs:ignore
596 $result[] = [ (int) ( 30 * $i ), esc_html( sprintf( _n( '%d month', '%d months', $i, 'sessions' ), $i ) ) ];
597 }
598 for ( $i = 1; $i < 7; $i++ ) {
599 // phpcs:ignore
600 $result[] = [ (int) ( 365 * $i ), esc_html( sprintf( _n( '%d year', '%d years', $i, 'sessions' ), $i ) ) ];
601 }
602 return $result;
603 }
604
605 /**
606 * Callback for plugin messages section.
607 *
608 * @since 2.3.0
609 */
610 public function plugin_messages_section_callback() {
611 $form = new Form();
612 add_settings_field(
613 'pose_plugin_messages_fallback',
614 esc_html__( 'Fallback page', 'sessions' ),
615 [ $form, 'echo_field_input_text' ],
616 'pose_plugin_messages_section',
617 'pose_plugin_messages_section',
618 [
619 'id' => 'pose_plugin_messages_fallback',
620 'value' => Option::network_get( 'fallback' ),
621 'description' => esc_html__( 'Full URL of the fallback page.', 'sessions' ) . '<br/>' . __( 'To help you to customize your fallback page, a parameter named <code>reason</code> will be added to this url.', 'sessions' ),
622 'full_width' => false,
623 'placeholder' => '',
624 'enabled' => true,
625 ]
626 );
627 register_setting( 'pose_plugin_messages_section', 'pose_plugin_messages_fallback' );
628 add_settings_field(
629 'pose_plugin_messages_blocked_message',
630 esc_html__( 'Session not allowed', 'sessions' ),
631 [ $form, 'echo_field_input_text' ],
632 'pose_plugin_messages_section',
633 'pose_plugin_messages_section',
634 [
635 'id' => 'pose_plugin_messages_blocked_message',
636 'value' => Option::network_get( 'blocked_message' ),
637 'description' => esc_html__( 'Custom message shown to the user. If not set, default message is used.', 'sessions' ) . '<br/>' . sprintf( esc_html__( 'Default message is "%s".', 'sessions'), esc_html__( 'You\'re not allowed to initiate a new session because your maximum number of active sessions has been reached.', 'sessions' ) ),
638 'full_width' => false,
639 'placeholder' => '',
640 'enabled' => true,
641 ]
642 );
643 register_setting( 'pose_plugin_messages_section', 'pose_plugin_messages_blocked_message' );
644 add_settings_field(
645 'pose_plugin_messages_bad_ip_message',
646 esc_html__( 'IP not allowed', 'sessions' ),
647 [ $form, 'echo_field_input_text' ],
648 'pose_plugin_messages_section',
649 'pose_plugin_messages_section',
650 [
651 'id' => 'pose_plugin_messages_bad_ip_message',
652 'value' => Option::network_get( 'bad_ip_message' ),
653 'description' => esc_html__( 'Custom message shown to the user. If not set, default message is used.', 'sessions' ) . '<br/>' . sprintf( esc_html__( 'Default message is "%s".', 'sessions'), esc_html__( 'You\'re not allowed to initiate a new session from your current IP address.', 'sessions' ) ),
654 'full_width' => false,
655 'placeholder' => '',
656 'enabled' => true,
657 ]
658 );
659 register_setting( 'pose_plugin_messages_section', 'pose_plugin_messages_bad_ip_message' );
660 }
661
662 /**
663 * Callback for plugin features section.
664 *
665 * @since 1.0.0
666 */
667 public function plugin_features_section_callback() {
668 $form = new Form();
669 $mode = [];
670 $mode[] = [ -1, esc_html__( 'Disabled - Don\'t limit sessions by roles', 'sessions' ) ];
671 $mode[] = [ 0, esc_html__( 'Enabled - Cumulative privileges', 'sessions' ) ];
672 $mode[] = [ 1, esc_html__( 'Enabled - Least privileges', 'sessions' ) ];
673 add_settings_field(
674 'pose_plugin_features_rolemode',
675 esc_html__( 'Settings by roles', 'sessions' ),
676 [ $form, 'echo_field_select' ],
677 'pose_plugin_features_section',
678 'pose_plugin_features_section',
679 [
680 'list' => $mode,
681 'id' => 'pose_plugin_features_rolemode',
682 'value' => Option::network_get( 'rolemode' ),
683 'description' => esc_html__( 'Operation mode of sessions limiter.', 'sessions' ) . '<br/><em>' . esc_html__( 'Note: administrators having other roles are not affected by the privileges computation; this privileges computation only applies on non-administrator users having multiple roles.', 'sessions' ) . '</em>',
684 'full_width' => false,
685 'enabled' => true,
686 ]
687 );
688 register_setting( 'pose_plugin_features_section', 'pose_plugin_features_rolemode' );
689 add_settings_field(
690 'pose_plugin_features_forceip',
691 esc_html__( 'IP detection', 'sessions' ),
692 [ $form, 'echo_field_checkbox' ],
693 'pose_plugin_features_section',
694 'pose_plugin_features_section',
695 [
696 'text' => esc_html__( 'Override WordPress', 'sessions' ),
697 'id' => 'pose_plugin_features_forceip',
698 'checked' => Option::network_get( 'forceip' ),
699 'description' => esc_html__( 'If checked, Sessions will improve IP detection used for tokens (recommended).', 'sessions' ),
700 'full_width' => false,
701 'enabled' => true,
702 ]
703 );
704 register_setting( 'pose_plugin_features_section', 'pose_plugin_features_forceip' );
705 add_settings_field(
706 'pose_plugin_features_followip',
707 esc_html__( 'IP follow-up', 'sessions' ),
708 [ $form, 'echo_field_checkbox' ],
709 'pose_plugin_features_section',
710 'pose_plugin_features_section',
711 [
712 'text' => esc_html__( 'Activated', 'sessions' ),
713 'id' => 'pose_plugin_features_followip',
714 'checked' => Option::network_get( 'followip' ),
715 'description' => esc_html__( 'If checked, Sessions will refresh IPs when a session is resumed (recommended).', 'sessions' ),
716 'full_width' => false,
717 'enabled' => true,
718 ]
719 );
720 register_setting( 'pose_plugin_features_section', 'pose_plugin_features_followip' );
721 add_settings_field(
722 'pose_plugin_features_killonreset',
723 esc_html__( 'On password reset', 'sessions' ),
724 [ $form, 'echo_field_checkbox' ],
725 'pose_plugin_features_section',
726 'pose_plugin_features_section',
727 [
728 'text' => esc_html__( 'Delete current sessions', 'sessions' ),
729 'id' => 'pose_plugin_features_killonreset',
730 'checked' => Option::network_get( 'killonreset' ),
731 'description' => esc_html__( 'If checked, Sessions will delete all sessions of users resetting their passwords (recommended).', 'sessions' ),
732 'full_width' => false,
733 'enabled' => true,
734 ]
735 );
736 register_setting( 'pose_plugin_features_section', 'pose_plugin_features_killonreset' );
737 add_settings_field(
738 'pose_plugin_features_analytics',
739 esc_html__( 'Analytics', 'sessions' ),
740 [ $form, 'echo_field_checkbox' ],
741 'pose_plugin_features_section',
742 'pose_plugin_features_section',
743 [
744 'text' => esc_html__( 'Activated', 'sessions' ),
745 'id' => 'pose_plugin_features_analytics',
746 'checked' => Option::network_get( 'analytics' ),
747 'description' => esc_html__( 'If checked, Sessions will store statistics about accounts and sessions.', 'sessions' ),
748 'full_width' => false,
749 'enabled' => true,
750 ]
751 );
752 register_setting( 'pose_plugin_features_section', 'pose_plugin_features_analytics' );
753 add_settings_field(
754 'pose_plugin_features_history',
755 esc_html__( 'Historical data', 'sessions' ),
756 [ $form, 'echo_field_select' ],
757 'pose_plugin_features_section',
758 'pose_plugin_features_section',
759 [
760 'list' => $this->get_retentions_array(),
761 'id' => 'pose_plugin_features_history',
762 'value' => Option::network_get( 'history' ),
763 'description' => esc_html__( 'Maximum age of data to keep for statistics.', 'sessions' ),
764 'full_width' => false,
765 'enabled' => true,
766 ]
767 );
768 register_setting( 'pose_plugin_features_section', 'pose_plugin_features_history' );
769 add_settings_field(
770 'pose_plugin_features_metrics',
771 esc_html__( 'Metrics', 'sessions' ),
772 [ $form, 'echo_field_checkbox' ],
773 'pose_plugin_features_section',
774 'pose_plugin_features_section',
775 [
776 'text' => esc_html__( 'Activated', 'sessions' ),
777 'id' => 'pose_plugin_features_metrics',
778 'checked' => \DecaLog\Engine::isDecalogActivated() ? Option::network_get( 'metrics' ) : false,
779 'description' => esc_html__( 'If checked, Sessions will collate and publish sessions metrics.', 'sessions' ) . '<br/>' . ( \DecaLog\Engine::isDecalogActivated() ? esc_html__( 'Note: for this to work, you must enable analytics.', 'sessions' ) : esc_html__( 'Note: for this to work, you must install DecaLog.', 'sessions' ) ),
780 'full_width' => false,
781 'enabled' => \DecaLog\Engine::isDecalogActivated(),
782 ]
783 );
784 register_setting( 'pose_plugin_features_section', 'pose_plugin_features_metrics' );
785 }
786
787 /**
788 * Get the available history retentions.
789 *
790 * @return array An array containing the history modes.
791 * @since 1.0.0
792 */
793 protected function get_session_count_array() {
794 $result = [];
795 $result[] = [ 'none', esc_html__( 'No limit', 'sessions' ) ];
796 foreach ( LimiterTypes::$selector_names as $key => $name ) {
797 for ( $i = 1; $i <= 9; $i++ ) {
798 if ( '' === $name ) {
799 $result[] = [ $key . '-' . $i, esc_html( sprintf( _n( '%d session per user', '%d sessions per user', $i, 'sessions' ), $i ) ), LimiterTypes::is_selector_available( $key ) ];
800 } else {
801 // phpcs:ignore
802 $result[] = [ $key . '-' . $i, esc_html( sprintf( _n( '%d session per user and per %s', '%d sessions per user and per %s', $i, 'sessions' ), $i, $name ) ), LimiterTypes::is_selector_available( $key ) ];
803 }
804 }
805 }
806 return $result;
807 }
808
809 /**
810 * Callback for plugin roles modification section.
811 *
812 * @since 1.0.0
813 */
814 public function plugin_roles_section_callback() {
815 $settings = Option::roles_get();
816 $blocks = [];
817 $blocks[] = [ 'none', esc_html__( 'Allow from everywhere', 'sessions' ) ];
818 $blocks[] = [ 'external', esc_html__( 'Allow only from private IP ranges', 'sessions' ) ];
819 $blocks[] = [ 'local', esc_html__( 'Allow only from public IP ranges', 'sessions' ) ];
820 $methods = [];
821 $methods[] = [ 'override', esc_html__( 'Override oldest session', 'sessions' ) ];
822 /* translators: please, do not translate the strings [HTTP 403 / Forbidden] and [HTTP 303 / See Other] as they are a standard HTTP headers. */
823 $methods[] = [ 'block', esc_html__( 'Block and send a "HTTP 403 / Forbidden" error', 'sessions' ) ];
824 $methods[] = [ 'redirect', esc_html__( 'Block and redirect to the fallback page with a "HTTP 303 / See Other" code', 'sessions' ) ];
825 $methods[] = [ 'default', esc_html__( 'Block and send a WordPress error', 'sessions' ) ];
826 $idle = [];
827 $idle[] = [ 0, esc_html__( 'Never terminate an idle session', 'sessions' ) ];
828 foreach ( [ 115, 130, 145 ] as $m ) {
829 // phpcs:ignore
830 $idle[] = [ $m, esc_html( sprintf( _n( 'Terminate a session when idle for more than %d minute', 'Terminate a session when idle for more than %d minutes', $m - 100 , 'sessions' ), $m - 100 ) ) ];
831 }
832 foreach ( [ 1, 2, 3, 4, 5, 6, 12, 18, 24, 36, 48, 72 ] as $h ) {
833 // phpcs:ignore
834 $idle[] = [ $h, esc_html( sprintf( _n( 'Terminate a session when idle for more than %d hour', 'Terminate a session when idle for more than %d hours', $h, 'sessions' ), $h ) ) ];
835 }
836 $maxip = [];
837 $maxip[] = [ 0, esc_html__( 'Unlimited', 'sessions' ) ];
838 foreach ( [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ] as $h ) {
839 // phpcs:ignore
840 $maxip[] = [ $h, esc_html( sprintf( _n( '%d IP address', '%d IP addresses', $h, 'sessions' ), $h ) ) ];
841 }
842 $ttl = [];
843 foreach ( [ 1, 2, 3, 4, 5, 6 ] as $h ) {
844 // phpcs:ignore
845 $ttl[] = [ 24 * $h, esc_html( sprintf( _n( '%d day', '%d days', $h, 'sessions' ), $h ) ) ];
846 }
847 foreach ( [ 1, 2, 3, 4 ] as $h ) {
848 // phpcs:ignore
849 $ttl[] = [ 24 * 7 * $h, esc_html( sprintf( _n( '%d week', '%d weeks', $h, 'sessions' ), $h ) ) ];
850 }
851 foreach ( [ 1, 2, 3, 4, 5, 6 ] as $h ) {
852 // phpcs:ignore
853 $ttl[] = [ 24 * 30 * $h, esc_html( sprintf( _n( '%d month', '%d months', $h, 'sessions' ), $h ) ) ];
854 }
855 foreach ( [ 1, 2, 3 ] as $h ) {
856 // phpcs:ignore
857 $ttl[] = [ 24 * 365 * $h, esc_html( sprintf( _n( '%d year', '%d years', $h, 'sessions' ), $h ) ) ];
858 }
859 $form = new Form();
860 foreach ( Role::get_all() as $role => $detail ) {
861 add_settings_field(
862 'pose_plugin_roles_block_' . $role,
863 $detail['l10n_name'],
864 [ $form, 'echo_field_select' ],
865 'pose_plugin_roles_section',
866 'pose_plugin_roles_section',
867 [
868 'list' => $blocks,
869 'id' => 'pose_plugin_roles_block_' . $role,
870 'value' => $settings[ $role ]['block'],
871 'description' => esc_html__( 'Allowed IP for logins. A user trying to login from a disallowed IP range will always receive a HTTP/403 error.', 'sessions' ),
872 'full_width' => false,
873 'enabled' => true,
874 ]
875 );
876 register_setting( 'pose_plugin_roles_section', 'pose_plugin_roles_block_' . $role );
877 add_settings_field(
878 'pose_plugin_roles_maxip_' . $role,
879 '',
880 [ $form, 'echo_field_select' ],
881 'pose_plugin_roles_section',
882 'pose_plugin_roles_section',
883 [
884 'list' => $maxip,
885 'id' => 'pose_plugin_roles_maxip_' . $role,
886 'value' => $settings[ $role ]['maxip'],
887 'description' => esc_html__( 'Maximal number of IP per user. Requires IP follow-up to be activated - see "Options" tab.', 'sessions' ),
888 'full_width' => false,
889 'enabled' => true,
890 ]
891 );
892 register_setting( 'pose_plugin_roles_section', 'pose_plugin_roles_maxip_' . $role );
893 add_settings_field(
894 'pose_plugin_roles_limit_' . $role,
895 '',
896 [ $form, 'echo_field_select' ],
897 'pose_plugin_roles_section',
898 'pose_plugin_roles_section',
899 [
900 'list' => $this->get_session_count_array(),
901 'id' => 'pose_plugin_roles_limit_' . $role,
902 'value' => $settings[ $role ]['limit'],
903 'description' => esc_html__( 'Maximal number of sessions for users.', 'sessions' ),
904 'full_width' => false,
905 'enabled' => true,
906 ]
907 );
908 register_setting( 'pose_plugin_roles_section', 'pose_plugin_roles_limit_' . $role );
909 add_settings_field(
910 'pose_plugin_roles_method_' . $role,
911 '',
912 [ $form, 'echo_field_select' ],
913 'pose_plugin_roles_section',
914 'pose_plugin_roles_section',
915 [
916 'list' => $methods,
917 'id' => 'pose_plugin_roles_method_' . $role,
918 'value' => $settings[ $role ]['method'],
919 'description' => esc_html__( 'Method to be used when the maximal number of sessions is reached.', 'sessions' ),
920 'full_width' => false,
921 'enabled' => true,
922 ]
923 );
924 register_setting( 'pose_plugin_roles_section', 'pose_plugin_roles_method_' . $role );
925 add_settings_field(
926 'pose_plugin_roles_idle_' . $role,
927 '',
928 [ $form, 'echo_field_select' ],
929 'pose_plugin_roles_section',
930 'pose_plugin_roles_section',
931 [
932 'list' => $idle,
933 'id' => 'pose_plugin_roles_idle_' . $role,
934 'value' => $settings[ $role ]['idle'],
935 'description' => esc_html__( 'Idle sessions supervision.', 'sessions' ),
936 'full_width' => false,
937 'enabled' => true,
938 ]
939 );
940 register_setting( 'pose_plugin_roles_section', 'pose_plugin_roles_idle_' . $role );
941 add_settings_field(
942 'pose_plugin_roles_cookie-ttl_' . $role,
943 '',
944 [ $form, 'echo_field_select' ],
945 'pose_plugin_roles_section',
946 'pose_plugin_roles_section',
947 [
948 'list' => $ttl,
949 'id' => 'pose_plugin_roles_cookie-ttl_' . $role,
950 'value' => $settings[ $role ]['cookie-ttl'],
951 'description' => esc_html__( 'Standard cookie duration.', 'sessions' ),
952 'full_width' => false,
953 'enabled' => true,
954 ]
955 );
956 register_setting( 'pose_plugin_roles_section', 'pose_plugin_roles_cookie-ttl_' . $role );
957 add_settings_field(
958 'pose_plugin_roles_cookie-rttl_' . $role,
959 '',
960 [ $form, 'echo_field_select' ],
961 'pose_plugin_roles_section',
962 'pose_plugin_roles_section',
963 [
964 'list' => $ttl,
965 'id' => 'pose_plugin_roles_cookie-rttl_' . $role,
966 'value' => $settings[ $role ]['cookie-rttl'],
967 'description' => esc_html__( '"Remember Me" cookie duration.', 'sessions' ),
968 'full_width' => false,
969 'enabled' => true,
970 ]
971 );
972 register_setting( 'pose_plugin_roles_section', 'pose_plugin_roles_cookie-rttl_' . $role );
973 }
974 }
975
976 }
977