http
2 weeks ago
integrations
2 weeks ago
mfa
2 weeks ago
mfa-flow
2 weeks ago
AdminNoticesController.php
2 weeks ago
Ajax.php
2 weeks ago
CloudApp.php
2 weeks ago
Config.php
2 weeks ago
Helpers.php
2 weeks ago
LimitLoginAttempts.php
2 weeks ago
LoginFlowTransientStore.php
2 weeks ago
MfaConstants.php
2 weeks ago
Shortcodes.php
2 weeks ago
AdminNoticesController.php
169 lines
| 1 | <?php |
| 2 | |
| 3 | namespace LLAR\Core; |
| 4 | |
| 5 | if ( ! defined( 'ABSPATH' ) ) { |
| 6 | exit; |
| 7 | } |
| 8 | |
| 9 | /** |
| 10 | * Renders admin notices for the LLAR options page. |
| 11 | * All notices use a single view; content is built from config per notice key. |
| 12 | */ |
| 13 | class AdminNoticesController { |
| 14 | |
| 15 | /** |
| 16 | * Allowed notice keys. |
| 17 | * |
| 18 | * @var array |
| 19 | */ |
| 20 | private static $allowed = array( 'auto-update', 'https-recommended', 'https-recommended-mfa', 'debug-foreign-auth-hooks', 'flash', 'mfa-recovery-links-expired' ); |
| 21 | |
| 22 | /** |
| 23 | * Get type, CSS class and HTML content for a notice key. |
| 24 | * |
| 25 | * @param string $notice_key Notice identifier. |
| 26 | * @param array $args Optional. For 'flash' key: 'msg', 'is_error'. |
| 27 | * @return array|null Array with 'type', 'class', 'content' or null if unknown. |
| 28 | */ |
| 29 | private function get_notice_config( $notice_key, array $args = array() ) { |
| 30 | $text_domain = 'limit-login-attempts-reloaded'; |
| 31 | switch ( $notice_key ) { |
| 32 | case 'auto-update': |
| 33 | $content = \__( 'Do you want Limit Login Attempts Reloaded to provide the latest version automatically?', $text_domain ); |
| 34 | $content .= ' <a href="#" class="auto-enable-update-option" data-val="yes">'; |
| 35 | $content .= \__( 'Yes, enable auto-update', $text_domain ) . '</a> | '; |
| 36 | $content .= '<a href="#" class="auto-enable-update-option" data-val="no">'; |
| 37 | $content .= \__( 'No thanks', $text_domain ) . '</a>'; |
| 38 | return array( |
| 39 | 'type' => 'notice-error', |
| 40 | 'class' => 'llar-options-notice llar-auto-update-notice', |
| 41 | 'content' => $content, |
| 42 | ); |
| 43 | case 'https-recommended': |
| 44 | return array( |
| 45 | 'type' => 'notice-warning', |
| 46 | 'class' => 'llar-options-notice', |
| 47 | 'content' => \__( 'Your site is not using HTTPS. Enabling HTTPS is recommended for better security.', $text_domain ), |
| 48 | ); |
| 49 | case 'https-recommended-mfa': |
| 50 | return array( |
| 51 | 'type' => 'notice-warning', |
| 52 | 'class' => 'llar-options-notice', |
| 53 | 'content' => \__( 'Before enabling 2FA/MFA, we strongly recommend ensuring your website is accessible only via HTTPS.', $text_domain ), |
| 54 | ); |
| 55 | case 'debug-foreign-auth-hooks': |
| 56 | $hooks = isset( $args['hooks'] ) && is_array( $args['hooks'] ) ? $args['hooks'] : array(); |
| 57 | if ( empty( $hooks ) ) { |
| 58 | return null; |
| 59 | } |
| 60 | |
| 61 | $content = \__( 'These plugins register additional callbacks on the authenticate filter and may affect LLAR login protection.', $text_domain ); |
| 62 | $grouped_hooks = array(); |
| 63 | foreach ( $hooks as $hook ) { |
| 64 | $plugin_slug = 'unknown'; |
| 65 | $plugin_label = 'Unknown plugin'; |
| 66 | $plugin_details_url = ''; |
| 67 | |
| 68 | if ( ! empty( $hook['plugin'] ) && is_array( $hook['plugin'] ) ) { |
| 69 | $plugin_name = isset( $hook['plugin']['name'] ) ? (string) $hook['plugin']['name'] : ''; |
| 70 | $plugin_slug_raw = isset( $hook['plugin']['slug'] ) ? (string) $hook['plugin']['slug'] : ''; |
| 71 | $plugin_slug = '' !== $plugin_slug_raw ? \sanitize_key( $plugin_slug_raw ) : 'unknown'; |
| 72 | $plugin_version = isset( $hook['plugin']['version'] ) ? (string) $hook['plugin']['version'] : ''; |
| 73 | |
| 74 | if ( '' !== $plugin_name ) { |
| 75 | $plugin_label = $plugin_name; |
| 76 | if ( '' !== $plugin_version ) { |
| 77 | $plugin_label .= ' v' . $plugin_version; |
| 78 | } |
| 79 | } elseif ( 'unknown' !== $plugin_slug ) { |
| 80 | $plugin_label = $plugin_slug; |
| 81 | } |
| 82 | |
| 83 | if ( 'unknown' !== $plugin_slug ) { |
| 84 | $plugin_details_url = \admin_url( |
| 85 | 'plugin-install.php?tab=plugin-information&plugin=' . rawurlencode( $plugin_slug ) . '&TB_iframe=true&width=600&height=550' |
| 86 | ); |
| 87 | } |
| 88 | } |
| 89 | |
| 90 | if ( ! isset( $grouped_hooks[ $plugin_slug ] ) ) { |
| 91 | $grouped_hooks[ $plugin_slug ] = array( |
| 92 | 'label' => $plugin_label, |
| 93 | 'url' => $plugin_details_url, |
| 94 | ); |
| 95 | } |
| 96 | } |
| 97 | |
| 98 | $content .= '<br /><ul style="margin-left: 18px; list-style: disc;">'; |
| 99 | foreach ( $grouped_hooks as $plugin_group ) { |
| 100 | $content .= '<li><strong>' . \esc_html( $plugin_group['label'] ) . '</strong>'; |
| 101 | if ( '' !== $plugin_group['url'] ) { |
| 102 | $content .= ' - <a href="' . \esc_url( $plugin_group['url'] ) . '" class="thickbox open-plugin-details-modal" target="_blank" rel="noopener noreferrer">' |
| 103 | . \esc_html__( 'View details', $text_domain ) . '</a>'; |
| 104 | } |
| 105 | $content .= '</li>'; |
| 106 | } |
| 107 | $content .= '</ul>'; |
| 108 | |
| 109 | return array( |
| 110 | 'type' => 'notice-warning', |
| 111 | 'class' => 'llar-options-notice', |
| 112 | 'content' => $content, |
| 113 | ); |
| 114 | case 'flash': |
| 115 | $msg = isset( $args['msg'] ) ? $args['msg'] : ''; |
| 116 | $is_error = ! empty( $args['is_error'] ); |
| 117 | if ( $msg === '' ) { |
| 118 | return null; |
| 119 | } |
| 120 | return array( |
| 121 | 'type' => $is_error ? 'notice-error' : 'notice-success', |
| 122 | 'class' => 'llar-options-notice llar-flash-notice', |
| 123 | 'content' => $msg, |
| 124 | ); |
| 125 | case 'mfa-recovery-links-expired': |
| 126 | $mfa_url = isset( $args['mfa_url'] ) ? (string) $args['mfa_url'] : ''; |
| 127 | if ( '' === $mfa_url ) { |
| 128 | return null; |
| 129 | } |
| 130 | return array( |
| 131 | 'type' => 'notice-error', |
| 132 | 'class' => 'llar-options-notice llar-mfa-recovery-links-expired', |
| 133 | 'content' => sprintf( |
| 134 | __( '⚠️ Action required: Your existing 2FA recovery links are no longer valid. On the <a href="%s">2FA settings page</a>, turn 2FA off and then back on, then follow the prompts to download the new recovery links.', 'limit-login-attempts-reloaded' ), |
| 135 | \esc_url( $mfa_url ) |
| 136 | ), |
| 137 | ); |
| 138 | default: |
| 139 | return null; |
| 140 | } |
| 141 | } |
| 142 | |
| 143 | /** |
| 144 | * Render a notice by key. |
| 145 | * |
| 146 | * @param string $notice_key Notice identifier (e.g. 'auto-update', 'https-recommended'). |
| 147 | * @param array $args Optional. Unused; reserved for future use. |
| 148 | * @return void |
| 149 | */ |
| 150 | public function render( $notice_key, array $args = array() ) { |
| 151 | $notice_key = \sanitize_key( $notice_key ); |
| 152 | if ( ! in_array( $notice_key, self::$allowed, true ) ) { |
| 153 | return; |
| 154 | } |
| 155 | $config = $this->get_notice_config( $notice_key, $args ); |
| 156 | if ( null === $config ) { |
| 157 | return; |
| 158 | } |
| 159 | $path = LLA_PLUGIN_DIR . 'views/notices.php'; |
| 160 | if ( ! is_readable( $path ) ) { |
| 161 | return; |
| 162 | } |
| 163 | $notice_type = $config['type']; |
| 164 | $notice_class = $config['class']; |
| 165 | $notice_content = $config['content']; |
| 166 | include $path; |
| 167 | } |
| 168 | } |
| 169 |