/var/www/hkosl.com/aga/wp-content/plugins/wordpress-seo/admin/class-yoast-network-admin.php


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
<?php
/**
 * WPSEO plugin file.
 *
 * @package WPSEO\Internals
 */

/**
 * Multisite utility class for network admin functionality.
 */
class Yoast_Network_Admin implements WPSEO_WordPress_IntegrationWPSEO_WordPress_AJAX_Integration {

    
/**
     * Action identifier for updating plugin network options.
     *
     * @var string
     */
    
const UPDATE_OPTIONS_ACTION 'yoast_handle_network_options';

    
/**
     * Action identifier for restoring a site.
     *
     * @var string
     */
    
const RESTORE_SITE_ACTION 'yoast_restore_site';

    
/**
     * Gets the available sites as choices, e.g. for a dropdown.
     *
     * @param bool $include_empty Optional. Whether to include an initial placeholder choice.
     *                            Default false.
     * @param bool $show_title    Optional. Whether to show the title for each site. This requires
     *                            switching through the sites, so has performance implications for
     *                            sites that do not use a persistent cache.
     *                            Default false.
     *
     * @return array Choices as $site_id => $site_label pairs.
     */
    
public function get_site_choices$include_empty false$show_title false ) {
        
$choices = array();

        if ( 
$include_empty ) {
            
$choices['-'] = __'None''wordpress-seo' );
        }

        
$criteria = array(
            
'deleted'    => 0,
            
'network_id' => get_current_network_id(),
        );
        
$sites    get_sites$criteria );

        foreach ( 
$sites as $site ) {
            
$site_name $site->domain $site->path;
            if ( 
$show_title ) {
                
$site_name $site->blogname ' (' $site->domain $site->path ')';
            }
            
$choices$site->blog_id ] = $site->blog_id ': ' $site_name;

            
$site_states $this->get_site_states$site );
            if ( ! empty( 
$site_states ) ) {
                
$choices$site->blog_id ] .= ' [' implode', '$site_states ) . ']';
            }
        }

        return 
$choices;
    }

    
/**
     * Gets the states of a site.
     *
     * @param WP_Site $site Site object.
     *
     * @return array Array of $state_slug => $state_label pairs.
     */
    
public function get_site_states$site ) {
        
$available_states = array(
            
'public'   => __'public''wordpress-seo' ),
            
'archived' => __'archived''wordpress-seo' ),
            
'mature'   => __'mature''wordpress-seo' ),
            
'spam'     => __'spam''wordpress-seo' ),
            
'deleted'  => __'deleted''wordpress-seo' ),
        );

        
$site_states = array();
        foreach ( 
$available_states as $state_slug => $state_label ) {
            if ( 
$site->$state_slug === '1' ) {
                
$site_states$state_slug ] = $state_label;
            }
        }

        return 
$site_states;
    }

    
/**
     * Handles a request to update plugin network options.
     *
     * This method works similar to how option updates are handled in `wp-admin/options.php` and
     * `wp-admin/network/settings.php`.
     *
     * @return void
     */
    
public function handle_update_options_request() {
        
$option_group filter_inputINPUT_POST'network_option_group'FILTER_SANITIZE_STRING );

        
$this->verify_request"{$option_group}-network-options" );

        
$whitelist_options Yoast_Network_Settings_API::get()->get_whitelist_options$option_group );

        if ( empty( 
$whitelist_options ) ) {
            
add_settings_error$option_group'settings_updated'__'You are not allowed to modify unregistered network settings.''wordpress-seo' ), 'error' );

            
$this->terminate_request();
            return;
        }

        foreach ( 
$whitelist_options as $option_name ) {
            
$value null;
            if ( isset( 
$_POST$option_name ] ) ) { // WPCS: CSRF ok.
                // Adding sanitize_text_field around this will break the saving of settings because it expects a string: https://github.com/Yoast/wordpress-seo/issues/12440.
                
$value wp_unslash$_POST$option_name ] ); // WPCS: CSRF ok.
            
}

            
WPSEO_Options::update_site_option$option_name$value );
        }

        
$settings_errors get_settings_errors();
        if ( empty( 
$settings_errors ) ) {
            
add_settings_error$option_group'settings_updated'__'Settings Updated.''wordpress-seo' ), 'updated' );
        }

        
$this->terminate_request();
    }

    
/**
     * Handles a request to restore a site's default settings.
     *
     * @return void
     */
    
public function handle_restore_site_request() {
        
$this->verify_request'wpseo-network-restore''restore_site_nonce' );

        
$option_group 'wpseo_ms';

        
$site_id = ! empty( $_POST$option_group ]['site_id'] ) ? (int) $_POST$option_group ]['site_id'] : 0// WPCS: CSRF ok.
        
if ( ! $site_id ) {
            
add_settings_error$option_group'settings_updated'__'No site has been selected to restore.''wordpress-seo' ), 'error' );

            
$this->terminate_request();
            return;
        }

        
