[ Index ]

PHP Cross Reference of WordPress

title

Body

[close]

/wp-admin/includes/ -> ms.php (source)

   1  <?php
   2  /**
   3   * Multisite administration functions.
   4   *
   5   * @package WordPress
   6   * @subpackage Multisite
   7   * @since 3.0.0
   8   */
   9  
  10  /**
  11   * Determine if uploaded file exceeds space quota.
  12   *
  13   * @since 3.0.0
  14   *
  15   * @param array $file $_FILES array for a given file.
  16   * @return array $_FILES array with 'error' key set if file exceeds quota. 'error' is empty otherwise.
  17   */
  18  function check_upload_size( $file ) {
  19      if ( get_site_option( 'upload_space_check_disabled' ) ) {
  20          return $file;
  21      }
  22  
  23      if ( $file['error'] != '0' ) { // there's already an error
  24          return $file;
  25      }
  26  
  27      if ( defined( 'WP_IMPORTING' ) ) {
  28          return $file;
  29      }
  30  
  31      $space_left = get_upload_space_available();
  32  
  33      $file_size = filesize( $file['tmp_name'] );
  34      if ( $space_left < $file_size ) {
  35          /* translators: %s: Required disk space in kilobytes. */
  36          $file['error'] = sprintf( __( 'Not enough space to upload. %s KB needed.' ), number_format( ( $file_size - $space_left ) / KB_IN_BYTES ) );
  37      }
  38  
  39      if ( $file_size > ( KB_IN_BYTES * get_site_option( 'fileupload_maxk', 1500 ) ) ) {
  40          /* translators: %s: Maximum allowed file size in kilobytes. */
  41          $file['error'] = sprintf( __( 'This file is too big. Files must be less than %s KB in size.' ), get_site_option( 'fileupload_maxk', 1500 ) );
  42      }
  43  
  44      if ( upload_is_user_over_quota( false ) ) {
  45          $file['error'] = __( 'You have used your space quota. Please delete files before uploading.' );
  46      }
  47  
  48      if ( $file['error'] != '0' && ! isset( $_POST['html-upload'] ) && ! wp_doing_ajax() ) {
  49          wp_die( $file['error'] . ' <a href="javascript:history.go(-1)">' . __( 'Back' ) . '</a>' );
  50      }
  51  
  52      return $file;
  53  }
  54  
  55  /**
  56   * Delete a site.
  57   *
  58   * @since 3.0.0
  59   * @since 5.1.0 Use wp_delete_site() internally to delete the site row from the database.
  60   *
  61   * @global wpdb $wpdb WordPress database abstraction object.
  62   *
  63   * @param int  $blog_id Site ID.
  64   * @param bool $drop    True if site's database tables should be dropped. Default is false.
  65   */
  66  function wpmu_delete_blog( $blog_id, $drop = false ) {
  67      global $wpdb;
  68  
  69      $switch = false;
  70      if ( get_current_blog_id() != $blog_id ) {
  71          $switch = true;
  72          switch_to_blog( $blog_id );
  73      }
  74  
  75      $blog = get_site( $blog_id );
  76  
  77      $current_network = get_network();
  78  
  79      // If a full blog object is not available, do not destroy anything.
  80      if ( $drop && ! $blog ) {
  81          $drop = false;
  82      }
  83  
  84      // Don't destroy the initial, main, or root blog.
  85      if ( $drop && ( 1 == $blog_id || is_main_site( $blog_id ) || ( $blog->path == $current_network->path && $blog->domain == $current_network->domain ) ) ) {
  86          $drop = false;
  87      }
  88  
  89      $upload_path = trim( get_option( 'upload_path' ) );
  90  
  91      // If ms_files_rewriting is enabled and upload_path is empty, wp_upload_dir is not reliable.
  92      if ( $drop && get_site_option( 'ms_files_rewriting' ) && empty( $upload_path ) ) {
  93          $drop = false;
  94      }
  95  
  96      if ( $drop ) {
  97          wp_delete_site( $blog_id );
  98      } else {
  99          /** This action is documented in wp-includes/ms-blogs.php */
 100          do_action_deprecated( 'delete_blog', array( $blog_id, false ), '5.1.0' );
 101  
 102          $users = get_users(
 103              array(
 104                  'blog_id' => $blog_id,
 105                  'fields'  => 'ids',
 106              )
 107          );
 108  
 109          // Remove users from this blog.
 110          if ( ! empty( $users ) ) {
 111              foreach ( $users as $user_id ) {
 112                  remove_user_from_blog( $user_id, $blog_id );
 113              }
 114          }
 115  
 116          update_blog_status( $blog_id, 'deleted', 1 );
 117  
 118          /** This action is documented in wp-includes/ms-blogs.php */
 119          do_action_deprecated( 'deleted_blog', array( $blog_id, false ), '5.1.0' );
 120      }
 121  
 122      if ( $switch ) {
 123          restore_current_blog();
 124      }
 125  }
 126  
 127  /**
 128   * Delete a user from the network and remove from all sites.
 129   *
 130   * @since 3.0.0
 131   *
 132   * @todo Merge with wp_delete_user() ?
 133   *
 134   * @global wpdb $wpdb WordPress database abstraction object.
 135   *
 136   * @param int $id The user ID.
 137   * @return bool True if the user was deleted, otherwise false.
 138   */
 139  function wpmu_delete_user( $id ) {
 140      global $wpdb;
 141  
 142      if ( ! is_numeric( $id ) ) {
 143          return false;
 144      }
 145  
 146      $id   = (int) $id;
 147      $user = new WP_User( $id );
 148  
 149      if ( ! $user->exists() ) {
 150          return false;
 151      }
 152  
 153      // Global super-administrators are protected, and cannot be deleted.
 154      $_super_admins = get_super_admins();
 155      if ( in_array( $user->user_login, $_super_admins, true ) ) {
 156          return false;
 157      }
 158  
 159      /**
 160       * Fires before a user is deleted from the network.
 161       *
 162       * @since MU (3.0.0)
 163       *
 164       * @param int $id ID of the user about to be deleted from the network.
 165       */
 166      do_action( 'wpmu_delete_user', $id );
 167  
 168      $blogs = get_blogs_of_user( $id );
 169  
 170      if ( ! empty( $blogs ) ) {
 171          foreach ( $blogs as $blog ) {
 172              switch_to_blog( $blog->userblog_id );
 173              remove_user_from_blog( $id, $blog->userblog_id );
 174  
 175              $post_ids = $wpdb->get_col( $wpdb->prepare( "SELECT ID FROM $wpdb->posts WHERE post_author = %d", $id ) );
 176              foreach ( (array) $post_ids as $post_id ) {
 177                  wp_delete_post( $post_id );
 178              }
 179  
 180              // Clean links
 181              $link_ids = $wpdb->get_col( $wpdb->prepare( "SELECT link_id FROM $wpdb->links WHERE link_owner = %d", $id ) );
 182  
 183              if ( $link_ids ) {
 184                  foreach ( $link_ids as $link_id ) {
 185                      wp_delete_link( $link_id );
 186                  }
 187              }
 188  
 189              restore_current_blog();
 190          }
 191      }
 192  
 193      $meta = $wpdb->get_col( $wpdb->prepare( "SELECT umeta_id FROM $wpdb->usermeta WHERE user_id = %d", $id ) );
 194      foreach ( $meta as $mid ) {
 195          delete_metadata_by_mid( 'user', $mid );
 196      }
 197  
 198      $wpdb->delete( $wpdb->users, array( 'ID' => $id ) );
 199  
 200      clean_user_cache( $user );
 201  
 202      /** This action is documented in wp-admin/includes/user.php */
 203      do_action( 'deleted_user', $id, null );
 204  
 205      return true;
 206  }
 207  
 208  /**
 209   * Check whether a site has used its allotted upload space.
 210   *
 211   * @since MU (3.0.0)
 212   *
 213   * @param bool $echo Optional. If $echo is set and the quota is exceeded, a warning message is echoed. Default is true.
 214   * @return bool True if user is over upload space quota, otherwise false.
 215   */
 216  function upload_is_user_over_quota( $echo = true ) {
 217      if ( get_site_option( 'upload_space_check_disabled' ) ) {
 218          return false;
 219      }
 220  
 221      $space_allowed = get_space_allowed();
 222      if ( ! is_numeric( $space_allowed ) ) {
 223          $space_allowed = 10; // Default space allowed is 10 MB
 224      }
 225      $space_used = get_space_used();
 226  
 227      if ( ( $space_allowed - $space_used ) < 0 ) {
 228          if ( $echo ) {
 229              printf(
 230                  /* translators: %s: Allowed space allocation. */
 231                  __( 'Sorry, you have used your space allocation of %s. Please delete some files to upload more files.' ),
 232                  size_format( $space_allowed * MB_IN_BYTES )
 233              );
 234          }
 235          return true;
 236      } else {
 237          return false;
 238      }
 239  }
 240  
 241  /**
 242   * Displays the amount of disk space used by the current site. Not used in core.
 243   *
 244   * @since MU (3.0.0)
 245   */
 246  function display_space_usage() {
 247      $space_allowed = get_space_allowed();
 248      $space_used    = get_space_used();
 249  
 250      $percent_used = ( $space_used / $space_allowed ) * 100;
 251  
 252      $space = size_format( $space_allowed * MB_IN_BYTES );
 253      ?>
 254      <strong>
 255      <?php
 256          /* translators: Storage space that's been used. 1: Percentage of used space, 2: Total space allowed in megabytes or gigabytes. */
 257          printf( __( 'Used: %1$s%% of %2$s' ), number_format( $percent_used ), $space );
 258      ?>
 259      </strong>
 260      <?php
 261  }
 262  
 263  /**
 264   * Get the remaining upload space for this site.
 265   *
 266   * @since MU (3.0.0)
 267   *
 268   * @param int $size Current max size in bytes
 269   * @return int Max size in bytes
 270   */
 271  function fix_import_form_size( $size ) {
 272      if ( upload_is_user_over_quota( false ) ) {
 273          return 0;
 274      }
 275      $available = get_upload_space_available();
 276      return min( $size, $available );
 277  }
 278  
 279  /**
 280   * Displays the site upload space quota setting form on the Edit Site Settings screen.
 281   *
 282   * @since 3.0.0
 283   *
 284   * @param int $id The ID of the site to display the setting for.
 285   */
 286  function upload_space_setting( $id ) {
 287      switch_to_blog( $id );
 288      $quota = get_option( 'blog_upload_space' );
 289      restore_current_blog();
 290  
 291      if ( ! $quota ) {
 292          $quota = '';
 293      }
 294  
 295      ?>
 296      <tr>
 297          <th><label for="blog-upload-space-number"><?php _e( 'Site Upload Space Quota' ); ?></label></th>
 298          <td>
 299              <input type="number" step="1" min="0" style="width: 100px" name="option[blog_upload_space]" id="blog-upload-space-number" aria-describedby="blog-upload-space-desc" value="<?php echo $quota; ?>" />
 300              <span id="blog-upload-space-desc"><span class="screen-reader-text"><?php _e( 'Size in megabytes' ); ?></span> <?php _e( 'MB (Leave blank for network default)' ); ?></span>
 301          </td>
 302      </tr>
 303      <?php
 304  }
 305  
 306  /**
 307   * Cleans the user cache for a specific user.
 308   *
 309   * @since 3.0.0
 310   *
 311   * @param int $id The user ID.
 312   * @return bool|int The ID of the refreshed user or false if the user does not exist.
 313   */
 314  function refresh_user_details( $id ) {
 315      $id = (int) $id;
 316  
 317      $user = get_userdata( $id );
 318      if ( ! $user ) {
 319          return false;
 320      }
 321  
 322      clean_user_cache( $user );
 323  
 324      return $id;
 325  }
 326  
 327  /**
 328   * Returns the language for a language code.
 329   *
 330   * @since 3.0.0
 331   *
 332   * @param string $code Optional. The two-letter language code. Default empty.
 333   * @return string The language corresponding to $code if it exists. If it does not exist,
 334   *                then the first two letters of $code is returned.
 335   */
 336  function format_code_lang( $code = '' ) {
 337      $code       = strtolower( substr( $code, 0, 2 ) );
 338      $lang_codes = array(
 339          'aa' => 'Afar',
 340          'ab' => 'Abkhazian',
 341          'af' => 'Afrikaans',
 342          'ak' => 'Akan',
 343          'sq' => 'Albanian',
 344          'am' => 'Amharic',
 345          'ar' => 'Arabic',
 346          'an' => 'Aragonese',
 347          'hy' => 'Armenian',
 348          'as' => 'Assamese',
 349          'av' => 'Avaric',
 350          'ae' => 'Avestan',
 351          'ay' => 'Aymara',
 352          'az' => 'Azerbaijani',
 353          'ba' => 'Bashkir',
 354          'bm' => 'Bambara',
 355          'eu' => 'Basque',
 356          'be' => 'Belarusian',
 357          'bn' => 'Bengali',
 358          'bh' => 'Bihari',
 359          'bi' => 'Bislama',
 360          'bs' => 'Bosnian',
 361          'br' => 'Breton',
 362          'bg' => 'Bulgarian',
 363          'my' => 'Burmese',
 364          'ca' => 'Catalan; Valencian',
 365          'ch' => 'Chamorro',
 366          'ce' => 'Chechen',
 367          'zh' => 'Chinese',
 368          'cu' => 'Church Slavic; Old Slavonic; Church Slavonic; Old Bulgarian; Old Church Slavonic',
 369          'cv' => 'Chuvash',
 370          'kw' => 'Cornish',
 371          'co' => 'Corsican',
 372          'cr' => 'Cree',
 373          'cs' => 'Czech',
 374          'da' => 'Danish',
 375          'dv' => 'Divehi; Dhivehi; Maldivian',
 376          'nl' => 'Dutch; Flemish',
 377          'dz' => 'Dzongkha',
 378          'en' => 'English',
 379          'eo' => 'Esperanto',
 380          'et' => 'Estonian',
 381          'ee' => 'Ewe',
 382          'fo' => 'Faroese',
 383          'fj' => 'Fijjian',
 384          'fi' => 'Finnish',
 385          'fr' => 'French',
 386          'fy' => 'Western Frisian',
 387          'ff' => 'Fulah',
 388          'ka' => 'Georgian',
 389          'de' => 'German',
 390          'gd' => 'Gaelic; Scottish Gaelic',
 391          'ga' => 'Irish',
 392          'gl' => 'Galician',
 393          'gv' => 'Manx',
 394          'el' => 'Greek, Modern',
 395          'gn' => 'Guarani',
 396          'gu' => 'Gujarati',
 397          'ht' => 'Haitian; Haitian Creole',
 398          'ha' => 'Hausa',
 399          'he' => 'Hebrew',
 400          'hz' => 'Herero',
 401          'hi' => 'Hindi',
 402          'ho' => 'Hiri Motu',
 403          'hu' => 'Hungarian',
 404          'ig' => 'Igbo',
 405          'is' => 'Icelandic',
 406          'io' => 'Ido',
 407          'ii' => 'Sichuan Yi',
 408          'iu' => 'Inuktitut',
 409          'ie' => 'Interlingue',
 410          'ia' => 'Interlingua (International Auxiliary Language Association)',
 411          'id' => 'Indonesian',
 412          'ik' => 'Inupiaq',
 413          'it' => 'Italian',
 414          'jv' => 'Javanese',
 415          'ja' => 'Japanese',
 416          'kl' => 'Kalaallisut; Greenlandic',
 417          'kn' => 'Kannada',
 418          'ks' => 'Kashmiri',
 419          'kr' => 'Kanuri',
 420          'kk' => 'Kazakh',
 421          'km' => 'Central Khmer',
 422          'ki' => 'Kikuyu; Gikuyu',
 423          'rw' => 'Kinyarwanda',
 424          'ky' => 'Kirghiz; Kyrgyz',
 425          'kv' => 'Komi',
 426          'kg' => 'Kongo',
 427          'ko' => 'Korean',
 428          'kj' => 'Kuanyama; Kwanyama',
 429          'ku' => 'Kurdish',
 430          'lo' => 'Lao',
 431          'la' => 'Latin',
 432          'lv' => 'Latvian',
 433          'li' => 'Limburgan; Limburger; Limburgish',
 434          'ln' => 'Lingala',
 435          'lt' => 'Lithuanian',
 436          'lb' => 'Luxembourgish; Letzeburgesch',
 437          'lu' => 'Luba-Katanga',
 438          'lg' => 'Ganda',
 439          'mk' => 'Macedonian',
 440          'mh' => 'Marshallese',
 441          'ml' => 'Malayalam',
 442          'mi' => 'Maori',
 443          'mr' => 'Marathi',
 444          'ms' => 'Malay',
 445          'mg' => 'Malagasy',
 446          'mt' => 'Maltese',
 447          'mo' => 'Moldavian',
 448          'mn' => 'Mongolian',
 449          'na' => 'Nauru',
 450          'nv' => 'Navajo; Navaho',
 451          'nr' => 'Ndebele, South; South Ndebele',
 452          'nd' => 'Ndebele, North; North Ndebele',
 453          'ng' => 'Ndonga',
 454          'ne' => 'Nepali',
 455          'nn' => 'Norwegian Nynorsk; Nynorsk, Norwegian',
 456          'nb' => 'Bokmål, Norwegian, Norwegian Bokmål',
 457          'no' => 'Norwegian',
 458          'ny' => 'Chichewa; Chewa; Nyanja',
 459          'oc' => 'Occitan, Provençal',
 460          'oj' => 'Ojibwa',
 461          'or' => 'Oriya',
 462          'om' => 'Oromo',
 463          'os' => 'Ossetian; Ossetic',
 464          'pa' => 'Panjabi; Punjabi',
 465          'fa' => 'Persian',
 466          'pi' => 'Pali',
 467          'pl' => 'Polish',
 468          'pt' => 'Portuguese',
 469          'ps' => 'Pushto',
 470          'qu' => 'Quechua',
 471          'rm' => 'Romansh',
 472          'ro' => 'Romanian',
 473          'rn' => 'Rundi',
 474          'ru' => 'Russian',
 475          'sg' => 'Sango',
 476          'sa' => 'Sanskrit',
 477          'sr' => 'Serbian',
 478          'hr' => 'Croatian',
 479          'si' => 'Sinhala; Sinhalese',
 480          'sk' => 'Slovak',
 481          'sl' => 'Slovenian',
 482          'se' => 'Northern Sami',
 483          'sm' => 'Samoan',
 484          'sn' => 'Shona',
 485          'sd' => 'Sindhi',
 486          'so' => 'Somali',
 487          'st' => 'Sotho, Southern',
 488          'es' => 'Spanish; Castilian',
 489          'sc' => 'Sardinian',
 490          'ss' => 'Swati',
 491          'su' => 'Sundanese',
 492          'sw' => 'Swahili',
 493          'sv' => 'Swedish',
 494          'ty' => 'Tahitian',
 495          'ta' => 'Tamil',
 496          'tt' => 'Tatar',
 497          'te' => 'Telugu',
 498          'tg' => 'Tajik',
 499          'tl' => 'Tagalog',
 500          'th' => 'Thai',
 501          'bo' => 'Tibetan',
 502          'ti' => 'Tigrinya',
 503          'to' => 'Tonga (Tonga Islands)',
 504          'tn' => 'Tswana',
 505          'ts' => 'Tsonga',
 506          'tk' => 'Turkmen',
 507          'tr' => 'Turkish',
 508          'tw' => 'Twi',
 509          'ug' => 'Uighur; Uyghur',
 510          'uk' => 'Ukrainian',
 511          'ur' => 'Urdu',
 512          'uz' => 'Uzbek',
 513          've' => 'Venda',
 514          'vi' => 'Vietnamese',
 515          'vo' => 'Volapük',
 516          'cy' => 'Welsh',
 517          'wa' => 'Walloon',
 518          'wo' => 'Wolof',
 519          'xh' => 'Xhosa',
 520          'yi' => 'Yiddish',
 521          'yo' => 'Yoruba',
 522          'za' => 'Zhuang; Chuang',
 523          'zu' => 'Zulu',
 524      );
 525  
 526      /**
 527       * Filters the language codes.
 528       *
 529       * @since MU (3.0.0)
 530       *
 531       * @param string[] $lang_codes Array of key/value pairs of language codes where key is the short version.
 532       * @param string   $code       A two-letter designation of the language.
 533       */
 534      $lang_codes = apply_filters( 'lang_codes', $lang_codes, $code );
 535      return strtr( $code, $lang_codes );
 536  }
 537  
 538  /**
 539   * Synchronizes category and post tag slugs when global terms are enabled.
 540   *
 541   * @since 3.0.0
 542   *
 543   * @param WP_Term|array $term     The term.
 544   * @param string        $taxonomy The taxonomy for `$term`. Should be 'category' or 'post_tag', as these are
 545   *                                the only taxonomies which are processed by this function; anything else
 546   *                                will be returned untouched.
 547   * @return WP_Term|array Returns `$term`, after filtering the 'slug' field with `sanitize_title()`
 548   *                       if `$taxonomy` is 'category' or 'post_tag'.
 549   */
 550  function sync_category_tag_slugs( $term, $taxonomy ) {
 551      if ( global_terms_enabled() && ( $taxonomy == 'category' || $taxonomy == 'post_tag' ) ) {
 552          if ( is_object( $term ) ) {
 553              $term->slug = sanitize_title( $term->name );
 554          } else {
 555              $term['slug'] = sanitize_title( $term['name'] );
 556          }
 557      }
 558      return $term;
 559  }
 560  
 561  /**
 562   * Displays an access denied message when a user tries to view a site's dashboard they
 563   * do not have access to.
 564   *
 565   * @since 3.2.0
 566   * @access private
 567   */
 568  function _access_denied_splash() {
 569      if ( ! is_user_logged_in() || is_network_admin() ) {
 570          return;
 571      }
 572  
 573      $blogs = get_blogs_of_user( get_current_user_id() );
 574  
 575      if ( wp_list_filter( $blogs, array( 'userblog_id' => get_current_blog_id() ) ) ) {
 576          return;
 577      }
 578  
 579      $blog_name = get_bloginfo( 'name' );
 580  
 581      if ( empty( $blogs ) ) {
 582          wp_die(
 583              sprintf(
 584                  /* translators: 1: Site title. */
 585                  __( 'You attempted to access the "%1$s" dashboard, but you do not currently have privileges on this site. If you believe you should be able to access the "%1$s" dashboard, please contact your network administrator.' ),
 586                  $blog_name
 587              ),
 588              403
 589          );
 590      }
 591  
 592      $output = '<p>' . sprintf(
 593          /* translators: 1: Site title. */
 594          __( 'You attempted to access the "%1$s" dashboard, but you do not currently have privileges on this site. If you believe you should be able to access the "%1$s" dashboard, please contact your network administrator.' ),
 595          $blog_name
 596      ) . '</p>';
 597      $output .= '<p>' . __( 'If you reached this screen by accident and meant to visit one of your own sites, here are some shortcuts to help you find your way.' ) . '</p>';
 598  
 599      $output .= '<h3>' . __( 'Your Sites' ) . '</h3>';
 600      $output .= '<table>';
 601  
 602      foreach ( $blogs as $blog ) {
 603          $output .= '<tr>';
 604          $output .= "<td>{$blog->blogname}</td>";
 605          $output .= '<td><a href="' . esc_url( get_admin_url( $blog->userblog_id ) ) . '">' . __( 'Visit Dashboard' ) . '</a> | ' .
 606              '<a href="' . esc_url( get_home_url( $blog->userblog_id ) ) . '">' . __( 'View Site' ) . '</a></td>';
 607          $output .= '</tr>';
 608      }
 609  
 610      $output .= '</table>';
 611  
 612      wp_die( $output, 403 );
 613  }
 614  
 615  /**
 616   * Checks if the current user has permissions to import new users.
 617   *
 618   * @since 3.0.0
 619   *
 620   * @param string $permission A permission to be checked. Currently not used.
 621   * @return bool True if the user has proper permissions, false if they do not.
 622   */
 623  function check_import_new_users( $permission ) {
 624      if ( ! current_user_can( 'manage_network_users' ) ) {
 625          return false;
 626      }
 627  
 628      return true;
 629  }
 630  // See "import_allow_fetch_attachments" and "import_attachment_size_limit" filters too.
 631  
 632  /**
 633   * Generates and displays a drop-down of available languages.
 634   *
 635   * @since 3.0.0
 636   *
 637   * @param string[] $lang_files Optional. An array of the language files. Default empty array.
 638   * @param string   $current    Optional. The current language code. Default empty.
 639   */
 640  function mu_dropdown_languages( $lang_files = array(), $current = '' ) {
 641      $flag   = false;
 642      $output = array();
 643  
 644      foreach ( (array) $lang_files as $val ) {
 645          $code_lang = basename( $val, '.mo' );
 646  
 647          if ( $code_lang == 'en_US' ) { // American English
 648              $flag          = true;
 649              $ae            = __( 'American English' );
 650              $output[ $ae ] = '<option value="' . esc_attr( $code_lang ) . '"' . selected( $current, $code_lang, false ) . '> ' . $ae . '</option>';
 651          } elseif ( $code_lang == 'en_GB' ) { // British English
 652              $flag          = true;
 653              $be            = __( 'British English' );
 654              $output[ $be ] = '<option value="' . esc_attr( $code_lang ) . '"' . selected( $current, $code_lang, false ) . '> ' . $be . '</option>';
 655          } else {
 656              $translated            = format_code_lang( $code_lang );
 657              $output[ $translated ] = '<option value="' . esc_attr( $code_lang ) . '"' . selected( $current, $code_lang, false ) . '> ' . esc_html( $translated ) . '</option>';
 658          }
 659      }
 660  
 661      if ( $flag === false ) { // WordPress english
 662          $output[] = '<option value=""' . selected( $current, '', false ) . '>' . __( 'English' ) . '</option>';
 663      }
 664  
 665      // Order by name
 666      uksort( $output, 'strnatcasecmp' );
 667  
 668      /**
 669       * Filters the languages available in the dropdown.
 670       *
 671       * @since MU (3.0.0)
 672       *
 673       * @param string[] $output     Array of HTML output for the dropdown.
 674       * @param string[] $lang_files Array of available language files.
 675       * @param string   $current    The current language code.
 676       */
 677      $output = apply_filters( 'mu_dropdown_languages', $output, $lang_files, $current );
 678  
 679      echo implode( "\n\t", $output );
 680  }
 681  
 682  /**
 683   * Displays an admin notice to upgrade all sites after a core upgrade.
 684   *
 685   * @since 3.0.0
 686   *
 687   * @global int    $wp_db_version WordPress database version.
 688   * @global string $pagenow
 689   *
 690   * @return false False if the current user is not a super admin.
 691   */
 692  function site_admin_notice() {
 693      global $wp_db_version, $pagenow;
 694  
 695      if ( ! current_user_can( 'upgrade_network' ) ) {
 696          return false;
 697      }
 698  
 699      if ( 'upgrade.php' == $pagenow ) {
 700          return;
 701      }
 702  
 703      if ( get_site_option( 'wpmu_upgrade_site' ) != $wp_db_version ) {
 704          echo "<div class='update-nag'>" . sprintf(
 705              /* translators: %s: URL to Upgrade Network screen. */
 706              __( 'Thank you for Updating! Please visit the <a href="%s">Upgrade Network</a> page to update all your sites.' ),
 707              esc_url( network_admin_url( 'upgrade.php' ) )
 708          ) . '</div>';
 709      }
 710  }
 711  
 712  /**
 713   * Avoids a collision between a site slug and a permalink slug.
 714   *
 715   * In a subdirectory installation this will make sure that a site and a post do not use the
 716   * same subdirectory by checking for a site with the same name as a new post.
 717   *
 718   * @since 3.0.0
 719   *
 720   * @param array $data    An array of post data.
 721   * @param array $postarr An array of posts. Not currently used.
 722   * @return array The new array of post data after checking for collisions.
 723   */
 724  function avoid_blog_page_permalink_collision( $data, $postarr ) {
 725      if ( is_subdomain_install() ) {
 726          return $data;
 727      }
 728      if ( $data['post_type'] != 'page' ) {
 729          return $data;
 730      }
 731      if ( ! isset( $data['post_name'] ) || $data['post_name'] == '' ) {
 732          return $data;
 733      }
 734      if ( ! is_main_site() ) {
 735          return $data;
 736      }
 737  
 738      $post_name = $data['post_name'];
 739      $c         = 0;
 740      while ( $c < 10 && get_id_from_blogname( $post_name ) ) {
 741          $post_name .= mt_rand( 1, 10 );
 742          $c ++;
 743      }
 744      if ( $post_name != $data['post_name'] ) {
 745          $data['post_name'] = $post_name;
 746      }
 747      return $data;
 748  }
 749  
 750  /**
 751   * Handles the display of choosing a user's primary site.
 752   *
 753   * This displays the user's primary site and allows the user to choose
 754   * which site is primary.
 755   *
 756   * @since 3.0.0
 757   */
 758  function choose_primary_blog() {
 759      ?>
 760      <table class="form-table" role="presentation">
 761      <tr>
 762      <?php /* translators: My Sites label. */ ?>
 763          <th scope="row"><label for="primary_blog"><?php _e( 'Primary Site' ); ?></label></th>
 764          <td>
 765          <?php
 766          $all_blogs    = get_blogs_of_user( get_current_user_id() );
 767          $primary_blog = get_user_meta( get_current_user_id(), 'primary_blog', true );
 768          if ( count( $all_blogs ) > 1 ) {
 769              $found = false;
 770              ?>
 771              <select name="primary_blog" id="primary_blog">
 772                  <?php
 773                  foreach ( (array) $all_blogs as $blog ) {
 774                      if ( $primary_blog == $blog->userblog_id ) {
 775                          $found = true;
 776                      }
 777                      ?>
 778                      <option value="<?php echo $blog->userblog_id; ?>"<?php selected( $primary_blog, $blog->userblog_id ); ?>><?php echo esc_url( get_home_url( $blog->userblog_id ) ); ?></option>
 779                      <?php
 780                  }
 781                  ?>
 782              </select>
 783              <?php
 784              if ( ! $found ) {
 785                  $blog = reset( $all_blogs );
 786                  update_user_meta( get_current_user_id(), 'primary_blog', $blog->userblog_id );
 787              }
 788          } elseif ( count( $all_blogs ) == 1 ) {
 789              $blog = reset( $all_blogs );
 790              echo esc_url( get_home_url( $blog->userblog_id ) );
 791              if ( $primary_blog != $blog->userblog_id ) { // Set the primary blog again if it's out of sync with blog list.
 792                  update_user_meta( get_current_user_id(), 'primary_blog', $blog->userblog_id );
 793              }
 794          } else {
 795              echo 'N/A';
 796          }
 797          ?>
 798          </td>
 799      </tr>
 800      </table>
 801      <?php
 802  }
 803  
 804  /**
 805   * Whether or not we can edit this network from this page.
 806   *
 807   * By default editing of network is restricted to the Network Admin for that `$network_id`.
 808   * This function allows for this to be overridden.
 809   *
 810   * @since 3.1.0
 811   *
 812   * @param int $network_id The network ID to check.
 813   * @return bool True if network can be edited, otherwise false.
 814   */
 815  function can_edit_network( $network_id ) {
 816      if ( $network_id == get_current_network_id() ) {
 817          $result = true;
 818      } else {
 819          $result = false;
 820      }
 821  
 822      /**
 823       * Filters whether this network can be edited from this page.
 824       *
 825       * @since 3.1.0
 826       *
 827       * @param bool $result     Whether the network can be edited from this page.
 828       * @param int  $network_id The network ID to check.
 829       */
 830      return apply_filters( 'can_edit_network', $result, $network_id );
 831  }
 832  
 833  /**
 834   * Thickbox image paths for Network Admin.
 835   *
 836   * @since 3.1.0
 837   *
 838   * @access private
 839   */
 840  function _thickbox_path_admin_subfolder() {
 841      ?>
 842  <script type="text/javascript">
 843  var tb_pathToImage = "<?php echo includes_url( 'js/thickbox/loadingAnimation.gif', 'relative' ); ?>";
 844  </script>
 845      <?php
 846  }
 847  
 848  /**
 849   * @param array $users
 850   */
 851  function confirm_delete_users( $users ) {
 852      $current_user = wp_get_current_user();
 853      if ( ! is_array( $users ) || empty( $users ) ) {
 854          return false;
 855      }
 856      ?>
 857      <h1><?php esc_html_e( 'Users' ); ?></h1>
 858  
 859      <?php if ( 1 == count( $users ) ) : ?>
 860          <p><?php _e( 'You have chosen to delete the user from all networks and sites.' ); ?></p>
 861      <?php else : ?>
 862          <p><?php _e( 'You have chosen to delete the following users from all networks and sites.' ); ?></p>
 863      <?php endif; ?>
 864  
 865      <form action="users.php?action=dodelete" method="post">
 866      <input type="hidden" name="dodelete" />
 867      <?php
 868      wp_nonce_field( 'ms-users-delete' );
 869      $site_admins = get_super_admins();
 870      $admin_out   = '<option value="' . esc_attr( $current_user->ID ) . '">' . $current_user->user_login . '</option>';
 871      ?>
 872      <table class="form-table" role="presentation">
 873      <?php
 874      $allusers = (array) $_POST['allusers'];
 875      foreach ( $allusers as $user_id ) {
 876          if ( $user_id != '' && $user_id != '0' ) {
 877              $delete_user = get_userdata( $user_id );
 878  
 879              if ( ! current_user_can( 'delete_user', $delete_user->ID ) ) {
 880                  wp_die(
 881                      sprintf(
 882                          /* translators: %s: User login. */
 883                          __( 'Warning! User %s cannot be deleted.' ),
 884                          $delete_user->user_login
 885                      )
 886                  );
 887              }
 888  
 889              if ( in_array( $delete_user->user_login, $site_admins ) ) {
 890                  wp_die(
 891                      sprintf(
 892                          /* translators: %s: User login. */
 893                          __( 'Warning! User cannot be deleted. The user %s is a network administrator.' ),
 894                          '<em>' . $delete_user->user_login . '</em>'
 895                      )
 896                  );
 897              }
 898              ?>
 899              <tr>
 900                  <th scope="row"><?php echo $delete_user->user_login; ?>
 901                      <?php echo '<input type="hidden" name="user[]" value="' . esc_attr( $user_id ) . '" />' . "\n"; ?>
 902                  </th>
 903              <?php
 904              $blogs = get_blogs_of_user( $user_id, true );
 905  
 906              if ( ! empty( $blogs ) ) {
 907                  ?>
 908                  <td><fieldset><p><legend>
 909                  <?php
 910                  printf(
 911                      /* translators: User login. */
 912                      __( 'What should be done with content owned by %s?' ),
 913                      '<em>' . $delete_user->user_login . '</em>'
 914                  );
 915                  ?>
 916                  </legend></p>
 917                  <?php
 918                  foreach ( (array) $blogs as $key => $details ) {
 919                      $blog_users = get_users(
 920                          array(
 921                              'blog_id' => $details->userblog_id,
 922                              'fields'  => array( 'ID', 'user_login' ),
 923                          )
 924                      );
 925                      if ( is_array( $blog_users ) && ! empty( $blog_users ) ) {
 926                          $user_site      = "<a href='" . esc_url( get_home_url( $details->userblog_id ) ) . "'>{$details->blogname}</a>";
 927                          $user_dropdown  = '<label for="reassign_user" class="screen-reader-text">' . __( 'Select a user' ) . '</label>';
 928                          $user_dropdown .= "<select name='blog[$user_id][$key]' id='reassign_user'>";
 929                          $user_list      = '';
 930                          foreach ( $blog_users as $user ) {
 931                              if ( ! in_array( $user->ID, $allusers ) ) {
 932                                  $user_list .= "<option value='{$user->ID}'>{$user->user_login}</option>";
 933                              }
 934                          }
 935                          if ( '' == $user_list ) {
 936                              $user_list = $admin_out;
 937                          }
 938                          $user_dropdown .= $user_list;
 939                          $user_dropdown .= "</select>\n";
 940                          ?>
 941                          <ul style="list-style:none;">
 942                              <li>
 943                                  <?php
 944                                  /* translators: %s: Link to user's site. */
 945                                  printf( __( 'Site: %s' ), $user_site );
 946                                  ?>
 947                              </li>
 948                              <li><label><input type="radio" id="delete_option0" name="delete[<?php echo $details->userblog_id . '][' . $delete_user->ID; ?>]" value="delete" checked="checked" />
 949                              <?php _e( 'Delete all content.' ); ?></label></li>
 950                              <li><label><input type="radio" id="delete_option1" name="delete[<?php echo $details->userblog_id . '][' . $delete_user->ID; ?>]" value="reassign" />
 951                              <?php _e( 'Attribute all content to:' ); ?></label>
 952                              <?php echo $user_dropdown; ?></li>
 953                          </ul>
 954                          <?php
 955                      }
 956                  }
 957                  echo '</fieldset></td></tr>';
 958              } else {
 959                  ?>
 960                  <td><p><?php _e( 'User has no sites or content and will be deleted.' ); ?></p></td>
 961              <?php } ?>
 962              </tr>
 963              <?php
 964          }
 965      }
 966  
 967      ?>
 968      </table>
 969      <?php
 970      /** This action is documented in wp-admin/users.php */
 971      do_action( 'delete_user_form', $current_user, $allusers );
 972  
 973      if ( 1 == count( $users ) ) :
 974          ?>
 975          <p><?php _e( 'Once you hit &#8220;Confirm Deletion&#8221;, the user will be permanently removed.' ); ?></p>
 976      <?php else : ?>
 977          <p><?php _e( 'Once you hit &#8220;Confirm Deletion&#8221;, these users will be permanently removed.' ); ?></p>
 978          <?php
 979      endif;
 980  
 981      submit_button( __( 'Confirm Deletion' ), 'primary' );
 982      ?>
 983      </form>
 984      <?php
 985      return true;
 986  }
 987  
 988  /**
 989   * Print JavaScript in the header on the Network Settings screen.
 990   *
 991   * @since 4.1.0
 992   */
 993  function network_settings_add_js() {
 994      ?>
 995  <script type="text/javascript">
 996  jQuery(document).ready( function($) {
 997      var languageSelect = $( '#WPLANG' );
 998      $( 'form' ).submit( function() {
 999          // Don't show a spinner for English and installed languages,
1000          // as there is nothing to download.
1001          if ( ! languageSelect.find( 'option:selected' ).data( 'installed' ) ) {
1002              $( '#submit', this ).after( '<span class="spinner language-install-spinner is-active" />' );
1003          }
1004      });
1005  });
1006  </script>
1007      <?php
1008  }
1009  
1010  /**
1011   * Outputs the HTML for a network's "Edit Site" tabular interface.
1012   *
1013   * @since 4.6.0
1014   *
1015   * @param $args {
1016   *     Optional. Array or string of Query parameters. Default empty array.
1017   *
1018   *     @type int    $blog_id  The site ID. Default is the current site.
1019   *     @type array  $links    The tabs to include with (label|url|cap) keys.
1020   *     @type string $selected The ID of the selected link.
1021   * }
1022   */
1023  function network_edit_site_nav( $args = array() ) {
1024  
1025      /**
1026       * Filters the links that appear on site-editing network pages.
1027       *
1028       * Default links: 'site-info', 'site-users', 'site-themes', and 'site-settings'.
1029       *
1030       * @since 4.6.0
1031       *
1032       * @param array $links {
1033       *     An array of link data representing individual network admin pages.
1034       *
1035       *     @type array $link_slug {
1036       *         An array of information about the individual link to a page.
1037       *
1038       *         $type string $label Label to use for the link.
1039       *         $type string $url   URL, relative to `network_admin_url()` to use for the link.
1040       *         $type string $cap   Capability required to see the link.
1041       *     }
1042       * }
1043       */
1044      $links = apply_filters(
1045          'network_edit_site_nav_links',
1046          array(
1047              'site-info'     => array(
1048                  'label' => __( 'Info' ),
1049                  'url'   => 'site-info.php',
1050                  'cap'   => 'manage_sites',
1051              ),
1052              'site-users'    => array(
1053                  'label' => __( 'Users' ),
1054                  'url'   => 'site-users.php',
1055                  'cap'   => 'manage_sites',
1056              ),
1057              'site-themes'   => array(
1058                  'label' => __( 'Themes' ),
1059                  'url'   => 'site-themes.php',
1060                  'cap'   => 'manage_sites',
1061              ),
1062              'site-settings' => array(
1063                  'label' => __( 'Settings' ),
1064                  'url'   => 'site-settings.php',
1065                  'cap'   => 'manage_sites',
1066              ),
1067          )
1068      );
1069  
1070      // Parse arguments
1071      $parsed_args = wp_parse_args(
1072          $args,
1073          array(
1074              'blog_id'  => isset( $_GET['blog_id'] ) ? (int) $_GET['blog_id'] : 0,
1075              'links'    => $links,
1076              'selected' => 'site-info',
1077          )
1078      );
1079  
1080      // Setup the links array
1081      $screen_links = array();
1082  
1083      // Loop through tabs
1084      foreach ( $parsed_args['links'] as $link_id => $link ) {
1085  
1086          // Skip link if user can't access
1087          if ( ! current_user_can( $link['cap'], $parsed_args['blog_id'] ) ) {
1088              continue;
1089          }
1090  
1091          // Link classes
1092          $classes = array( 'nav-tab' );
1093  
1094          // Aria-current attribute.
1095          $aria_current = '';
1096  
1097          // Selected is set by the parent OR assumed by the $pagenow global
1098          if ( $parsed_args['selected'] === $link_id || $link['url'] === $GLOBALS['pagenow'] ) {
1099              $classes[]    = 'nav-tab-active';
1100              $aria_current = ' aria-current="page"';
1101          }
1102  
1103          // Escape each class
1104          $esc_classes = implode( ' ', $classes );
1105  
1106          // Get the URL for this link
1107          $url = add_query_arg( array( 'id' => $parsed_args['blog_id'] ), network_admin_url( $link['url'] ) );
1108  
1109          // Add link to nav links
1110          $screen_links[ $link_id ] = '<a href="' . esc_url( $url ) . '" id="' . esc_attr( $link_id ) . '" class="' . $esc_classes . '"' . $aria_current . '>' . esc_html( $link['label'] ) . '</a>';
1111      }
1112  
1113      // All done!
1114      echo '<nav class="nav-tab-wrapper wp-clearfix" aria-label="' . esc_attr__( 'Secondary menu' ) . '">';
1115      echo implode( '', $screen_links );
1116      echo '</nav>';
1117  }
1118  
1119  /**
1120   * Returns the arguments for the help tab on the Edit Site screens.
1121   *
1122   * @since 4.9.0
1123   *
1124   * @return array Help tab arguments.
1125   */
1126  function get_site_screen_help_tab_args() {
1127      return array(
1128          'id'      => 'overview',
1129          'title'   => __( 'Overview' ),
1130          'content' =>
1131              '<p>' . __( 'The menu is for editing information specific to individual sites, particularly if the admin area of a site is unavailable.' ) . '</p>' .
1132              '<p>' . __( '<strong>Info</strong> &mdash; The site URL is rarely edited as this can cause the site to not work properly. The Registered date and Last Updated date are displayed. Network admins can mark a site as archived, spam, deleted and mature, to remove from public listings or disable.' ) . '</p>' .
1133              '<p>' . __( '<strong>Users</strong> &mdash; This displays the users associated with this site. You can also change their role, reset their password, or remove them from the site. Removing the user from the site does not remove the user from the network.' ) . '</p>' .
1134              '<p>' . sprintf(
1135                  /* translators: %s: URL to Network Themes screen. */
1136                  __( '<strong>Themes</strong> &mdash; This area shows themes that are not already enabled across the network. Enabling a theme in this menu makes it accessible to this site. It does not activate the theme, but allows it to show in the site&#8217;s Appearance menu. To enable a theme for the entire network, see the <a href="%s">Network Themes</a> screen.' ),
1137                  network_admin_url( 'themes.php' )
1138              ) . '</p>' .
1139              '<p>' . __( '<strong>Settings</strong> &mdash; This page shows a list of all settings associated with this site. Some are created by WordPress and others are created by plugins you activate. Note that some fields are grayed out and say Serialized Data. You cannot modify these values due to the way the setting is stored in the database.' ) . '</p>',
1140      );
1141  }
1142  
1143  /**
1144   * Returns the content for the help sidebar on the Edit Site screens.
1145   *
1146   * @since 4.9.0
1147   *
1148   * @return string Help sidebar content.
1149   */
1150  function get_site_screen_help_sidebar_content() {
1151      return '<p><strong>' . __( 'For more information:' ) . '</strong></p>' .
1152          '<p>' . __( '<a href="https://wordpress.org/support/article/network-admin-sites-screen/">Documentation on Site Management</a>' ) . '</p>' .
1153          '<p>' . __( '<a href="https://wordpress.org/support/forum/multisite/">Support Forums</a>' ) . '</p>';
1154  }


Generated: Tue Sep 17 01:00:03 2019 Cross-referenced by PHPXref 0.7.1