-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 792a9a9
Showing
4 changed files
with
493 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
<?php | ||
/** | ||
* Plugin Name: 404 Fallback | ||
* Plugin URI: PLUGIN SITE HERE | ||
* Description: PLUGIN DESCRIPTION HERE | ||
* Author: YOUR NAME HERE | ||
* Author URI: YOUR SITE HERE | ||
* Text Domain: 404-fallback | ||
* Domain Path: /languages | ||
* Version: 0.1.0 | ||
* | ||
* @package 404_Fallback | ||
*/ | ||
|
||
require_once plugin_dir_path( __FILE__ ) . '/lib/menus.php'; | ||
require_once plugin_dir_path( __FILE__ ) . '/lib/menu-site.php'; | ||
|
||
function fb404_redirect_404() { | ||
global $wp; | ||
|
||
$request = wp_unslash( $_SERVER['REQUEST_URI'] ); | ||
$url = stripslashes( get_option( 'fb404_setting_fallback_url' )); | ||
if ( is_404() && !empty($url) ) { | ||
$location = $url . $request; | ||
$status = 302; | ||
$x_redirect_by = '404 Fallback'; | ||
wp_redirect( $location, $status, $x_redirect_by ); | ||
die(); | ||
} | ||
} | ||
|
||
add_action( 'template_redirect', 'fb404_redirect_404' ); | ||
|
||
/** | ||
* Add a site menu called Cluster | ||
*/ | ||
function fb404_add_settings_menu() { | ||
wpc_menu_register_page( [ | ||
'id' => 'fb404', | ||
'menu_slug' => 'fb404_page', | ||
'page_title' => '404 Fallback Settings', | ||
'menu_title' => '404 Fallback', | ||
'action' => 'fb404_page_update_handler', | ||
] ); | ||
|
||
wpc_menu_register_settings( 'fb404', [ | ||
'general' => [ | ||
'fb404_setting_fallback_url' => 'Fallback URL', | ||
], | ||
] ); | ||
do_action( __FUNCTION__ ); | ||
} | ||
|
||
add_action( 'init', 'fb404_add_settings_menu' ); | ||
|
||
/** | ||
* Templating for our menu page. The function must match the 'menu_slug' in the menu config. | ||
*/ | ||
function fb404_page() { | ||
// Use the default page rendering instead of templating our page here. | ||
wpc_menu_page_render( 'fb404' ); | ||
} | ||
|
||
/** | ||
* Handling the form submission. The function must match the 'action' key in the menu config. | ||
*/ | ||
function fb404_page_update_handler() { | ||
// Use the default page update handler instead of processing our options in a custom way. | ||
wpc_menu_page_update_handler( 'fb404' ); | ||
} | ||
|
||
function fb404_setting_fallback_url_render() { | ||
$option_name = 'fb404_setting_fallback_url'; | ||
$config = stripslashes( get_option( $option_name ) ); | ||
printf( '<input name="%1$s" value="%2$s" | ||
size="48"/>', $option_name, $config ); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,137 @@ | ||
<?php | ||
|
||
/** | ||
* Code used by site menus. | ||
*/ | ||
|
||
/** | ||
* List of menus and their setup configuration | ||
* | ||
* @param string $menu_id Identifier of the menu configuration to access. Leave empty to return all the configurations | ||
* | ||
* @return array Menu configuration(s) | ||
*/ | ||
function wpc_menu_page_configs( $menu_id = '' ) { | ||
return wpc_menu_configs( 'wpc_menu_page_configs', $menu_id ); | ||
} | ||
|
||
function wpc_menu_page_render( $menu_id ) { | ||
$config = wpc_menu_page_configs( $menu_id ); | ||
wpc_menu_render( 'site', $config ); | ||
} | ||
|
||
/** | ||
* Registration of the setting groups to the menu_slug. | ||
*/ | ||
function wpc_menu_page_settings_registration() { | ||
$menus = wpc_menu_page_configs(); | ||
wpc_menu_registration( $menus ); | ||
} | ||
|
||
add_action( 'admin_init', 'wpc_menu_page_settings_registration' ); | ||
|
||
/** | ||
* A generic way to handle the form post request. | ||
* | ||
* @param string $menu_id Menu page configuration id | ||
*/ | ||
function wpc_menu_page_update_handler( $menu_id ) { | ||
// Make sure we are posting from our options page. Note we must add the '-options' postfix | ||
// when we check the referrer. | ||
$config = wpc_menu_page_configs( $menu_id ); | ||
$updated = wpc_menu_update_options( 'site', $config, true ); | ||
|
||
wp_redirect( add_query_arg( [ | ||
'page' => $config['menu_slug'], | ||
'updated' => (string) $updated, | ||
], admin_url( 'admin.php' ) ) ); | ||
exit; | ||
|
||
} | ||
|
||
/** | ||
* Register a grouped setting to a menu page id. | ||
* | ||
* @example Add a setting to the general settings group of the cluster menu-page: | ||
* wpc_menu_register_page_settings( 'cluster', [ | ||
* 'general' => [ | ||
* 'wpc_cluster_use_production_images' => 'Use Production Images', | ||
* ], | ||
* ] ); | ||
* | ||
* @param string|array $menu_id Menu identifier or configuration | ||
* @param array $grouped_settings Array of setting groups. | ||
*/ | ||
function wpc_menu_register_settings( $menu_id, $grouped_settings ) { | ||
|
||
add_filter( 'wpc_menu_page_configs', function ( $menus ) use ( $menu_id, $grouped_settings ) { | ||
if ( empty( $menus[ $menu_id ]['setting_sections'] ) ) { | ||
$menus[ $menu_id ]['setting_sections'] = []; | ||
} | ||
$menus[ $menu_id ]['setting_sections'] = array_merge_recursive( $menus[ $menu_id ]['setting_sections'], $grouped_settings ); | ||
|
||
return $menus; | ||
}, 11 ); | ||
|
||
} | ||
|
||
/** | ||
* Register a menu-page. | ||
* | ||
* @example Add a setting to the general settings group of the cluster menu-page: | ||
* wpc_menu_register_page( [ | ||
* 'id' => 'cluster', | ||
* 'menu_slug' => 'wpc_network_cluster_page', | ||
* 'page_title' => 'Cluster Settings', | ||
* 'menu_title' => 'Cluster', | ||
* ] ); | ||
* | ||
* The following keys are optional: | ||
* - action: points to the function that will update the options instead | ||
* of wpc_menu_page_update_handler() | ||
* | ||
* @param $config | ||
*/ | ||
function wpc_menu_register_page( $config ) { | ||
add_filter( 'wpc_menu_page_configs', function ( $menus ) use ( $config ) { | ||
$menus[ $config['id'] ] = $config; | ||
|
||
return $menus; | ||
} ); | ||
|
||
$defaults = [ | ||
'page_title' => 'My Menu Page', | ||
'menu_title' => 'My Menu', | ||
]; | ||
$config = wp_parse_args( $config, $defaults ); | ||
|
||
add_action( 'admin_menu', function () use ( $config ) { | ||
$menu_slug = $config['menu_slug']; | ||
|
||
if ( empty( $config['parent_slug'] ) ) { | ||
add_menu_page( | ||
$config['page_title'], | ||
$config['menu_title'], | ||
'manage_options', | ||
$menu_slug, | ||
$menu_slug | ||
); | ||
} else { | ||
add_submenu_page( | ||
$config['parent_slug'], | ||
$config['page_title'], | ||
$config['menu_title'], | ||
'manage_options', | ||
$menu_slug, | ||
$menu_slug | ||
); | ||
} | ||
} ); | ||
|
||
$action = $config['action']; | ||
|
||
/** | ||
* This function here is hooked up to a special action and necessary to process the saving of the options. | ||
*/ | ||
add_action( 'admin_post_' . $action, $action ); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,164 @@ | ||
<?php | ||
/** | ||
* Code used by both networkmenus and sitemenus | ||
*/ | ||
|
||
/** | ||
* Accessor for creating menupage configurations | ||
* | ||
* @param string $filter_id Extension point for other code to hook menus into. | ||
* @param string $menu_id Identifier of the menu to retrieve from the filter. | ||
* | ||
* @return array Menu configuration | ||
*/ | ||
function wpc_menu_configs( $filter_id, $menu_id = '' ) { | ||
/* | ||
* Amend the networkmenupage configurations | ||
* Almost always it's better to use one of the following functions instead of calling this directly: | ||
* - function wpc_menu_register_networkpage( $config ) | ||
* - function wpc_menu_register_network_settings( $menu_id, $grouped_settings ) | ||
*/ | ||
$menus = apply_filters( $filter_id, [] ); | ||
|
||
// All menus | ||
if ( false === isset( $menus[ $menu_id ] ) ) { | ||
return $menus; | ||
} | ||
|
||
return $menus[ $menu_id ]; | ||
} | ||
|
||
/** | ||
* @param $menus | ||
*/ | ||
function wpc_menu_registration( array $menus ): void { | ||
// for each menu's data build out sections and register the section's settings | ||
foreach ( array_keys( $menus ) as $id ) { | ||
$config = $menus[ $id ]; | ||
if ( empty( $config['setting_sections'] ) ) { | ||
continue; | ||
} | ||
$sections = $config['setting_sections']; | ||
|
||
if ( is_iterable( $sections ) ) { | ||
foreach ( $sections as $section => $settings ) { | ||
$page = $config['menu_slug']; | ||
add_settings_section( $section, strtoupper( $section ), null, $page ); | ||
|
||
foreach ( (array) $settings as $name => $title ) { | ||
$sanitization = is_callable( $name . '_sanitize' ) ? $name . '_sanitize' : []; | ||
register_setting( $section, $name, $sanitization ); | ||
add_settings_field( $name, $title, | ||
$name . '_render', $page, | ||
$section ); | ||
} | ||
} | ||
} | ||
} | ||
} | ||
|
||
/** | ||
* Update a single option | ||
* | ||
* @param string $type Type: network or site | ||
* @param bool $delete_missing Whether to delete the option if not submitted? | ||
* @param string $option Option name | ||
* | ||
* @return bool False if value was not updated, true if updated. | ||
*/ | ||
function wpc_menu_update_option( $type, $delete_missing, $option ): bool { | ||
$updated = false; | ||
|
||
if ( isset( $_POST[ $option ] ) ) { | ||
if ( 'network' === $type ) { | ||
$updated = update_site_option( $option, $_POST[ $option ] ); | ||
} else { | ||
$updated = update_option( $option, $_POST[ $option ] ); | ||
|
||
} | ||
} elseif ( $delete_missing ) { | ||
if ( 'network' === $type ) { | ||
$updated = delete_site_option( $option ); | ||
} else { | ||
$updated = delete_option( $option ); | ||
} | ||
} | ||
|
||
return $updated; | ||
} | ||
|
||
/** | ||
* Update the options for a given network page configuration | ||
* | ||
* @param string $type network|site configuration type | ||
* @param array|string $config menu configuration or id of one. | ||
* @param bool $delete_missing if missing options should be deleted or skipped | ||
* | ||
* @return bool if any of the options was updated or deleted | ||
*/ | ||
function wpc_menu_update_options( $type, $config, $delete_missing ) { | ||
global $new_whitelist_options; | ||
|
||
check_admin_referer( $config['menu_slug'] . '-options' ); | ||
|
||
$did_update = false; | ||
|
||
// Update or delete all the options | ||
$sections = $config['setting_sections']; | ||
if ( false === is_iterable( $sections ) ) { | ||
return $did_update ? 'true' : 'false'; | ||
} | ||
foreach ( (array) $sections as $section => $options ) { | ||
|
||
$options = $new_whitelist_options[ $section ]; | ||
foreach ( (array) $options as $option ) { | ||
$updated = wpc_menu_update_option( $type, $delete_missing, $option ); | ||
if ( $updated ) { | ||
$did_update = true; | ||
} | ||
} | ||
} | ||
|
||
return $did_update ? 'true' : 'false'; | ||
|
||
} | ||
|
||
function wpc_menu_render( $type, $config ) { | ||
// Nonce is verified by wpc_menu_fields | ||
if ( isset( $_GET['updated'] ) ): ?> | ||
<div id="message" class="updated notice is-dismissible"><p><?php _e( 'Options saved.' ); ?></p></div> | ||
<?php endif; | ||
|
||
$full_action = [ | ||
'network' => 'edit.php?action=' . esc_attr( $config['action'] ), | ||
'site' => admin_url( 'admin-post.php' ), | ||
]; | ||
?> | ||
<div class="wrap custom-options"> | ||
<header class="custom-options__header"> | ||
<h1><?php echo esc_html( $config['page_title'] ); ?></h1> | ||
</header> | ||
|
||
<form action="<?php echo $full_action[ $type ] ?>" method="POST"> | ||
<?php | ||
wpc_menu_fields( $type, $config ); | ||
do_settings_sections( $config['menu_slug'] ); | ||
submit_button(); | ||
?> | ||
</form> | ||
</div> | ||
<?php | ||
} | ||
|
||
/** | ||
* Configuration type aware settings fields | ||
* | ||
* @param string $type network|site | ||
* @param array $config menu configuration | ||
*/ | ||
function wpc_menu_fields( $type, $config ) { | ||
settings_fields( $config['menu_slug'] ); | ||
if ( 'network' !== $type ) { | ||
echo "<input type='hidden' name='action' value='" . esc_attr( $config['action'] ) . "' />"; | ||
} | ||
} |
Oops, something went wrong.