https-migration.php 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. <?php
  2. /**
  3. * HTTPS migration functions.
  4. *
  5. * @package WordPress
  6. * @since 5.7.0
  7. */
  8. /**
  9. * Checks whether WordPress should replace old HTTP URLs to the site with their HTTPS counterpart.
  10. *
  11. * If a WordPress site had its URL changed from HTTP to HTTPS, by default this will return `true`, causing WordPress to
  12. * add frontend filters to replace insecure site URLs that may be present in older database content. The
  13. * {@see 'wp_should_replace_insecure_home_url'} filter can be used to modify that behavior.
  14. *
  15. * @since 5.7.0
  16. *
  17. * @return bool True if insecure URLs should replaced, false otherwise.
  18. */
  19. function wp_should_replace_insecure_home_url() {
  20. $should_replace_insecure_home_url = wp_is_using_https()
  21. && get_option( 'https_migration_required' )
  22. // For automatic replacement, both 'home' and 'siteurl' need to not only use HTTPS, they also need to be using
  23. // the same domain.
  24. && wp_parse_url( home_url(), PHP_URL_HOST ) === wp_parse_url( site_url(), PHP_URL_HOST );
  25. /**
  26. * Filters whether WordPress should replace old HTTP URLs to the site with their HTTPS counterpart.
  27. *
  28. * If a WordPress site had its URL changed from HTTP to HTTPS, by default this will return `true`. This filter can
  29. * be used to disable that behavior, e.g. after having replaced URLs manually in the database.
  30. *
  31. * @since 5.7.0
  32. *
  33. * @param bool $should_replace_insecure_home_url Whether insecure HTTP URLs to the site should be replaced.
  34. */
  35. return apply_filters( 'wp_should_replace_insecure_home_url', $should_replace_insecure_home_url );
  36. }
  37. /**
  38. * Replaces insecure HTTP URLs to the site in the given content, if configured to do so.
  39. *
  40. * This function replaces all occurrences of the HTTP version of the site's URL with its HTTPS counterpart, if
  41. * determined via {@see wp_should_replace_insecure_home_url()}.
  42. *
  43. * @since 5.7.0
  44. *
  45. * @param string $content Content to replace URLs in.
  46. * @return string Filtered content.
  47. */
  48. function wp_replace_insecure_home_url( $content ) {
  49. if ( ! wp_should_replace_insecure_home_url() ) {
  50. return $content;
  51. }
  52. $https_url = home_url( '', 'https' );
  53. $http_url = str_replace( 'https://', 'http://', $https_url );
  54. // Also replace potentially escaped URL.
  55. $escaped_https_url = str_replace( '/', '\/', $https_url );
  56. $escaped_http_url = str_replace( '/', '\/', $http_url );
  57. return str_replace(
  58. array(
  59. $http_url,
  60. $escaped_http_url,
  61. ),
  62. array(
  63. $https_url,
  64. $escaped_https_url,
  65. ),
  66. $content
  67. );
  68. }
  69. /**
  70. * Update the 'home' and 'siteurl' option to use the HTTPS variant of their URL.
  71. *
  72. * If this update does not result in WordPress recognizing that the site is now using HTTPS (e.g. due to constants
  73. * overriding the URLs used), the changes will be reverted. In such a case the function will return false.
  74. *
  75. * @since 5.7.0
  76. *
  77. * @return bool True on success, false on failure.
  78. */
  79. function wp_update_urls_to_https() {
  80. // Get current URL options.
  81. $orig_home = get_option( 'home' );
  82. $orig_siteurl = get_option( 'siteurl' );
  83. // Get current URL options, replacing HTTP with HTTPS.
  84. $home = str_replace( 'http://', 'https://', $orig_home );
  85. $siteurl = str_replace( 'http://', 'https://', $orig_siteurl );
  86. // Update the options.
  87. update_option( 'home', $home );
  88. update_option( 'siteurl', $siteurl );
  89. if ( ! wp_is_using_https() ) {
  90. // If this did not result in the site recognizing HTTPS as being used,
  91. // revert the change and return false.
  92. update_option( 'home', $orig_home );
  93. update_option( 'siteurl', $orig_siteurl );
  94. return false;
  95. }
  96. // Otherwise the URLs were successfully changed to use HTTPS.
  97. return true;
  98. }
  99. /**
  100. * Updates the 'https_migration_required' option if needed when the given URL has been updated from HTTP to HTTPS.
  101. *
  102. * If this is a fresh site, a migration will not be required, so the option will be set as `false`.
  103. *
  104. * This is hooked into the {@see 'update_option_home'} action.
  105. *
  106. * @since 5.7.0
  107. * @access private
  108. *
  109. * @param mixed $old_url Previous value of the URL option.
  110. * @param mixed $new_url New value of the URL option.
  111. */
  112. function wp_update_https_migration_required( $old_url, $new_url ) {
  113. // Do nothing if WordPress is being installed.
  114. if ( wp_installing() ) {
  115. return;
  116. }
  117. // Delete/reset the option if the new URL is not the HTTPS version of the old URL.
  118. if ( untrailingslashit( (string) $old_url ) !== str_replace( 'https://', 'http://', untrailingslashit( (string) $new_url ) ) ) {
  119. delete_option( 'https_migration_required' );
  120. return;
  121. }
  122. // If this is a fresh site, there is no content to migrate, so do not require migration.
  123. $https_migration_required = get_option( 'fresh_site' ) ? false : true;
  124. update_option( 'https_migration_required', $https_migration_required );
  125. }