WordPress.org

Make WordPress Core

Ticket #37217: 37217.diff

File 37217.diff, 10.4 KB (added by spacedmonkey, 3 years ago)
  • src/wp-includes/class-wp-network.php

     
    265265         * @return WP_Network|bool Network object if successful. False when no network is found.
    266266         */
    267267        public static function get_by_path( $domain = '', $path = '', $segments = null ) {
    268                 global $wpdb;
    269 
    270                 $domains = array( $domain );
    271                 $pieces  = explode( '.', $domain );
    272 
    273                 /*
    274                  * It's possible one domain to search is 'com', but it might as well
    275                  * be 'localhost' or some other locally mapped domain.
    276                  */
    277                 while ( array_shift( $pieces ) ) {
    278                         if ( ! empty( $pieces ) ) {
    279                                 $domains[] = implode( '.', $pieces );
    280                         }
    281                 }
    282 
    283                 /*
    284                  * If we've gotten to this function during normal execution, there is
    285                  * more than one network installed. At this point, who knows how many
    286                  * we have. Attempt to optimize for the situation where networks are
    287                  * only domains, thus meaning paths never need to be considered.
    288                  *
    289                  * This is a very basic optimization; anything further could have
    290                  * drawbacks depending on the setup, so this is best done per-install.
    291                  */
    292                 $using_paths = true;
    293                 if ( wp_using_ext_object_cache() ) {
    294                         $using_paths = wp_cache_get( 'networks_have_paths', 'site-options' );
    295                         if ( false === $using_paths ) {
    296                                 $using_paths = (int) $wpdb->get_var( "SELECT id FROM {$wpdb->site} WHERE path <> '/' LIMIT 1" );
    297                                 wp_cache_add( 'networks_have_paths', $using_paths, 'site-options'  );
    298                         }
    299                 }
    300 
    301                 $paths = array();
    302                 if ( $using_paths ) {
    303                         $path_segments = array_filter( explode( '/', trim( $path, '/' ) ) );
    304 
    305                         /**
    306                          * Filters the number of path segments to consider when searching for a site.
    307                          *
    308                          * @since 3.9.0
    309                          *
    310                          * @param int|null $segments The number of path segments to consider. WordPress by default looks at
    311                          *                           one path segment. The function default of null only makes sense when you
    312                          *                           know the requested path should match a network.
    313                          * @param string   $domain   The requested domain.
    314                          * @param string   $path     The requested path, in full.
    315                          */
    316                         $segments = apply_filters( 'network_by_path_segments_count', $segments, $domain, $path );
    317 
    318                         if ( ( null !== $segments ) && count( $path_segments ) > $segments ) {
    319                                 $path_segments = array_slice( $path_segments, 0, $segments );
    320                         }
    321 
    322                         while ( count( $path_segments ) ) {
    323                                 $paths[] = '/' . implode( '/', $path_segments ) . '/';
    324                                 array_pop( $path_segments );
    325                         }
    326 
    327                         $paths[] = '/';
    328                 }
    329 
    330                 /**
    331                  * Determine a network by its domain and path.
    332                  *
    333                  * This allows one to short-circuit the default logic, perhaps by
    334                  * replacing it with a routine that is more optimal for your setup.
    335                  *
    336                  * Return null to avoid the short-circuit. Return false if no network
    337                  * can be found at the requested domain and path. Otherwise, return
    338                  * an object from wp_get_network().
    339                  *
    340                  * @since 3.9.0
    341                  *
    342                  * @param null|bool|object $network  Network value to return by path.
    343                  * @param string           $domain   The requested domain.
    344                  * @param string           $path     The requested path, in full.
    345                  * @param int|null         $segments The suggested number of paths to consult.
    346                  *                                   Default null, meaning the entire path was to be consulted.
    347                  * @param array            $paths    The paths to search for, based on $path and $segments.
    348                  */
    349                 $pre = apply_filters( 'pre_get_network_by_path', null, $domain, $path, $segments, $paths );
    350                 if ( null !== $pre ) {
    351                         return $pre;
    352                 }
    353 
    354                 // @todo Consider additional optimization routes, perhaps as an opt-in for plugins.
    355                 // We already have paths covered. What about how far domains should be drilled down (including www)?
    356 
    357                 $search_domains = "'" . implode( "', '", $wpdb->_escape( $domains ) ) . "'";
    358 
    359                 if ( ! $using_paths ) {
    360                         $network = $wpdb->get_row( "
    361                                 SELECT * FROM {$wpdb->site}
    362                                 WHERE domain IN ({$search_domains})
    363                                 ORDER BY CHAR_LENGTH(domain)
    364                                 DESC LIMIT 1
    365                         " );
    366 
    367                         if ( ! empty( $network ) && ! is_wp_error( $network ) ) {
    368                                 return new WP_Network( $network );
    369                         }
    370 
    371                         return false;
    372 
    373                 } else {
    374                         $search_paths = "'" . implode( "', '", $wpdb->_escape( $paths ) ) . "'";
    375                         $networks = $wpdb->get_results( "
    376                                 SELECT * FROM {$wpdb->site}
    377                                 WHERE domain IN ({$search_domains})
    378                                 AND path IN ({$search_paths})
    379                                 ORDER BY CHAR_LENGTH(domain) DESC, CHAR_LENGTH(path) DESC
    380                         " );
    381                 }
    382 
    383                 /*
    384                  * Domains are sorted by length of domain, then by length of path.
    385                  * The domain must match for the path to be considered. Otherwise,
    386                  * a network with the path of / will suffice.
    387                  */
    388                 $found = false;
    389                 foreach ( $networks as $network ) {
    390                         if ( ( $network->domain === $domain ) || ( "www.{$network->domain}" === $domain ) ) {
    391                                 if ( in_array( $network->path, $paths, true ) ) {
    392                                         $found = true;
    393                                         break;
    394                                 }
    395                         }
    396                         if ( $network->path === '/' ) {
    397                                 $found = true;
    398                                 break;
    399                         }
    400                 }
    401 
    402                 if ( true === $found ) {
    403                         return new WP_Network( $network );
    404                 }
    405 
    406                 return false;
     268                _deprecated_function( __METHOD__, '4.7.0', 'get_network_by_path()' );
     269                return get_network_by_path( $domain, $path, $segments );
    407270        }
    408271}
  • src/wp-includes/ms-load.php

     
    129129 * @return WP_Network|false Network object if successful. False when no network is found.
    130130 */
    131131function get_network_by_path( $domain, $path, $segments = null ) {
    132         return WP_Network::get_by_path( $domain, $path, $segments );
     132
     133        $domains = array( $domain );
     134        $pieces  = explode( '.', $domain );
     135
     136        /*
     137         * It's possible one domain to search is 'com', but it might as well
     138         * be 'localhost' or some other locally mapped domain.
     139         */
     140        while ( array_shift( $pieces ) ) {
     141                if ( ! empty( $pieces ) ) {
     142                        $domains[] = implode( '.', $pieces );
     143                }
     144        }
     145
     146        /*
     147         * If we've gotten to this function during normal execution, there is
     148         * more than one network installed. At this point, who knows how many
     149         * we have. Attempt to optimize for the situation where networks are
     150         * only domains, thus meaning paths never need to be considered.
     151         *
     152         * This is a very basic optimization; anything further could have
     153         * drawbacks depending on the setup, so this is best done per-install.
     154         */
     155        $using_paths = true;
     156        if ( wp_using_ext_object_cache() ) {
     157                $using_paths = get_networks( array( 'fields' => 'count', 'path__not_in' => '/') );
     158        }
     159
     160        $paths = array();
     161        if ( $using_paths ) {
     162                $path_segments = array_filter( explode( '/', trim( $path, '/' ) ) );
     163
     164                /**
     165                 * Filters the number of path segments to consider when searching for a site.
     166                 *
     167                 * @since 3.9.0
     168                 *
     169                 * @param int|null $segments The number of path segments to consider. WordPress by default looks at
     170                 *                           one path segment. The function default of null only makes sense when you
     171                 *                           know the requested path should match a network.
     172                 * @param string $domain The requested domain.
     173                 * @param string $path The requested path, in full.
     174                 */
     175                $segments = apply_filters( 'network_by_path_segments_count', $segments, $domain, $path );
     176
     177                if ( ( null !== $segments ) && count( $path_segments ) > $segments ) {
     178                        $path_segments = array_slice( $path_segments, 0, $segments );
     179                }
     180
     181                while ( count( $path_segments ) ) {
     182                        $paths[] = '/' . implode( '/', $path_segments ) . '/';
     183                        array_pop( $path_segments );
     184                }
     185
     186                $paths[] = '/';
     187        }
     188
     189        /**
     190         * Determine a network by its domain and path.
     191         *
     192         * This allows one to short-circuit the default logic, perhaps by
     193         * replacing it with a routine that is more optimal for your setup.
     194         *
     195         * Return null to avoid the short-circuit. Return false if no network
     196         * can be found at the requested domain and path. Otherwise, return
     197         * an object from wp_get_network().
     198         *
     199         * @since 3.9.0
     200         *
     201         * @param null|bool|object $network Network value to return by path.
     202         * @param string $domain The requested domain.
     203         * @param string $path The requested path, in full.
     204         * @param int|null $segments The suggested number of paths to consult.
     205         *                                   Default null, meaning the entire path was to be consulted.
     206         * @param array $paths The paths to search for, based on $path and $segments.
     207         */
     208        $pre = apply_filters( 'pre_get_network_by_path', null, $domain, $path, $segments, $paths );
     209        if ( null !== $pre ) {
     210                return $pre;
     211        }
     212
     213        // @todo Consider additional optimization routes, perhaps as an opt-in for plugins.
     214        // We already have paths covered. What about how far domains should be drilled down (including www)?
     215
     216        if ( ! $using_paths ) {
     217
     218                $networks = get_networks( array( 'number' => 1, 'domain__in' => $domains, 'orderby' => 'domain_length' ) );
     219
     220                if ( ! empty( $networks ) ) {
     221                        return array_shift( $networks );
     222                }
     223
     224                return false;
     225
     226        } else {
     227                $networks = get_networks( array(
     228                                'domain__in' => $domains,
     229                                'path__in'   => $paths,
     230                                'orderby'    => array( 'domain_length' => 'DESC', 'path_length' => 'DESC' )
     231                        )
     232                );
     233        }
     234
     235        /*
     236         * Domains are sorted by length of domain, then by length of path.
     237         * The domain must match for the path to be considered. Otherwise,
     238         * a network with the path of / will suffice.
     239         */
     240        $found = false;
     241        foreach ( $networks as $network ) {
     242                if ( ( $network->domain === $domain ) || ( "www.{$network->domain}" === $domain ) ) {
     243                        if ( in_array( $network->path, $paths, true ) ) {
     244                                $found = true;
     245                                break;
     246                        }
     247                }
     248                if ( $network->path === '/' ) {
     249                        $found = true;
     250                        break;
     251                }
     252        }
     253
     254        if ( true === $found ) {
     255                return $network;
     256        }
     257
     258        return false;
    133259}
    134260
    135261/**
     
    336462                }
    337463
    338464                if ( empty( $current_site ) ) {
    339                         $current_site = WP_Network::get_by_path( $domain, $path, 1 );
     465                        $current_site = get_network_by_path( $domain, $path, 1 );
    340466                }
    341467
    342468                if ( empty( $current_site ) ) {
     
    367493                        $current_site = WP_Network::get_instance( $current_blog->site_id ? $current_blog->site_id : 1 );
    368494                } else {
    369495                        // If you don't have a site with the same domain/path as a network, you're pretty screwed, but:
    370                         $current_site = WP_Network::get_by_path( $domain, $path, 1 );
     496                        $current_site = get_network_by_path( $domain, $path, 1 );
    371497                }
    372498        }
    373499