| @@ -34,9 +34,9 @@ | ||
| 34 | 34 | * Public static variable to hold the current plugin version. |
| 35 | 35 | * |
| 36 | 36 | * @var string Current plugin version. |
| 37 | 37 | */ |
| 38 | - public static $version = '6.2'; // NOSONAR. | |
| 38 | + public static $version = '6.3'; // NOSONAR. | |
| 39 | 39 | |
| 40 | 40 | /** |
| 41 | 41 | * Private static variable to hold the single instance of the class. |
| 42 | 42 | * |
| @@ -63,9 +63,9 @@ | ||
| 63 | 63 | * Private variable to hold the check update version number. |
| 64 | 64 | * |
| 65 | 65 | * @var string The plugin current update version. |
| 66 | 66 | */ |
| 67 | - private $check_ver_update = '0.0.5'; | |
| 67 | + private $check_ver_update = '0.0.8'; | |
| 68 | 68 | |
| 69 | 69 | /** |
| 70 | 70 | * Private variable to hold the plugin slug (mainwp/mainwp.php) |
| 71 | 71 | * |
| @@ -239,8 +239,9 @@ | ||
| 239 | 239 | MainWP_Bulk_Post::get_instance(); |
| 240 | 240 | |
| 241 | 241 | add_action( 'admin_init', array( &$this, 'admin_init' ), 20 ); |
| 242 | 242 | add_action( 'admin_init', array( $this, 'hook_admin_update_check' ) ); |
| 243 | + add_action( 'admin_init', array( $this, 'admin_init_update' ) ); | |
| 243 | 244 | add_action( 'after_setup_theme', array( &$this, 'after_setup_theme' ) ); |
| 244 | 245 | |
| 245 | 246 | add_action( 'init', array( &$this, 'parse_init' ) ); |
| 246 | 247 | add_action( 'init', array( &$this, 'init_jobs' ) ); |
| @@ -289,8 +290,9 @@ | ||
| 289 | 290 | MainWP_Themes::init(); |
| 290 | 291 | MainWP_Plugins::init(); |
| 291 | 292 | MainWP_Updates_Overview::init(); |
| 292 | 293 | MainWP_Client::init(); |
| 294 | + MainWP_Knowledge_UI::init(); | |
| 293 | 295 | MainWP_Rest_Api_Page::init(); |
| 294 | 296 | MainWP_Logger::instance(); |
| 295 | 297 | |
| 296 | 298 | if ( class_exists( '\MainWP\Dashboard\Module\Log\Log_Manage_Insights_Events_Page' ) ) { |
| @@ -401,8 +403,9 @@ | ||
| 401 | 403 | 'mainwp_show_language_updates', |
| 402 | 404 | 'mainwp_logger_check_daily', |
| 403 | 405 | 'mainwp_site_actions_notification_enable', |
| 404 | 406 | 'mainwp_update_check_version', |
| 407 | + 'mainwp_admin_init_update_data', | |
| 405 | 408 | 'mainwp_setting_demo_mode_enabled', |
| 406 | 409 | 'mainwp_log_wait_lasttime', |
| 407 | 410 | 'mainwp_cron_license_deactivated_alert_lasttime', |
| 408 | 411 | 'mainwp_updatescheck_is_running', |
| @@ -615,9 +618,9 @@ | ||
| 615 | 618 | */ |
| 616 | 619 | public static function is_mainwp_site_page() { |
| 617 | 620 | $is_page = false; |
| 618 | 621 | //phpcs:disable WordPress.Security.NonceVerification.Recommended |
| 619 | - if ( isset( $_GET['page'] ) && 'CostTrackerAdd' !== $_GET['page'] && ( ( ( isset( $_GET['id'] ) && ! empty( $_GET['id'] ) ) || ( isset( $_GET['dashboard'] ) && ! empty( $_GET['dashboard'] ) ) || ( isset( $_GET['updateid'] ) && ! empty( $_GET['updateid'] ) ) || ( isset( $_GET['monitor_wpid'] ) && ! empty( $_GET['monitor_wpid'] ) ) || ( isset( $_GET['emailsettingsid'] ) && ! empty( $_GET['emailsettingsid'] ) ) || ( isset( $_GET['scanid'] ) && ! empty( $_GET['scanid'] ) ) ) || ( 'ServerInformation' === $_GET['page'] || 'ServerInformationCron' === $_GET['page'] || 'ErrorLog' === $_GET['page'] || 'ActionLogs' === $_GET['page'] || 'PluginPrivacy' === $_GET['page'] || 'Settings' === $_GET['page'] || 'SettingsAdvanced' === $_GET['page'] || 'SettingsEmail' === $_GET['page'] || 'PremiumUpdates' === $_GET['page'] || 'MainWPTools' === $_GET['page'] || 'SettingsInsights' === $_GET['page'] || 'SettingsApiBackups' === $_GET['page'] || 'MonitoringSettings' === $_GET['page'] ) ) ) { | |
| 622 | + if ( isset( $_GET['page'] ) && 'CostTrackerAdd' !== $_GET['page'] && ( ( ( isset( $_GET['id'] ) && ! empty( $_GET['id'] ) ) || ( isset( $_GET['dashboard'] ) && ! empty( $_GET['dashboard'] ) ) || ( isset( $_GET['knowledgeid'] ) && ! empty( $_GET['knowledgeid'] ) ) || ( isset( $_GET['updateid'] ) && ! empty( $_GET['updateid'] ) ) || ( isset( $_GET['monitor_wpid'] ) && ! empty( $_GET['monitor_wpid'] ) ) || ( isset( $_GET['emailsettingsid'] ) && ! empty( $_GET['emailsettingsid'] ) ) || ( isset( $_GET['scanid'] ) && ! empty( $_GET['scanid'] ) ) ) || ( 'ServerInformation' === $_GET['page'] || 'ServerInformationCron' === $_GET['page'] || 'ErrorLog' === $_GET['page'] || 'ActionLogs' === $_GET['page'] || 'PluginPrivacy' === $_GET['page'] || 'Settings' === $_GET['page'] || 'SettingsAdvanced' === $_GET['page'] || 'SettingsEmail' === $_GET['page'] || 'PremiumUpdates' === $_GET['page'] || 'MainWPTools' === $_GET['page'] || 'SettingsInsights' === $_GET['page'] || 'SettingsApiBackups' === $_GET['page'] || 'MonitoringSettings' === $_GET['page'] ) ) ) { | |
| 620 | 623 | $is_page = true; |
| 621 | 624 | } |
| 622 | 625 | //phpcs:enable |
| 623 | 626 | |
| @@ -730,17 +733,16 @@ | ||
| 730 | 733 | */ |
| 731 | 734 | public function parse_init() { |
| 732 | 735 | // phpcs:disable WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized |
| 733 | 736 | if ( isset( $_GET['mwpdl'] ) && isset( $_GET['sig'] ) ) { |
| 737 | + if ( ! isset( $_REQUEST['mwpdl'] ) || ! is_string( $_REQUEST['mwpdl'] ) || ! is_string( $_GET['sig'] ) ) { | |
| 738 | + return; | |
| 739 | + } | |
| 734 | 740 | $mwpDir = MainWP_System_Utility::get_mainwp_dir(); |
| 735 | 741 | $mwpDir = $mwpDir[0]; |
| 736 | 742 | $mwpdl = isset( $_REQUEST['mwpdl'] ) ? wp_unslash( $_REQUEST['mwpdl'] ) : ''; |
| 737 | 743 | $file = trailingslashit( $mwpDir ) . rawurldecode( $mwpdl ); |
| 738 | 744 | |
| 739 | - if ( stristr( rawurldecode( $mwpdl ), '..' ) ) { | |
| 740 | - return; | |
| 741 | - } | |
| 742 | - | |
| 743 | 745 | $hasWPFileSystem = MainWP_System_Utility::get_wp_file_system(); |
| 744 | 746 | |
| 745 | 747 | /** |
| 746 | 748 | * WordPress files system object. |
| @@ -748,18 +750,19 @@ | ||
| 748 | 750 | * @global object |
| 749 | 751 | */ |
| 750 | 752 | global $wp_filesystem; |
| 751 | 753 | $sig_value = wp_unslash( $_GET['sig'] ); |
| 752 | - $valid_sig = MainWP_System_Utility::valid_download_sig( $file, $sig_value ); | |
| 754 | + $valid_sig = ! stristr( rawurldecode( $mwpdl ), '..' ) && MainWP_System_Utility::valid_download_sig( $file, $sig_value ); | |
| 753 | 755 | |
| 754 | - if ( ! $valid_sig ) { | |
| 755 | - MainWP_Logger::instance()->debug( ' :: download :: invalid sig :: ' . base64_decode( $sig_value ) ); // phpcs:ignore -- for debug logging. | |
| 756 | - } | |
| 757 | - | |
| 758 | 756 | if ( $hasWPFileSystem && $wp_filesystem->exists( $file ) && $valid_sig ) { |
| 759 | 757 | MainWP_System_Handler::instance()->upload_file( $file ); |
| 760 | 758 | exit(); |
| 761 | 759 | } |
| 760 | + | |
| 761 | + status_header( 403 ); | |
| 762 | + header( 'Content-Type: text/plain; charset=utf-8' ); | |
| 763 | + echo 'Download link is invalid or expired.'; | |
| 764 | + exit(); | |
| 762 | 765 | } elseif ( isset( $_GET['page'] ) ) { |
| 763 | 766 | if ( MainWP_System_Utility::is_admin() && 'mainwp-setup' === $_GET['page'] ) { |
| 764 | 767 | MainWP_Setup_Wizard::get_instance(); |
| 765 | 768 | } |
| @@ -791,19 +794,15 @@ | ||
| 791 | 794 | * Method hook_admin_update_check() |
| 792 | 795 | */ |
| 793 | 796 | public function hook_admin_update_check() { |
| 794 | 797 | $current_ver = $this->check_ver_update; |
| 795 | - $saved_ver = get_option( 'mainwp_update_check_version', false ); | |
| 798 | + $saved_ver = get_option( 'mainwp_update_check_version', '' ); | |
| 796 | 799 | |
| 797 | - if ( false === $saved_ver ) { | |
| 798 | - return; | |
| 799 | - } | |
| 800 | - | |
| 801 | 800 | if ( version_compare( $saved_ver, $current_ver, '=' ) ) { |
| 802 | 801 | return; |
| 803 | 802 | } |
| 804 | 803 | |
| 805 | - if ( version_compare( $saved_ver, '0.0.4', '<' ) ) { | |
| 804 | + if ( ! empty( $saved_ver ) && version_compare( $saved_ver, '0.0.4', '<' ) ) { | |
| 806 | 805 | $sched = wp_next_scheduled( 'mainwp_cronstats_action' ); |
| 807 | 806 | if ( ! empty( $sched ) ) { |
| 808 | 807 | wp_unschedule_event( $sched, 'mainwp_cronstats_action' ); |
| 809 | 808 | } |
| @@ -810,9 +809,9 @@ | ||
| 810 | 809 | global $wpdb; |
| 811 | 810 | $wpdb->query( 'DELETE FROM ' . $wpdb->usermeta . ' WHERE meta_key = "mainwp_widgets_sorted_toplevel_page_mainwp_tab" OR meta_key="mainwp_settings_show_widgets"' );//phpcs:ignore -- safe. |
| 812 | 811 | } |
| 813 | 812 | |
| 814 | - if ( version_compare( $saved_ver, '0.0.5', '<' ) ) { | |
| 813 | + if ( ! empty( $saved_ver ) && version_compare( $saved_ver, '0.0.5', '<' ) ) { | |
| 815 | 814 | $all_ext = MainWP_Extensions_View::get_available_extensions(); |
| 816 | 815 | foreach ( $all_ext as $slug => $info ) { |
| 817 | 816 | $data = MainWP_Api_Manager::instance()->get_activation_info( $slug ); |
| 818 | 817 | if ( is_array( $data ) && isset( $data['api_key'] ) ) { |
| @@ -823,12 +822,73 @@ | ||
| 823 | 822 | } |
| 824 | 823 | update_option( 'mainwp_extensions_all_activation_cached', '' ); |
| 825 | 824 | } |
| 826 | 825 | |
| 826 | + if ( version_compare( $saved_ver, '0.0.8', '<' ) ) { | |
| 827 | + static::handle_admin_perform_update( 'attempted_repair_primary_monitors' ); // init attempted repair. | |
| 828 | + } | |
| 829 | + | |
| 827 | 830 | MainWP_Utility::update_option( 'mainwp_update_check_version', $current_ver ); |
| 828 | 831 | } |
| 829 | 832 | |
| 833 | + | |
| 830 | 834 | /** |
| 835 | + * Method admin_init_update() | |
| 836 | + */ | |
| 837 | + public function admin_init_update() { | |
| 838 | + static::handle_admin_perform_update(); | |
| 839 | + } | |
| 840 | + | |
| 841 | + | |
| 842 | + /** | |
| 843 | + * Method handle_admin_perform_update() | |
| 844 | + * | |
| 845 | + * @param string $action Init action. | |
| 846 | + */ | |
| 847 | + public function handle_admin_perform_update( $action = '' ) { | |
| 848 | + | |
| 849 | + $update_actions = get_option( 'mainwp_admin_init_update_data' ); | |
| 850 | + | |
| 851 | + /** | |
| 852 | + * Filters the update actions. | |
| 853 | + * | |
| 854 | + * @param array $update_actions The available update actions. | |
| 855 | + * @param string $action The current update action. | |
| 856 | + * | |
| 857 | + * @since 6.2.1 | |
| 858 | + * | |
| 859 | + * @return array The filtered update actions. | |
| 860 | + */ | |
| 861 | + $update_actions = apply_filters( 'mainwp_admin_init_update_data', $update_actions, $action ); | |
| 862 | + | |
| 863 | + if ( ! empty( $action ) ) { | |
| 864 | + if ( ! is_array( $update_actions ) ) { | |
| 865 | + $update_actions = array(); | |
| 866 | + } | |
| 867 | + if ( 'attempted_repair_primary_monitors' === $action ) { | |
| 868 | + $update_actions['attempted_repair_primary_monitors'] = 0; | |
| 869 | + } | |
| 870 | + } | |
| 871 | + | |
| 872 | + if ( is_array( $update_actions ) ) { | |
| 873 | + $update = false; | |
| 874 | + if ( isset( $update_actions['attempted_repair_primary_monitors'] ) ) { | |
| 875 | + $result = MainWP_DB_Uptime_Monitoring::instance()->repair_missing_primary_monitors( $update_actions['attempted_repair_primary_monitors'] ); | |
| 876 | + if ( is_array( $result ) && ! empty( $result['attempted'] ) ) { | |
| 877 | + $update_actions['attempted_repair_primary_monitors'] = $result['attempted']; | |
| 878 | + } else { | |
| 879 | + unset( $update_actions['attempted_repair_primary_monitors'] ); | |
| 880 | + } | |
| 881 | + $update = true; | |
| 882 | + } | |
| 883 | + | |
| 884 | + if ( $update ) { | |
| 885 | + MainWP_Utility::update_option( 'mainwp_admin_init_update_data', $update_actions ); | |
| 886 | + } | |
| 887 | + } | |
| 888 | + } | |
| 889 | + | |
| 890 | + /** | |
| 831 | 891 | * Method admin_init() |
| 832 | 892 | * |
| 833 | 893 | * Do nothing if current user is not an Admin else display the page. |
| 834 | 894 | * |
| @@ -916,8 +976,9 @@ | ||
| 916 | 976 | 'installedBulkSettingsManager' => is_plugin_active( 'mainwp-bulk-settings-manager/mainwp-bulk-settings-manager.php' ) ? 1 : 0, |
| 917 | 977 | 'maximumSyncRequests' => ( get_option( 'mainwp_maximumSyncRequests' ) === false ) ? 8 : get_option( 'mainwp_maximumSyncRequests' ), |
| 918 | 978 | 'maximumInstallUpdateRequests' => ( get_option( 'mainwp_maximumInstallUpdateRequests' ) === false ) ? 3 : get_option( 'mainwp_maximumInstallUpdateRequests' ), |
| 919 | 979 | 'maximumUptimeMonitoringRequests' => (int) get_option( 'mainwp_maximum_uptime_monitoring_requests', 10 ), |
| 980 | + 'siteRemovalTimeout' => MainWP_Connect::get_site_removal_ajax_timeout_ms(), | |
| 920 | 981 | '_wpnonce' => wp_create_nonce( 'mainwp-admin-nonce' ), |
| 921 | 982 | 'quickThemeChangeNonce' => wp_create_nonce( 'mainwp_quick_theme_change' ), |
| 922 | 983 | 'demoMode' => MainWP_Demo_Handle::is_demo_mode() ? 1 : 0, |
| 923 | 984 | 'roll_ui_icon' => MainWP_Updates_Helper::get_roll_icon( '', true ), |
| @@ -972,8 +1033,9 @@ | ||
| 972 | 1033 | remove_action( 'admin_notices', 'update_nag', 3 ); |
| 973 | 1034 | } |
| 974 | 1035 | } |
| 975 | 1036 | |
| 1037 | + | |
| 976 | 1038 | /** |
| 977 | 1039 | * Method hook_wp_shutdown() |
| 978 | 1040 | */ |
| 979 | 1041 | public function hook_wp_shutdown() { |
| @@ -1163,8 +1225,10 @@ | ||
| 1163 | 1225 | wp_enqueue_script( 'mainwp-backups', MAINWP_PLUGIN_URL . 'assets/js/mainwp-backups.js', array(), $this->current_version, true ); |
| 1164 | 1226 | wp_enqueue_script( 'mainwp-posts', MAINWP_PLUGIN_URL . 'assets/js/mainwp-posts.js', array(), $this->current_version, true ); |
| 1165 | 1227 | wp_enqueue_script( 'mainwp-users', MAINWP_PLUGIN_URL . 'assets/js/mainwp-users.js', array(), $this->current_version, true ); |
| 1166 | 1228 | wp_enqueue_script( 'mainwp-clients', MAINWP_PLUGIN_URL . 'assets/js/mainwp-clients.js', array(), $this->current_version, true ); |
| 1229 | + wp_enqueue_script( 'mainwp-knowledge', MAINWP_PLUGIN_URL . 'assets/js/mainwp-knowledge.js', array( 'jquery', 'fomantic-ui' ), $this->current_version, true ); | |
| 1230 | + wp_localize_script( 'mainwp-knowledge', 'mainwpKnowledgeStrings', MainWP_Knowledge_UI::js_strings() ); | |
| 1167 | 1231 | wp_enqueue_script( 'mainwp-extensions', MAINWP_PLUGIN_URL . 'assets/js/mainwp-extensions.js', array(), $this->current_version, true ); |
| 1168 | 1232 | wp_enqueue_script( 'moment' ); |
| 1169 | 1233 | wp_enqueue_script( 'fomantic-ui', MAINWP_PLUGIN_URL . 'assets/js/fomantic-ui/fomantic-ui.js', array( 'jquery' ), $this->current_version, false ); |
| 1170 | 1234 | |
| @@ -1175,9 +1239,10 @@ | ||
| 1175 | 1239 | |
| 1176 | 1240 | wp_enqueue_script( 'datatables-natural-sorting', MAINWP_PLUGIN_URL . 'assets/js/sorting/natural.min.js', array( 'jquery', 'datatables' ), $this->current_version, true ); |
| 1177 | 1241 | |
| 1178 | 1242 | wp_enqueue_script( 'clipboard' ); |
| 1179 | - wp_enqueue_script( 'mainwp-rest-api', MAINWP_PLUGIN_URL . 'assets/js/mainwp-rest-api.js', array(), time(), true ); | |
| 1243 | + wp_enqueue_script( 'mainwp-ai-client-setup', MAINWP_PLUGIN_URL . 'assets/js/mainwp-ai-client-setup.js', array(), $this->current_version, true ); | |
| 1244 | + wp_enqueue_script( 'mainwp-rest-api', MAINWP_PLUGIN_URL . 'assets/js/mainwp-rest-api.js', array( 'mainwp-ai-client-setup' ), time(), true ); | |
| 1180 | 1245 | |
| 1181 | 1246 | if ( isset( $_GET['page'] ) && 'ManageGroups' === $_GET['page'] ) { // phpcs:ignore WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized |
| 1182 | 1247 | wp_enqueue_script( 'mainwp-groups', MAINWP_PLUGIN_URL . 'assets/js/mainwp-groups.js', array(), $this->current_version, true ); |
| 1183 | 1248 | } |
| @@ -1268,9 +1333,9 @@ | ||
| 1268 | 1333 | * |
| 1269 | 1334 | * @return array<string, array<int, mixed>> Command palette configuration. |
| 1270 | 1335 | */ |
| 1271 | 1336 | private function get_command_palette_data() { |
| 1272 | - $registered_pages = $this->get_command_palette_registered_pages(); | |
| 1337 | + $registered_pages = $this->get_command_palette_registered_pages(); | |
| 1273 | 1338 | $registered_page_urls = array(); |
| 1274 | 1339 | |
| 1275 | 1340 | foreach ( $registered_pages as $slug => $page_data ) { |
| 1276 | 1341 | $registered_page_urls[ $slug ] = $page_data['url']; |
| @@ -1961,9 +2026,9 @@ | ||
| 1961 | 2026 | <div class="ui large modal" id="mainwp-response-data-modal"> |
| 1962 | 2027 | <i class="close icon"></i> |
| 1963 | 2028 | <div class="header"><?php esc_html_e( 'Child Site Response', 'mainwp' ); ?></div> |
| 1964 | 2029 | <div class="content"> |
| 1965 | - <div class="ui info message"><?php esc_html_e( 'To see the response in a more readable way, you can copy it and paste it into some HTML render tool, such as Codepen.io.', 'mainwp' ); ?> | |
| 2030 | + <div class="ui info message"><?php esc_html_e( 'This is the readable child/HTTP response from the failed request (status, headers snippet, and body when it is safe to show). Copy it for support if needed.', 'mainwp' ); ?> | |
| 1966 | 2031 | </div> |
| 1967 | 2032 | </div> |
| 1968 | 2033 | <div class="scrolling content content-response" contenteditable="true"></div> |
| 1969 | 2034 | <div class="actions"> |
| @@ -2070,8 +2135,9 @@ | ||
| 2070 | 2135 | * @uses \MainWP\Dashboard\MainWP_Install::install() |
| 2071 | 2136 | */ |
| 2072 | 2137 | public function update_install() { |
| 2073 | 2138 | MainWP_DB_Client::instance(); |
| 2139 | + MainWP_DB_Knowledge::instance(); | |
| 2074 | 2140 | MainWP_DB_Site_Actions::instance(); |
| 2075 | 2141 | MainWP_Install::instance()->install(); |
| 2076 | 2142 | $this->check_to_updates(); |
| 2077 | 2143 | } |
| @@ -2127,15 +2193,15 @@ | ||
| 2127 | 2193 | /** |
| 2128 | 2194 | * Method get_selected_sites_with_allowed_sites. |
| 2129 | 2195 | * |
| 2130 | 2196 | * @param array $selected_ids Selected sites IDs. |
| 2131 | - * @param array $current_sites Current sites IDs. | |
| 2197 | + * @param array $current_sites_ids Current sites IDs. | |
| 2132 | 2198 | * @return array Not selected but in not allowed sites in current sites ids, and selected sites ids. |
| 2133 | 2199 | */ |
| 2134 | 2200 | public static function get_selected_sites_with_allowed_sites( $selected_ids, $current_sites_ids = array() ) { |
| 2135 | 2201 | |
| 2136 | - $allowed_sites = apply_filters( 'mainwp_currentuserallowedaccesssites', 'all' ); | |
| 2137 | - if ( 'all' === $allowed_sites ) { | |
| 2202 | + $allowed_ids = MainWP_Abilities_Util::get_allowed_site_ids(); | |
| 2203 | + if ( 'all' === $allowed_ids ) { | |
| 2138 | 2204 | return $selected_ids; |
| 2139 | 2205 | } |
| 2140 | 2206 | |
| 2141 | 2207 | if ( ! is_array( $selected_ids ) ) { |
| @@ -2145,22 +2211,8 @@ | ||
| 2145 | 2211 | if ( ! is_array( $current_sites_ids ) ) { |
| 2146 | 2212 | $current_sites_ids = array(); |
| 2147 | 2213 | } |
| 2148 | 2214 | |
| 2149 | - $allowed_sites = MainWP_DB::instance()->get_websites_for_current_user(); | |
| 2150 | - if ( empty( $allowed_sites ) ) { | |
| 2151 | - return array(); | |
| 2152 | - } | |
| 2153 | - | |
| 2154 | - $allowed_ids = array_values( | |
| 2155 | - array_map( | |
| 2156 | - function ( $item ) { | |
| 2157 | - return $item->id; | |
| 2158 | - }, | |
| 2159 | - $allowed_sites | |
| 2160 | - ) | |
| 2161 | - ); | |
| 2162 | - | |
| 2163 | 2215 | $client_site_ids = array(); |
| 2164 | 2216 | foreach ( $selected_ids as $id ) { |
| 2165 | 2217 | if ( in_array( $id, $allowed_ids ) ) { |
| 2166 | 2218 | $client_site_ids[] = $id; |
| @@ -2166,8 +2218,9 @@ | ||
| 2166 | 2218 | $client_site_ids[] = $id; |
| 2167 | 2219 | } |
| 2168 | 2220 | } |
| 2169 | 2221 | |
| 2222 | + // Team Control cannot remove memberships outside the caller's site grants. | |
| 2170 | 2223 | foreach ( $current_sites_ids as $id ) { |
| 2171 | 2224 | if ( ! in_array( $id, $selected_ids ) && ! in_array( $id, $allowed_ids ) ) { // If it’s not in the allowed site IDs, the user is not permitted to change it. |
| 2172 | 2225 | $client_site_ids[] = $id; // keep this site ids. |
| 2173 | 2226 | } |