$site get_site$site_id );
        if ( ! 
$site ) {
            
/* translators: %s expands to the ID of a site within a multisite network. */
            
add_settings_error$option_group'settings_updated'sprintf__'Site with ID %d not found.''wordpress-seo' ), $site_id ), 'error' );
        }
        else {
            
WPSEO_Options::reset_ms_blog$site_id );

            
/* translators: %s expands to the name of a site within a multisite network. */
            
add_settings_error$option_group'settings_updated'sprintf__'%s restored to default SEO settings.''wordpress-seo' ), esc_html$site->blogname ) ), 'updated' );
        }

        
$this->terminate_request();
    }

    
/**
     * Outputs nonce, action and option group fields for a network settings page in the plugin.
     *
     * @param string $option_group Option group name for the current page.
     *
     * @return void
     */
    
public function settings_fields$option_group ) {
        
?>
        <input type="hidden" name="network_option_group" value="<?php echo esc_attr$option_group ); ?>" />
        <input type="hidden" name="action" value="<?php echo esc_attrself::UPDATE_OPTIONS_ACTION ); ?>" />
        <?php
        wp_nonce_field
"$option_group-network-options" );
    }

    
/**
     * Enqueues network admin assets.
     *
     * @return void
     */
    
public function enqueue_assets() {
        
$asset_manager = new WPSEO_Admin_Asset_Manager();
        
$asset_manager->enqueue_script'network-admin-script' );

        
$translations = array(
            
/* translators: %s: success message */
            
'success_prefix' => __'Success: %s''wordpress-seo' ),
            
/* translators: %s: error message */
            
'error_prefix'   => __'Error: %s''wordpress-seo' ),
        );
        
wp_localize_script(
            
WPSEO_Admin_Asset_Manager::PREFIX 'network-admin-script',
            
'wpseoNetworkAdminGlobalL10n',
            
$translations
        
);
    }

    
/**
     * Hooks in the necessary actions and filters.
     *
     * @return void
     */
    
public function register_hooks() {

        if ( ! 
$this->meets_requirements() ) {
            return;
        }

        
add_action'admin_enqueue_scripts', array( $this'enqueue_assets' ) );

        
add_action'admin_action_' self::UPDATE_OPTIONS_ACTION, array( $this'handle_update_options_request' ) );
        
add_action'admin_action_' self::RESTORE_SITE_ACTION, array( $this'handle_restore_site_request' ) );
    }

    
/**
     * Hooks in the necessary AJAX actions.
     *
     * @return void
     */
    
public function register_ajax_hooks() {
        
add_action'wp_ajax_' self::UPDATE_OPTIONS_ACTION, array( $this'handle_update_options_request' ) );
        
add_action'wp_ajax_' self::RESTORE_SITE_ACTION, array( $this'handle_restore_site_request' ) );
    }

    
/**
     * Checks whether the requirements to use this class are met.
     *
     * @return bool True if requirements are met, false otherwise.
     */
    
public function meets_requirements() {
        return 
is_multisite() && is_network_admin();
    }

    
/**
     * Verifies that the current request is valid.
     *
     * @param string $action    Nonce action.
     * @param string $query_arg Optional. Nonce query argument. Default '_wpnonce'.
     *
     * @return void
     */
    
public function verify_request$action$query_arg '_wpnonce' ) {
        
$has_access current_user_can'wpseo_manage_network_options' );

        if ( 
wp_doing_ajax() ) {
            
check_ajax_referer$action$query_arg );

            if ( ! 
$has_access ) {
                
wp_die( -1403 );
            }
            return;
        }

        
check_admin_referer$action$query_arg );

        if ( ! 
$has_access ) {
            
wp_dieesc_html__'You are not allowed to perform this action.''wordpress-seo' ) );
        }
    }

    
/**
     * Terminates the current request by either redirecting back or sending an AJAX response.
     *
     * @return void
     */
    
public function terminate_request() {
        if ( 
wp_doing_ajax() ) {
            
$settings_errors get_settings_errors();

            if ( ! empty( 
$settings_errors ) && $settings_errors[0]['type'] === 'updated' ) {
                
wp_send_json_success$settings_errors200 );
            }

            
wp_send_json_error$settings_errors400 );
        }

        
$this->persist_settings_errors();
        
$this->redirect_back( array( 'settings-updated' => 'true' ) );
    }

    
/**
     * Persists settings errors.
     *
     * Settings errors are stored in a transient for 30 seconds so that this transient
     * can be retrieved on the next page load.
     *
     * @return void
     */
    
protected function persist_settings_errors() {
        
/*
         * A regular transient is used here, since it is automatically cleared right after the redirect.
         * A network transient would be cleaner, but would require a lot of copied code from core for
         * just a minor adjustment when displaying settings errors.
         */
        
set_transient'settings_errors'get_settings_errors(), 30 );
    }

    
/**
     * Redirects back to the referer URL, with optional query arguments.
     *
     * @param array $query_args Optional. Query arguments to add to the redirect URL. Default none.
     *
     * @return void
     */
    
protected function redirect_back$query_args = array() ) {
        
$sendback wp_get_referer();

        if ( ! empty( 
$query_args ) ) {
            
$sendback add_query_arg$query_args$sendback );
        }

        
wp_safe_redirect$sendback );
        exit;
    }
}