Plugin Directory

source: sessions/trunk/admin/class-sessions-admin.php

Last change on this file was 3347476, checked in by PierreLannoy, 7 months ago

Sessions 3.2.1 released from GitHub

  • Property svn:executable set to *
File size: 44.1 KB
Line 
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
10namespace POSessions\Plugin;
11
12use POSessions\Plugin\Feature\Analytics;
13use POSessions\Plugin\Feature\AnalyticsFactory;
14use POSessions\System\Assets;
15use POSessions\System\Environment;
16
17use POSessions\System\Role;
18use POSessions\System\Option;
19use POSessions\System\Form;
20use POSessions\System\Blog;
21use POSessions\System\Date;
22use POSessions\System\Timezone;
23use POSessions\System\GeoIP;
24use POSessions\Plugin\Feature\LimiterTypes;
25use PerfOpsOne\Menus;
26use PerfOpsOne\AdminBar;
27use 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 */
36class 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( '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' ) );
361                                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' ) );
362                                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' ) );
363                                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' ) );
364                                $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' );
365                                if ( filter_var( $fallback, FILTER_VALIDATE_URL ) ) {
366                                        Option::network_set( 'fallback', $fallback );
367                                        $message = esc_html__( 'Plugin settings have been saved.', 'sessions' );
368                                        $code    = 0;
369                                        add_settings_error( 'pose_no_error', $code, $message, 'updated' );
370                                        \DecaLog\Engine::eventsLogger( POSE_SLUG )->info( 'Plugin settings updated.', [ 'code' => $code ] );
371                                } else {
372                                        Option::network_set( 'fallback', '' );
373                                        $message = esc_html__( 'Plugin settings have not been fully saved. Please verify the fallback page url.', 'sessions' );
374                                        $code    = 3;
375                                        add_settings_error( 'pose_nonce_error', $code, $message, 'error' );
376                                        \DecaLog\Engine::eventsLogger( POSE_SLUG )->warning( 'Plugin settings not fully updated.', [ 'code' => $code ] );
377                                }
378                        } else {
379                                $message = esc_html__( 'Plugin settings have not been saved. Please try again.', 'sessions' );
380                                $code    = 2;
381                                add_settings_error( 'pose_nonce_error', $code, $message, 'error' );
382                                \DecaLog\Engine::eventsLogger( POSE_SLUG )->warning( 'Plugin settings not updated.', [ 'code' => $code ] );
383                        }
384                }
385        }
386
387        /**
388         * Reset the plugin options.
389         *
390         * @since 1.0.0
391         */
392        private function reset_options() {
393                if ( ! empty( $_POST ) ) {
394                        if ( array_key_exists( '_wpnonce', $_POST ) && wp_verify_nonce( $_POST['_wpnonce'], 'pose-plugin-options' ) ) {
395                                Option::reset_to_defaults();
396                                $message = esc_html__( 'Plugin settings have been reset to defaults.', 'sessions' );
397                                $code    = 0;
398                                add_settings_error( 'pose_no_error', $code, $message, 'updated' );
399                                \DecaLog\Engine::eventsLogger( POSE_SLUG )->info( 'Plugin settings reset to defaults.', [ 'code' => $code ] );
400                        } else {
401                                $message = esc_html__( 'Plugin settings have not been reset to defaults. Please try again.', 'sessions' );
402                                $code    = 2;
403                                add_settings_error( 'pose_nonce_error', $code, $message, 'error' );
404                                \DecaLog\Engine::eventsLogger( POSE_SLUG )->warning( 'Plugin settings not reset to defaults.', [ 'code' => $code ] );
405                        }
406                }
407        }
408
409        /**
410         * Callback for plugin advanced section.
411         *
412         * @since 1.0.0
413         */
414        public function plugin_advanced_section_callback() {
415                $form = new Form();
416                add_settings_field(
417                        'pose_plugin_advanced_buffer_limit',
418                        'List size',
419                        [ $form, 'echo_field_input_integer' ],
420                        'pose_plugin_advanced_section',
421                        'pose_plugin_advanced_section',
422                        [
423                                'id'          => 'pose_plugin_advanced_buffer_limit',
424                                'value'       => Option::network_get( 'buffer_limit' ),
425                                'min'         => 1000,
426                                'max'         => 200000,
427                                'step'        => 1000,
428                                'description' => 'List size, in number of items.',
429                                'full_width'  => false,
430                                'enabled'     => true,
431                        ]
432                );
433                register_setting( 'pose_plugin_advanced_section', 'pose_plugin_advanced_buffer_limit' );
434                add_settings_field(
435                        'pose_plugin_advanced_zk_tsize',
436                        'Zookeeper size',
437                        [ $form, 'echo_field_input_integer' ],
438                        'pose_plugin_advanced_section',
439                        'pose_plugin_advanced_section',
440                        [
441                                'id'          => 'pose_plugin_advanced_zk_tsize',
442                                'value'       => Option::network_get( 'zk_tsize' ),
443                                'min'         => 10,
444                                'max'         => 1000,
445                                'step'        => 10,
446                                'description' => 'Batch size, in number of items.',
447                                'full_width'  => false,
448                                'enabled'     => true,
449                        ]
450                );
451                register_setting( 'pose_plugin_advanced_section', 'pose_plugin_advanced_zk_tsize' );
452                add_settings_field(
453                        'pose_plugin_advanced_zk_semaphore',
454                        'Zookeeper semaphore',
455                        [ $form, 'echo_field_input_integer' ],
456                        'pose_plugin_advanced_section',
457                        'pose_plugin_advanced_section',
458                        [
459                                'id'          => 'pose_plugin_advanced_zk_semaphore',
460                                'value'       => Option::network_get( 'zk_semaphore' ),
461                                'min'         => 300,
462                                'max'         => 1800,
463                                'step'        => 60,
464                                'description' => 'Semaphore auto release, in seconds.',
465                                'full_width'  => false,
466                                'enabled'     => true,
467                        ]
468                );
469                register_setting( 'pose_plugin_advanced_section', 'pose_plugin_advanced_zk_semaphore' );
470                add_settings_field(
471                        'pose_plugin_advanced_zk_cycle',
472                        'Zookeeper cycle',
473                        [ $form, 'echo_field_input_integer' ],
474                        'pose_plugin_advanced_section',
475                        'pose_plugin_advanced_section',
476                        [
477                                'id'          => 'pose_plugin_advanced_zk_cycle',
478                                'value'       => Option::network_get( 'zk_cycle' ),
479                                'min'         => 60,
480                                'max'         => 1800,
481                                'step'        => 30,
482                                'description' => 'Cycle duration, in seconds. Must be less than semaphore value.',
483                                'full_width'  => false,
484                                'enabled'     => true,
485                        ]
486                );
487                register_setting( 'pose_plugin_advanced_section', 'pose_plugin_advanced_zk_cycle' );
488        }
489
490        /**
491         * Callback for plugin options section.
492         *
493         * @since 1.0.0
494         */
495        public function plugin_options_section_callback() {
496                $form = new Form();
497                if ( \DecaLog\Engine::isDecalogActivated() ) {
498                        $help  = '<img style="width:16px;vertical-align:text-bottom;" src="' . \Feather\Icons::get_base64( 'thumbs-up', 'none', '#00C800' ) . '" />&nbsp;';
499                        $help .= sprintf( esc_html__( 'Your site is currently using %s.', 'sessions' ), '<em>' . \DecaLog\Engine::getVersionString() . '</em>' );
500                } else {
501                        $help  = '<img style="width:16px;vertical-align:text-bottom;" src="' . \Feather\Icons::get_base64( 'alert-triangle', 'none', '#FF8C00' ) . '" />&nbsp;';
502                        $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>' );
503                        if ( class_exists( 'PerfOpsOne\Installer' ) && ! Environment::is_wordpress_multisite() ) {
504                                $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>';
505                        }
506                }
507                add_settings_field(
508                        'pose_plugin_options_logger',
509                        esc_html__( 'Logging', 'sessions' ),
510                        [ $form, 'echo_field_simple_text' ],
511                        'pose_plugin_options_section',
512                        'pose_plugin_options_section',
513                        [
514                                'text' => $help,
515                        ]
516                );
517                register_setting( 'pose_plugin_options_section', 'pose_plugin_options_logger' );
518                if ( class_exists( 'PODeviceDetector\API\Device' ) ) {
519                        $help  = '<img style="width:16px;vertical-align:text-bottom;" src="' . \Feather\Icons::get_base64( 'thumbs-up', 'none', '#00C800' ) . '" />&nbsp;';
520                        $help .= sprintf( esc_html__( 'Your site is currently using %s.', 'sessions' ), '<em>Device Detector v' . PODD_VERSION . '</em>' );
521                } else {
522                        $help  = '<img style="width:16px;vertical-align:text-bottom;" src="' . \Feather\Icons::get_base64( 'alert-triangle', 'none', '#FF8C00' ) . '" />&nbsp;';
523                        $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>' );
524                        if ( class_exists( 'PerfOpsOne\Installer' ) && ! Environment::is_wordpress_multisite() ) {
525                                $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>';
526                        }
527                }
528                add_settings_field(
529                        'pose_plugin_options_podd',
530                        __( 'Device detection', 'sessions' ),
531                        [ $form, 'echo_field_simple_text' ],
532                        'pose_plugin_options_section',
533                        'pose_plugin_options_section',
534                        [
535                                'text' => $help,
536                        ]
537                );
538                register_setting( 'pose_plugin_options_section', 'pose_plugin_options_podd' );
539                $geo_ip = new GeoIP();
540                if ( $geo_ip->is_installed() ) {
541                        $help  = '<img style="width:16px;vertical-align:text-bottom;" src="' . \Feather\Icons::get_base64( 'thumbs-up', 'none', '#00C800' ) . '" />&nbsp;';
542                        $help .= sprintf( esc_html__( 'Your site is currently using %s.', 'sessions' ), '<em>' . $geo_ip->get_full_name() . '</em>' );
543                } else {
544                        $help  = '<img style="width:16px;vertical-align:text-bottom;" src="' . \Feather\Icons::get_base64( 'alert-triangle', 'none', '#FF8C00' ) . '" />&nbsp;';
545                        $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>' );
546                        if ( class_exists( 'PerfOpsOne\Installer' ) && ! Environment::is_wordpress_multisite() ) {
547                                $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>';
548                        }
549                }
550                add_settings_field(
551                        'pose_plugin_options_geoip',
552                        __( 'IP information', 'sessions' ),
553                        [ $form, 'echo_field_simple_text' ],
554                        'pose_plugin_options_section',
555                        'pose_plugin_options_section',
556                        [
557                                'text' => $help,
558                        ]
559                );
560                register_setting( 'pose_plugin_options_section', 'pose_plugin_options_geoip' );
561                add_settings_field(
562                        'pose_plugin_options_usecdn',
563                        esc_html__( 'Resources', 'sessions' ),
564                        [ $form, 'echo_field_checkbox' ],
565                        'pose_plugin_options_section',
566                        'pose_plugin_options_section',
567                        [
568                                'text'        => esc_html__( 'Use public CDN', 'sessions' ),
569                                'id'          => 'pose_plugin_options_usecdn',
570                                'checked'     => Option::network_get( 'use_cdn' ),
571                                'description' => esc_html__( 'If checked, Sessions will use a public CDN (jsDelivr) to serve scripts and stylesheets.', 'sessions' ),
572                                'full_width'  => false,
573                                'enabled'     => true,
574                        ]
575                );
576                register_setting( 'pose_plugin_options_section', 'pose_plugin_options_usecdn' );
577                add_settings_field(
578                        'pose_plugin_options_nag',
579                        esc_html__( 'Admin notices', 'sessions' ),
580                        [ $form, 'echo_field_checkbox' ],
581                        'pose_plugin_options_section',
582                        'pose_plugin_options_section',
583                        [
584                                'text'        => esc_html__( 'Display', 'sessions' ),
585                                'id'          => 'pose_plugin_options_nag',
586                                'checked'     => Option::network_get( 'display_nag' ),
587                                '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' ),
588                                'full_width'  => false,
589                                'enabled'     => true,
590                        ]
591                );
592                register_setting( 'pose_plugin_options_section', 'pose_plugin_options_nag' );
593        }
594
595        /**
596         * Get the available history retentions.
597         *
598         * @return array An array containing the history modes.
599         * @since  1.0.0
600         */
601        protected function get_retentions_array() {
602                $result = [];
603                for ( $i = 1; $i < 7; $i++ ) {
604                        // phpcs:ignore
605                        $result[] = [ (int) ( 30 * $i ), esc_html( sprintf( _n( '%d month', '%d months', $i, 'sessions' ), $i ) ) ];
606                }
607                for ( $i = 1; $i < 7; $i++ ) {
608                        // phpcs:ignore
609                        $result[] = [ (int) ( 365 * $i ), esc_html( sprintf( _n( '%d year', '%d years', $i, 'sessions' ), $i ) ) ];
610                }
611                return $result;
612        }
613
614        /**
615         * Callback for plugin messages section.
616         *
617         * @since 2.3.0
618         */
619        public function plugin_messages_section_callback() {
620                $form = new Form();
621                add_settings_field(
622                        'pose_plugin_messages_fallback',
623                        esc_html__( 'Fallback page', 'sessions' ),
624                        [ $form, 'echo_field_input_text' ],
625                        'pose_plugin_messages_section',
626                        'pose_plugin_messages_section',
627                        [
628                                'id'          => 'pose_plugin_messages_fallback',
629                                'value'       => Option::network_get( 'fallback' ),
630                                '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' ),
631                                'full_width'  => false,
632                                'placeholder' => '',
633                                'enabled'     => true,
634                        ]
635                );
636                register_setting( 'pose_plugin_messages_section', 'pose_plugin_messages_fallback' );
637                add_settings_field(
638                        'pose_plugin_messages_blocked_message',
639                        esc_html__( 'Session not allowed', 'sessions' ),
640                        [ $form, 'echo_field_input_text' ],
641                        'pose_plugin_messages_section',
642                        'pose_plugin_messages_section',
643                        [
644                                'id'          => 'pose_plugin_messages_blocked_message',
645                                'value'       => Option::network_get( 'blocked_message' ),
646                                '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' ) ),
647                                'full_width'  => false,
648                                'placeholder' => '',
649                                'enabled'     => true,
650                        ]
651                );
652                register_setting( 'pose_plugin_messages_section', 'pose_plugin_messages_blocked_message' );
653                add_settings_field(
654                        'pose_plugin_messages_bad_ip_message',
655                        esc_html__( 'IP not allowed', 'sessions' ),
656                        [ $form, 'echo_field_input_text' ],
657                        'pose_plugin_messages_section',
658                        'pose_plugin_messages_section',
659                        [
660                                'id'          => 'pose_plugin_messages_bad_ip_message',
661                                'value'       => Option::network_get( 'bad_ip_message' ),
662                                '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' ) ),
663                                'full_width'  => false,
664                                'placeholder' => '',
665                                'enabled'     => true,
666                        ]
667                );
668                register_setting( 'pose_plugin_messages_section', 'pose_plugin_messages_bad_ip_message' );
669        }
670
671        /**
672         * Callback for plugin features section.
673         *
674         * @since 1.0.0
675         */
676        public function plugin_features_section_callback() {
677                $form   = new Form();
678                $mode   = [];
679                $mode[] = [ -1, esc_html__( 'Disabled - Don\'t limit sessions by roles', 'sessions' ) ];
680                $mode[] = [ 0, esc_html__( 'Enabled - Cumulative privileges', 'sessions' ) ];
681                $mode[] = [ 1, esc_html__( 'Enabled - Least privileges', 'sessions' ) ];
682                add_settings_field(
683                        'pose_plugin_features_rolemode',
684                        esc_html__( 'Settings by roles', 'sessions' ),
685                        [ $form, 'echo_field_select' ],
686                        'pose_plugin_features_section',
687                        'pose_plugin_features_section',
688                        [
689                                'list'        => $mode,
690                                'id'          => 'pose_plugin_features_rolemode',
691                                'value'       => Option::network_get( 'rolemode' ),
692                                '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>',
693                                'full_width'  => false,
694                                'enabled'     => true,
695                        ]
696                );
697                register_setting( 'pose_plugin_features_section', 'pose_plugin_features_rolemode' );
698                add_settings_field(
699                        'pose_plugin_features_forceip',
700                        esc_html__( 'IP detection', 'sessions' ),
701                        [ $form, 'echo_field_checkbox' ],
702                        'pose_plugin_features_section',
703                        'pose_plugin_features_section',
704                        [
705                                'text'        => esc_html__( 'Override WordPress', 'sessions' ),
706                                'id'          => 'pose_plugin_features_forceip',
707                                'checked'     => Option::network_get( 'forceip' ),
708                                'description' => esc_html__( 'If checked, Sessions will improve IP detection used for tokens (recommended).', 'sessions' ),
709                                'full_width'  => false,
710                                'enabled'     => true,
711                        ]
712                );
713                register_setting( 'pose_plugin_features_section', 'pose_plugin_features_forceip' );
714                add_settings_field(
715                        'pose_plugin_features_followip',
716                        esc_html__( 'IP follow-up', 'sessions' ),
717                        [ $form, 'echo_field_checkbox' ],
718                        'pose_plugin_features_section',
719                        'pose_plugin_features_section',
720                        [
721                                'text'        => esc_html__( 'Activated', 'sessions' ),
722                                'id'          => 'pose_plugin_features_followip',
723                                'checked'     => Option::network_get( 'followip' ),
724                                'description' => esc_html__( 'If checked, Sessions will refresh IPs when a session is resumed (recommended).', 'sessions' ),
725                                'full_width'  => false,
726                                'enabled'     => true,
727                        ]
728                );
729                register_setting( 'pose_plugin_features_section', 'pose_plugin_features_followip' );
730                add_settings_field(
731                        'pose_plugin_features_killonreset',
732                        esc_html__( 'On password reset', 'sessions' ),
733                        [ $form, 'echo_field_checkbox' ],
734                        'pose_plugin_features_section',
735                        'pose_plugin_features_section',
736                        [
737                                'text'        => esc_html__( 'Delete current sessions', 'sessions' ),
738                                'id'          => 'pose_plugin_features_killonreset',
739                                'checked'     => Option::network_get( 'killonreset' ),
740                                'description' => esc_html__( 'If checked, Sessions will delete all sessions of users resetting their passwords (recommended).', 'sessions' ),
741                                'full_width'  => false,
742                                'enabled'     => true,
743                        ]
744                );
745                register_setting( 'pose_plugin_features_section', 'pose_plugin_features_killonreset' );
746                add_settings_field(
747                        'pose_plugin_features_analytics',
748                        esc_html__( 'Analytics', 'sessions' ),
749                        [ $form, 'echo_field_checkbox' ],
750                        'pose_plugin_features_section',
751                        'pose_plugin_features_section',
752                        [
753                                'text'        => esc_html__( 'Activated', 'sessions' ),
754                                'id'          => 'pose_plugin_features_analytics',
755                                'checked'     => Option::network_get( 'analytics' ),
756                                'description' => esc_html__( 'If checked, Sessions will store statistics about accounts and sessions.', 'sessions' ),
757                                'full_width'  => false,
758                                'enabled'     => true,
759                        ]
760                );
761                register_setting( 'pose_plugin_features_section', 'pose_plugin_features_analytics' );
762                add_settings_field(
763                        'pose_plugin_features_history',
764                        esc_html__( 'Historical data', 'sessions' ),
765                        [ $form, 'echo_field_select' ],
766                        'pose_plugin_features_section',
767                        'pose_plugin_features_section',
768                        [
769                                'list'        => $this->get_retentions_array(),
770                                'id'          => 'pose_plugin_features_history',
771                                'value'       => Option::network_get( 'history' ),
772                                'description' => esc_html__( 'Maximum age of data to keep for statistics.', 'sessions' ),
773                                'full_width'  => false,
774                                'enabled'     => true,
775                        ]
776                );
777                register_setting( 'pose_plugin_features_section', 'pose_plugin_features_history' );
778                add_settings_field(
779                        'pose_plugin_features_metrics',
780                        esc_html__( 'Metrics', 'sessions' ),
781                        [ $form, 'echo_field_checkbox' ],
782                        'pose_plugin_features_section',
783                        'pose_plugin_features_section',
784                        [
785                                'text'        => esc_html__( 'Activated', 'sessions' ),
786                                'id'          => 'pose_plugin_features_metrics',
787                                'checked'     => \DecaLog\Engine::isDecalogActivated() ? Option::network_get( 'metrics' ) : false,
788                                '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' ) ),
789                                'full_width'  => false,
790                                'enabled'     => \DecaLog\Engine::isDecalogActivated(),
791                        ]
792                );
793                register_setting( 'pose_plugin_features_section', 'pose_plugin_features_metrics' );
794        }
795
796        /**
797         * Get the available history retentions.
798         *
799         * @return array An array containing the history modes.
800         * @since  1.0.0
801         */
802        protected function get_session_count_array() {
803                $result   = [];
804                $result[] = [ 'none', esc_html__( 'No limit', 'sessions' ) ];
805                foreach ( LimiterTypes::$selector_names as $key => $name ) {
806                        for ( $i = 1; $i <= 9; $i++ ) {
807                                if ( '' === $name ) {
808                                        $result[] = [ $key . '-' . $i, esc_html( sprintf( _n( '%d session per user', '%d sessions per user', $i, 'sessions' ), $i ) ), LimiterTypes::is_selector_available( $key ) ];
809                                } else {
810                                        // phpcs:ignore
811                                        $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 ) ];
812                                }
813                        }
814                }
815                return $result;
816        }
817
818        /**
819         * Callback for plugin roles modification section.
820         *
821         * @since 1.0.0
822         */
823        public function plugin_roles_section_callback() {
824                $settings  = Option::roles_get();
825                $blocks    = [];
826                $blocks[]  = [ 'none', esc_html__( 'Allow from everywhere', 'sessions' ) ];
827                $blocks[]  = [ 'external', esc_html__( 'Allow only from private IP ranges', 'sessions' ) ];
828                $blocks[]  = [ 'local', esc_html__( 'Allow only from public IP ranges', 'sessions' ) ];
829                $methods   = [];
830                $methods[] = [ 'override', esc_html__( 'Override oldest session', 'sessions' ) ];
831                /* translators: please, do not translate the strings [HTTP 403 / Forbidden] and [HTTP 303 / See Other] as they are a standard HTTP headers. */
832                $methods[] = [ 'block', esc_html__( 'Block and send a "HTTP 403 / Forbidden" error', 'sessions' ) ];
833                $methods[] = [ 'redirect', esc_html__( 'Block and redirect to the fallback page with a "HTTP 303 / See Other" code', 'sessions' ) ];
834                $methods[] = [ 'default', esc_html__( 'Block and send a WordPress error', 'sessions' ) ];
835                $idle      = [];
836                $idle[]    = [ 0, esc_html__( 'Never terminate an idle session', 'sessions' ) ];
837                foreach ( [ 115, 130, 145 ]  as $m ) {
838                        // phpcs:ignore
839                        $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 ) ) ];
840                }
841                foreach ( [ 1, 2, 3, 4, 5, 6, 12, 18, 24, 36, 48, 72 ]  as $h ) {
842                        // phpcs:ignore
843                        $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 ) ) ];
844                }
845                $maxip   = [];
846                $maxip[] = [ 0, esc_html__( 'Unlimited', 'sessions' ) ];
847                foreach ( [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ]  as $h ) {
848                        // phpcs:ignore
849                        $maxip[] = [ $h, esc_html( sprintf( _n( '%d IP address', '%d IP addresses', $h, 'sessions' ), $h ) ) ];
850                }
851                $ttl = [];
852                foreach ( [ 1, 2, 3, 4, 5, 6 ]  as $h ) {
853                        // phpcs:ignore
854                        $ttl[] = [ 24 * $h, esc_html( sprintf( _n( '%d day', '%d days', $h, 'sessions' ), $h ) ) ];
855                }
856                foreach ( [ 1, 2, 3, 4 ]  as $h ) {
857                        // phpcs:ignore
858                        $ttl[] = [ 24 * 7 * $h, esc_html( sprintf( _n( '%d week', '%d weeks', $h, 'sessions' ), $h ) ) ];
859                }
860                foreach ( [ 1, 2, 3, 4, 5, 6 ]  as $h ) {
861                        // phpcs:ignore
862                        $ttl[] = [ 24 * 30 * $h, esc_html( sprintf( _n( '%d month', '%d months', $h, 'sessions' ), $h ) ) ];
863                }
864                foreach ( [ 1, 2, 3 ]  as $h ) {
865                        // phpcs:ignore
866                        $ttl[] = [ 24 * 365 * $h, esc_html( sprintf( _n( '%d year', '%d years', $h, 'sessions' ), $h ) ) ];
867                }
868                $form = new Form();
869                foreach ( Role::get_all() as $role => $detail ) {
870                        add_settings_field(
871                                'pose_plugin_roles_block_' . $role,
872                                $detail['l10n_name'],
873                                [ $form, 'echo_field_select' ],
874                                'pose_plugin_roles_section',
875                                'pose_plugin_roles_section',
876                                [
877                                        'list'        => $blocks,
878                                        'id'          => 'pose_plugin_roles_block_' . $role,
879                                        'value'       => $settings[ $role ]['block'],
880                                        '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' ),
881                                        'full_width'  => false,
882                                        'enabled'     => true,
883                                ]
884                        );
885                        register_setting( 'pose_plugin_roles_section', 'pose_plugin_roles_block_' . $role );
886                        add_settings_field(
887                                'pose_plugin_roles_maxip_' . $role,
888                                '',
889                                [ $form, 'echo_field_select' ],
890                                'pose_plugin_roles_section',
891                                'pose_plugin_roles_section',
892                                [
893                                        'list'        => $maxip,
894                                        'id'          => 'pose_plugin_roles_maxip_' . $role,
895                                        'value'       => $settings[ $role ]['maxip'],
896                                        'description' => esc_html__( 'Maximal number of IP per user. Requires IP follow-up to be activated - see "Options" tab.', 'sessions' ),
897                                        'full_width'  => false,
898                                        'enabled'     => true,
899                                ]
900                        );
901                        register_setting( 'pose_plugin_roles_section', 'pose_plugin_roles_maxip_' . $role );
902                        add_settings_field(
903                                'pose_plugin_roles_limit_' . $role,
904                                '',
905                                [ $form, 'echo_field_select' ],
906                                'pose_plugin_roles_section',
907                                'pose_plugin_roles_section',
908                                [
909                                        'list'        => $this->get_session_count_array(),
910                                        'id'          => 'pose_plugin_roles_limit_' . $role,
911                                        'value'       => $settings[ $role ]['limit'],
912                                        'description' => esc_html__( 'Maximal number of sessions for users.', 'sessions' ),
913                                        'full_width'  => false,
914                                        'enabled'     => true,
915                                ]
916                        );
917                        register_setting( 'pose_plugin_roles_section', 'pose_plugin_roles_limit_' . $role );
918                        add_settings_field(
919                                'pose_plugin_roles_method_' . $role,
920                                '',
921                                [ $form, 'echo_field_select' ],
922                                'pose_plugin_roles_section',
923                                'pose_plugin_roles_section',
924                                [
925                                        'list'        => $methods,
926                                        'id'          => 'pose_plugin_roles_method_' . $role,
927                                        'value'       => $settings[ $role ]['method'],
928                                        'description' => esc_html__( 'Method to be used when the maximal number of sessions is reached.', 'sessions' ),
929                                        'full_width'  => false,
930                                        'enabled'     => true,
931                                ]
932                        );
933                        register_setting( 'pose_plugin_roles_section', 'pose_plugin_roles_method_' . $role );
934                        add_settings_field(
935                                'pose_plugin_roles_idle_' . $role,
936                                '',
937                                [ $form, 'echo_field_select' ],
938                                'pose_plugin_roles_section',
939                                'pose_plugin_roles_section',
940                                [
941                                        'list'        => $idle,
942                                        'id'          => 'pose_plugin_roles_idle_' . $role,
943                                        'value'       => $settings[ $role ]['idle'],
944                                        'description' => esc_html__( 'Idle sessions supervision.', 'sessions' ),
945                                        'full_width'  => false,
946                                        'enabled'     => true,
947                                ]
948                        );
949                        register_setting( 'pose_plugin_roles_section', 'pose_plugin_roles_idle_' . $role );
950                        add_settings_field(
951                                'pose_plugin_roles_cookie-ttl_' . $role,
952                                '',
953                                [ $form, 'echo_field_select' ],
954                                'pose_plugin_roles_section',
955                                'pose_plugin_roles_section',
956                                [
957                                        'list'        => $ttl,
958                                        'id'          => 'pose_plugin_roles_cookie-ttl_' . $role,
959                                        'value'       => $settings[ $role ]['cookie-ttl'],
960                                        'description' => esc_html__( 'Standard cookie duration.', 'sessions' ),
961                                        'full_width'  => false,
962                                        'enabled'     => true,
963                                ]
964                        );
965                        register_setting( 'pose_plugin_roles_section', 'pose_plugin_roles_cookie-ttl_' . $role );
966                        add_settings_field(
967                                'pose_plugin_roles_cookie-rttl_' . $role,
968                                '',
969                                [ $form, 'echo_field_select' ],
970                                'pose_plugin_roles_section',
971                                'pose_plugin_roles_section',
972                                [
973                                        'list'        => $ttl,
974                                        'id'          => 'pose_plugin_roles_cookie-rttl_' . $role,
975                                        'value'       => $settings[ $role ]['cookie-rttl'],
976                                        'description' => esc_html__( '"Remember Me" cookie duration.', 'sessions' ),
977                                        'full_width'  => false,
978                                        'enabled'     => true,
979                                ]
980                        );
981                        register_setting( 'pose_plugin_roles_section', 'pose_plugin_roles_cookie-rttl_' . $role );
982                }
983        }
984
985}
Note: See TracBrowser for help on using the repository browser.