diff --git a/README.md b/README.md index e1d5ce7..1c03c6b 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,11 @@ +# WP Multi Network + [![WordPress plugin](https://img.shields.io/wordpress/plugin/v/wp-multi-network.svg)](https://wordpress.org/plugins/wp-multi-network/) [![WordPress](https://img.shields.io/wordpress/v/wp-multi-network.svg)](https://wordpress.org/plugins/wp-multi-network/) [![Build Status](https://api.travis-ci.org/stuttter/wp-multi-network.png?branch=master)](https://travis-ci.org/stuttter/wp-multi-network) [![Latest Stable Version](https://poser.pugx.org/stuttter/wp-multi-network/version)](https://packagist.org/packages/stuttter/wp-multi-network) [![License](https://poser.pugx.org/stuttter/wp-multi-network/license)](https://packagist.org/packages/stuttter/wp-multi-network) -# WP Multi Network - Provides a Network Management Interface for global administrators in WordPress Multisite installations. Turn your WordPress Multisite installation into many multisite networks, surrounding one global set of users. @@ -17,7 +17,7 @@ Turn your WordPress Multisite installation into many multisite networks, surroun * Allows global administrators to create new networks with their own sites and domain arrangements. * Group sites into logical networks using nearly any combination of domain (example.org) and path (/site/). -# Installation +## Installation * Download and install using the built in WordPress plugin installer. * Activate in the "Plugins" network admin panel using the "Network Activate" link. @@ -72,11 +72,11 @@ define( 'WP_HOME', 'https://' . $_SERVER['HTTP_HOST'] ); define( 'WP_SITEURL', 'https://' . $_SERVER['HTTP_HOST'] ); ``` -### Single Sign-on +## Single Sign-on Single Sign-on is a way to keep registered users signed into your installation regardless of what domain, subdomain, and path they are viewing. This functionality is outside the scope of what WP Multi Network hopes to provide, but a dedicated SSO plugin made specifically for WP Multi Network is in development. -# FAQ +## FAQ ### Can I have separate domains? diff --git a/readme.txt b/readme.txt index 90990e7..474353a 100644 --- a/readme.txt +++ b/readme.txt @@ -1,15 +1,14 @@ === WP Multi Network === Author: Triple J Software, Inc. Author URI: https://jjj.software -Donate link: https://buy.stripe.com/7sI3cd2tK1Cy2lydQR Plugin URI: https://wordpress.org/plugins/wp-multi-network/ License URI: https://www.gnu.org/licenses/gpl-2.0.html License: GPLv2 or later Contributors: johnjamesjacoby, flixos90, rmccue, spacedmonkey Tags: network, sites, domains, global, admin Requires PHP: 5.2 -Requires at least: 4.9 -Tested up to: 6.1 +Requires at least: 5.0 +Tested up to: 6.6 Stable tag: 2.5.2 == Description == @@ -122,12 +121,16 @@ please follow the steps in https://paulund.co.uk/wordpress-multisite-nested-path Not much to talk about really. Check the code for details! == Changelog == + += 2.5.3 = +* Remove filter_input usages + = 2.5.2 = * Use get_main_site_id function instead of get_main_site_for_network. * Tested against WordPress 6.1. = 2.5.1 = -* Save main site on network as network option. +* Save main site on network as network option. = 2.5.0 = * Fix new networks sometimes not being created. diff --git a/wp-multi-network/includes/classes/class-wp-ms-networks-admin.php b/wp-multi-network/includes/classes/class-wp-ms-networks-admin.php index 7d711c9..eda7361 100644 --- a/wp-multi-network/includes/classes/class-wp-ms-networks-admin.php +++ b/wp-multi-network/includes/classes/class-wp-ms-networks-admin.php @@ -137,7 +137,10 @@ public function fix_menu_highlight_for_move_page() { global $plugin_page, $submenu_file; if ( 'networks' === $plugin_page ) { - $action = filter_input( INPUT_GET, 'action' ); + $action = ! empty( $_GET['action'] ) + ? sanitize_key( $_GET['action'] ) + : ''; + if ( 'move' === $action ) { $submenu_file = 'sites.php'; // phpcs:ignore WordPress.Variables.GlobalVariables.OverrideProhibited } @@ -199,8 +202,12 @@ private function set_feedback_strings() { public function network_admin_notices() { $message = ''; $type = ''; + foreach ( $this->feedback_strings as $slug => $messages ) { - $passed = filter_input( INPUT_GET, $slug ); + + $passed = ! empty( $_GET[ $slug ] ) + ? sanitize_key( $_GET[ $slug ] ) + : ''; if ( is_string( $passed ) ) { if ( '1' === $passed ) { @@ -242,8 +249,9 @@ public function route_pages() { wp_die( esc_html__( 'You do not have permission to access this page.', 'wp-multi-network' ) ); } - $action = filter_input( INPUT_GET, 'action', FILTER_SANITIZE_FULL_SPECIAL_CHARS ); - $action = sanitize_key( $action ); + $action = ! empty( $_GET['action'] ) + ? sanitize_key( $_GET['action'] ) + : ''; switch ( $action ) { @@ -264,11 +272,19 @@ public function route_pages() { // View the list of networks, with bulk action handling. case 'all_networks': - $doaction = filter_input( INPUT_POST, 'action', FILTER_SANITIZE_FULL_SPECIAL_CHARS ); - if ( empty( $doaction ) || '-1' === $doaction ) { - $doaction = filter_input( INPUT_POST, 'action2', FILTER_SANITIZE_FULL_SPECIAL_CHARS ); + $doaction = ! empty( $_POST['action'] ) + ? sanitize_key( $_POST['action'] ) + : ''; + + if ( + empty( $doaction ) + || + ( '-1' === $doaction ) + ) { + $doaction = ! empty( $_POST['action2'] ) + ? sanitize_key( $_POST['action2'] ) + : ''; } - $doaction = sanitize_key( $doaction ); switch ( $doaction ) { case 'delete': @@ -300,11 +316,15 @@ public function route_save_handlers() { return; } - $action = filter_input( INPUT_POST, 'action', FILTER_SANITIZE_FULL_SPECIAL_CHARS ); + $action = ! empty( $_POST['action'] ) + ? sanitize_key( $_POST['action'] ) + : ''; + if ( empty( $action ) ) { $alternative_actions = array( 'delete', 'delete_multiple', 'move' ); + foreach ( $alternative_actions as $alternative_action ) { - if ( filter_input( INPUT_POST, $alternative_action ) ) { + if ( ! empty( $_POST[ $alternative_action ] ) ) { $action = $alternative_action; break; } @@ -352,8 +372,14 @@ public function route_save_handlers() { * @since 2.0.0 */ public function page_edit_network() { - $network_id = filter_input( INPUT_GET, 'id', FILTER_SANITIZE_NUMBER_INT ); - $network = $network_id ? get_network( $network_id ) : null; + + $network_id = ! empty( $_GET['id'] ) && is_numeric( $_GET['id'] ) + ? (int) $_GET['id'] + : 0; + + $network = ! empty( $network_id ) + ? get_network( $network_id ) + : null; add_meta_box( 'wpmn-edit-network-details', esc_html__( 'Details', 'wp-multi-network' ), 'wpmn_edit_network_details_metabox', get_current_screen()->id, 'normal', 'high', array( $network ) ); add_meta_box( 'wpmn-edit-network-publish', esc_html__( 'Network', 'wp-multi-network' ), 'wpmn_edit_network_publish_metabox', get_current_screen()->id, 'side', 'high', array( $network ) ); @@ -391,7 +417,7 @@ public function page_edit_network() {
-
+
@@ -434,7 +460,10 @@ private function page_all_networks() { $all_networks_url = $this->admin_url( array( 'action' => 'all_networks' ) ); $search_url = $this->admin_url( array( 'action' => 'domains' ) ); - $search_text = filter_input( INPUT_POST, 's', FILTER_SANITIZE_FULL_SPECIAL_CHARS ); + $search_text = ! empty( $_POST['s'] ) + ? stripslashes( trim( sanitize_text_field( $_POST['s'] ) ) ) + : ''; + ?>
@@ -462,7 +491,7 @@ private function page_all_networks() { -
+ display(); ?>
@@ -476,8 +505,14 @@ private function page_all_networks() { * @since 2.0.0 */ private function page_move_site() { - $site_id = filter_input( INPUT_GET, 'blog_id', FILTER_SANITIZE_NUMBER_INT ); - $site = $site_id ? get_site( $site_id ) : null; + + $site_id = ! empty( $_GET['blog_id'] ) && is_numeric( $_GET['blog_id'] ) + ? (int) $_GET['blog_id'] + : 0; + + $site = ! empty( $site_id ) + ? get_site( $site_id ) + : null; // Bail if invalid site ID. if ( empty( $site ) ) { @@ -506,7 +541,9 @@ private function page_move_site() { array( $site ) ); + // URLs to escape. $add_network_url = $this->admin_url( array( 'page' => 'add-new-network' ) ); + $form_action_url = $this->admin_url( array( 'action' => 'move', 'blog_id' => $site_id ) ); ?>
@@ -524,7 +561,7 @@ private function page_move_site() {
-
+
@@ -549,8 +586,14 @@ private function page_move_site() { * @since 2.0.0 */ private function page_delete_network() { - $network_id = filter_input( INPUT_GET, 'id', FILTER_SANITIZE_NUMBER_INT ); - $network = $network_id ? get_network( $network_id ) : null; + + $network_id = ! empty( $_GET['id'] ) && is_numeric( $_GET['id'] ) + ? (int) $_GET['id'] + : 0; + + $network = ! empty( $network_id ) + ? get_network( $network_id ) + : null; // Bail if invalid network ID. if ( empty( $network ) ) { @@ -577,7 +620,7 @@ private function page_delete_network() {
- + id; } - // Sanitize values. - $network_title = wp_unslash( filter_input( INPUT_POST, 'title', FILTER_SANITIZE_FULL_SPECIAL_CHARS ) ); - $network_domain = wp_unslash( filter_input( INPUT_POST, 'domain', FILTER_SANITIZE_FULL_SPECIAL_CHARS ) ); - $network_path = wp_unslash( filter_input( INPUT_POST, 'path', FILTER_SANITIZE_FULL_SPECIAL_CHARS ) ); - $site_name = wp_unslash( filter_input( INPUT_POST, 'new_site', FILTER_SANITIZE_FULL_SPECIAL_CHARS ) ); - - // Additional formatting. - $network_title = wp_strip_all_tags( $network_title ); + // Unslash posted values. + $network_title = ! empty( $_POST['title'] ) + ? wp_unslash( $_POST['title'] ) + : ''; + $network_domain = ! empty( $_POST['domain'] ) + ? wp_unslash( $_POST['domain'] ) + : ''; + $network_path = ! empty( $_POST['path'] ) + ? wp_unslash( $_POST['path'] ) + : ''; + $site_name = ! empty( $_POST['new_site'] ) + ? wp_unslash( $_POST['new_site'] ) + : ''; + + // Additional sanitization. + $network_title = sanitize_text_field( $network_title ); $network_domain = str_replace( ' ', '', strtolower( sanitize_text_field( $network_domain ) ) ); $network_path = str_replace( ' ', '', strtolower( sanitize_text_field( $network_path ) ) ); // Fallback to network title if not explicitly set. $site_name = ! empty( $site_name ) - ? wp_strip_all_tags( $site_name ) + ? sanitize_text_field( $site_name ) : $network_title; // Bail if missing fields. @@ -944,21 +1005,29 @@ private function handle_add_network() { private function handle_update_network() { // Sanitize network ID. - $network_id = filter_input( INPUT_POST, 'network_id', FILTER_SANITIZE_NUMBER_INT ); + $network_id = ! empty( $_GET['id'] ) && is_numeric( $_GET['id'] ) + ? (int) $_GET['id'] + : 0; // Bail if invalid network. if ( ! get_network( $network_id ) ) { wp_die( esc_html__( 'Invalid network id.', 'wp-multi-network' ) ); } - // Sanitize values. - $network_title = wp_unslash( filter_input( INPUT_POST, 'title', FILTER_SANITIZE_FULL_SPECIAL_CHARS ) ); - $network_domain = wp_unslash( filter_input( INPUT_POST, 'domain', FILTER_SANITIZE_FULL_SPECIAL_CHARS ) ); - $network_path = wp_unslash( filter_input( INPUT_POST, 'path', FILTER_SANITIZE_FULL_SPECIAL_CHARS ) ); - - // Additional formatting. + // Unslash posted values. + $network_title = ! empty( $_POST['title'] ) + ? wp_unslash( $_POST['title'] ) + : ''; + $network_domain = ! empty( $_POST['domain'] ) + ? wp_unslash( $_POST['domain'] ) + : ''; + $network_path = ! empty( $_POST['path'] ) + ? wp_unslash( $_POST['path'] ) + : ''; + + // Additional sanitization. $network_title = sanitize_text_field( $network_title ); - $network_domain = Requests_IDNAEncoder::encode( str_replace( ' ', '', strtolower( sanitize_text_field( $network_domain ) ) ) ); + $network_domain = str_replace( ' ', '', strtolower( sanitize_text_field( $network_domain ) ) ); $network_path = str_replace( ' ', '', strtolower( sanitize_text_field( $network_path ) ) ); // Bail if missing fields. @@ -1006,8 +1075,13 @@ private function handle_update_network() { private function handle_move_site() { // Sanitize values. - $site_id = filter_input( INPUT_GET, 'blog_id', FILTER_SANITIZE_NUMBER_INT ); - $new_network = filter_input( INPUT_POST, 'to', FILTER_SANITIZE_NUMBER_INT ); + $site_id = ! empty( $_GET['blog_id'] ) && is_numeric( $_GET['blog_id'] ) + ? (int) $_GET['blog_id'] + : 0; + + $new_network = ! empty( $_POST['to'] ) && is_numeric( $_POST['to'] ) + ? (int) $_POST['to'] + : 0; // Bail if no site ID. if ( empty( $site_id ) ) { @@ -1066,8 +1140,13 @@ private function handle_move_site() { private function handle_reassign_sites() { // Sanitize values. - $to = array_map( 'absint', (array) filter_input( INPUT_POST, 'to', FILTER_SANITIZE_NUMBER_INT, FILTER_FORCE_ARRAY ) ); - $from = array_map( 'absint', (array) filter_input( INPUT_POST, 'from', FILTER_SANITIZE_NUMBER_INT, FILTER_FORCE_ARRAY ) ); + $to = ! empty( $_POST['to'] ) && is_array( $_POST['to'] ) + ? wp_parse_id_list( (array) $_POST['to'] ) + : array(); + + $from = ! empty( $_POST['from'] ) && is_array( $_POST['from'] ) + ? wp_parse_id_list( (array) $_POST['from'] ) + : array(); // Bail early if no movement. if ( empty( $to ) && empty( $from ) ) { @@ -1075,7 +1154,9 @@ private function handle_reassign_sites() { } // Sanitize network ID. - $network_id = filter_input( INPUT_GET, 'id', FILTER_SANITIZE_NUMBER_INT ); + $network_id = ! empty( $_GET['id'] ) && is_numeric( $_GET['id'] ) + ? (int) $_GET['id'] + : 0; // Default to/from arrays. $moving_to = array(); @@ -1130,8 +1211,11 @@ private function handle_reassign_sites() { private function handle_delete_network() { // Sanitize values. - $network_id = filter_input( INPUT_GET, 'id', FILTER_SANITIZE_NUMBER_INT ); - $override = (bool) filter_input( INPUT_POST, 'override' ); + $network_id = ! empty( $_GET['id'] ) && is_numeric( $_GET['id'] ) + ? (int) $_GET['id'] + : 0; + + $override = (bool) ! empty( $_POST['override'] ); // Attempt to delete network. $result = delete_network( $network_id, $override ); @@ -1157,8 +1241,11 @@ private function handle_delete_network() { private function handle_delete_networks() { // Sanitize values. - $deleted_networks = array_map( 'absint', filter_input( INPUT_POST, 'deleted_networks', FILTER_SANITIZE_NUMBER_INT, FILTER_FORCE_ARRAY ) ); - $override = (bool) filter_input( INPUT_POST, 'override' ); + $deleted_networks = ! empty( $_POST['deleted_networks'] ) && is_array( $_POST['deleted_networks'] ) + ? wp_parse_id_list( (array) $_POST['deleted_networks'] ) + : array(); + + $override = (bool) ! empty( $_POST['override'] ); // Loop through deleted networks. if ( ! empty( $deleted_networks ) ) { diff --git a/wp-multi-network/includes/classes/class-wp-ms-networks-list-table.php b/wp-multi-network/includes/classes/class-wp-ms-networks-list-table.php index 87091d1..57bd053 100644 --- a/wp-multi-network/includes/classes/class-wp-ms-networks-list-table.php +++ b/wp-multi-network/includes/classes/class-wp-ms-networks-list-table.php @@ -52,16 +52,18 @@ public function prepare_items() { $per_page = $this->get_items_per_page( 'networks_per_page' ); $pagenum = $this->get_pagenum(); - $order_by = filter_input( INPUT_GET, 'orderby', FILTER_SANITIZE_FULL_SPECIAL_CHARS ); - $order_by = ! empty( $order_by ) ? sanitize_key( $order_by ) : ''; - $order = filter_input( INPUT_GET, 'order', FILTER_SANITIZE_FULL_SPECIAL_CHARS ); - $order = ! empty( $order ) ? strtoupper( $order ) : 'ASC'; - $search = filter_input( INPUT_GET, 's', FILTER_SANITIZE_FULL_SPECIAL_CHARS ); - if ( ! $search ) { - $search = filter_input( INPUT_POST, 's', FILTER_SANITIZE_FULL_SPECIAL_CHARS ); - } + $order_by = ! empty( $_GET['orderby'] ) + ? sanitize_key( $_GET['orderby'] ) + : ''; + + $order = ! empty( $_GET['order'] ) + ? strtoupper( sanitize_key( $_GET['order'] ) ) + : 'ASC'; + + $search = ! empty( $_REQUEST['s'] ) + ? stripslashes( sanitize_text_field( $_REQUEST['s'] ) ) + : ''; - $search = stripslashes( trim( $search ) ); if ( false !== strpos( $search, '*' ) ) { $search = trim( $search, '*' ); } diff --git a/wp-multi-network/includes/metaboxes/edit-network.php b/wp-multi-network/includes/metaboxes/edit-network.php index af37975..ac993ab 100644 --- a/wp-multi-network/includes/metaboxes/edit-network.php +++ b/wp-multi-network/includes/metaboxes/edit-network.php @@ -17,8 +17,14 @@ * @param WP_Network $network Optional. Network object. Default null. */ function wpmn_edit_network_details_metabox( $network = null ) { - $domain = ! empty( $network->domain ) ? Requests_IDNAEncoder::encode( $network->domain ) : ''; - $path = ! empty( $network->path ) ? $network->path : '/'; + + $domain = ! empty( $network->domain ) + ? $network->domain + : ''; + + $path = ! empty( $network->path ) + ? $network->path + : '/'; ?>