Changeset 3753699 for yuracode-security/trunk/src/Admin/SettingsPage.php
- Timestamp:
- 10/18/2026 11:12:11 PM (10 hours ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
yuracode-security/trunk/src/Admin/SettingsPage.php
r3714465 r3753699 10 10 const OPTION_GROUP = 'yuracode-security_settings_group'; 11 11 const PAGE = 'yuracode-security'; 12 13 // Placeholder tab on subsites of a multisite network: the firewall is 14 // network-managed, so its real sections collapse into this read-only one. 15 const NETWORK_FIREWALL_SECTION = 'yuracode-security_network_firewall'; 12 16 13 17 public static function init() { … … 62 66 $defaults = Plugin::defaults(); 63 67 $input = is_array($input) ? $input : array(); 68 $manages_file = HtaccessManager::current_site_manages_file(); 64 69 $out = array(); 65 70 66 71 foreach (Schema::fields() as $field) { 67 72 list($section, $key, $label, $type, $args) = $field; 73 74 // The firewall is network-managed on multisite: subsites don't 75 // render its fields, so its keys are dropped here, exactly like 76 // Pro keys after a license lapse. 77 if (!$manages_file && self::is_firewall_section($section)) { 78 continue; 79 } 68 80 69 81 $path = explode('.', $args['path']); … … 92 104 93 105 public static function htaccess_notice() { 94 if (!self::on_settings_page() ) {106 if (!self::on_settings_page() || !HtaccessManager::current_site_manages_file()) { 95 107 return; 96 108 } … … 112 124 113 125 public static function htaccess_server_notice() { 114 if (!self::on_settings_page() ) {126 if (!self::on_settings_page() || !HtaccessManager::current_site_manages_file()) { 115 127 return; 116 128 } … … 147 159 */ 148 160 public static function rewrite_block_notice() { 149 if (!self::on_settings_page() || !current_user_can('manage_options')) { 161 if ( 162 !self::on_settings_page() 163 || !current_user_can('manage_options') 164 || !HtaccessManager::current_site_manages_file() 165 ) { 150 166 return; 151 167 } … … 175 191 // Direct links to a tab (?ycs_tab=<id>) only activate known schema 176 192 // sections or extra tabs; anything else falls back to the first tab. 177 $known_tabs = array_merge(array_keys( Schema::sections()), array_keys($extra_tabs));193 $known_tabs = array_merge(array_keys(self::visible_sections()), array_keys($extra_tabs)); 178 194 179 195 if (!in_array($active_tab, $known_tabs, true)) { … … 211 227 $first = true; 212 228 213 foreach ( Schema::sections() as $id => $section): ?>229 foreach (self::visible_sections() as $id => $section): ?> 214 230 <button 215 231 type="button" … … 248 264 $first = true; 249 265 250 foreach ( Schema::sections() as $id => $section): ?>266 foreach (self::visible_sections() as $id => $section): ?> 251 267 <div 252 268 id="panel-<?php echo esc_attr($id); ?>" … … 263 279 </div> 264 280 <div class="ycs-fields"> 265 <?php FieldRenderer::render_fields($id); ?> 281 <?php 282 283 if (self::NETWORK_FIREWALL_SECTION === $id) { 284 echo 285 '<p class="description">' 286 . esc_html__( 287 'The firewall rules live in the one .htaccess file in the WordPress root that every site on this network shares, so they are configured on the main site. Open Settings > YuraCode Security there. The hardening and login-protection settings on this page apply to this site only.', 288 'yuracode-security', 289 ) 290 . '</p>'; 291 } else { 292 FieldRenderer::render_fields($id); 293 } 294 ?> 266 295 </div> 267 296 </div> … … 295 324 } 296 325 326 private static function visible_sections() { 327 return self::sections_for_context(Schema::sections(), HtaccessManager::current_site_manages_file()); 328 } 329 330 /** 331 * Sections as the current context shows them; pure, so the multisite 332 * branch stays testable on a single-site install. 333 * 334 * On a subsite of a multisite network the firewall sections collapse 335 * into a single read-only tab: the rules live in the one .htaccess the 336 * network shares and are managed on the main site. 337 * 338 * @param array $sections Schema sections, id => section. 339 * @param bool $site_manages Whether the current site writes the .htaccess. 340 */ 341 public static function sections_for_context($sections, $site_manages) { 342 if ($site_manages) { 343 return $sections; 344 } 345 346 $out = array(); 347 348 foreach ((array) $sections as $id => $section) { 349 if (self::is_firewall_section($id)) { 350 continue; 351 } 352 353 $out[$id] = $section; 354 } 355 356 $out[self::NETWORK_FIREWALL_SECTION] = array( 357 'title' => __('Firewall', 'yuracode-security'), 358 'desc' => __( 359 'The firewall protects the entire network and is managed on the main site.', 360 'yuracode-security', 361 ), 362 ); 363 364 return $out; 365 } 366 367 /** 368 * Whether a schema section belongs to the network-managed firewall. 369 * 370 * Add-ons registering firewall sections reuse the `yuracode-security_firewall*` 371 * prefix, so they collapse on subsites too. 372 */ 373 private static function is_firewall_section($id) { 374 return str_starts_with((string) $id, 'yuracode-security_firewall'); 375 } 376 297 377 private static function schema_tab_active($id, $active_tab, $first) { 298 378 // No tab selected (or an unknown/extra tab): the first schema tab wins.
Note:
See TracChangeset
for help on using the changeset viewer.
![(please configure the [header_logo] section in trac.ini)](/chrome/site/your_project_logo.png)