= 2 ) ? (string) $parts[ count( $parts ) - 2 ] : ''; if ( 'page' === $prev && ctype_digit( $last ) ) { return ''; } return $last; } public static function resolve_many( array $paths, $slow_fallback = false ) { global $wpdb; $want = array(); foreach ( $paths as $raw ) { $n = self::normalise( $raw ); if ( '' !== $n && '/' !== $n ) { $want[ $n ] = true; } } if ( empty( $want ) ) { return array(); } $want = array_keys( $want ); $out = array(); $sp = $wpdb->prefix . 'aieo_seo_posts'; if ( (string) $wpdb->get_var( $wpdb->prepare( 'SHOW TABLES LIKE %s', $sp ) ) === $sp ) { foreach ( array_chunk( $want, self::CHUNK ) as $chunk ) { $probe = array(); foreach ( $chunk as $p ) { $probe[] = $p; $probe[] = $p . '/'; } $ph = implode( ',', array_fill( 0, count( $probe ), '%s' ) ); $rows = $wpdb->get_results( $wpdb->prepare( "SELECT canonical_url, object_type, object_id FROM `{$sp}` WHERE canonical_url IN ({$ph}) AND object_id > 0", $probe ), ARRAY_A ); foreach ( (array) $rows as $r ) { $key = self::normalise( $r['canonical_url'] ); if ( '' !== $key && ! isset( $out[ $key ] ) ) { $out[ $key ] = array( 'type' => (string) $r['object_type'], 'id' => (int) $r['object_id'] ); } } } } $left = array_values( array_diff( $want, array_keys( $out ) ) ); if ( ! empty( $left ) ) { $by_slug = array(); foreach ( $left as $p ) { $s = self::slug_of( $p ); if ( '' !== $s ) { $by_slug[ $s ][] = $p; } } $public_types = array_values( (array) get_post_types( array( 'public' => true ), 'names' ) ); $public_types = array_values( array_diff( $public_types, array( 'attachment' ) ) ); if ( empty( $public_types ) ) { $public_types = array( 'post', 'page', 'product' ); } $tph = implode( ',', array_fill( 0, count( $public_types ), '%s' ) ); $slugs = array_keys( $by_slug ); $found = array(); foreach ( array_chunk( $slugs, self::CHUNK ) as $chunk ) { $ph = implode( ',', array_fill( 0, count( $chunk ), '%s' ) ); $rows = $wpdb->get_results( $wpdb->prepare( "SELECT ID, post_name, post_type FROM `{$wpdb->posts}` WHERE post_name IN ({$ph}) AND post_status IN ('publish','private') AND post_type IN ({$tph})", array_merge( $chunk, $public_types ) ), ARRAY_A ); foreach ( (array) $rows as $r ) { $found[ (string) $r['post_name'] ][] = array( 'type' => (string) $r['post_type'], 'id' => (int) $r['ID'] ); } } foreach ( $found as $slug => $cands ) { $pick = self::pick( $cands ); foreach ( (array) $by_slug[ $slug ] as $p ) { $out[ $p ] = $pick; } } } if ( $slow_fallback ) { foreach ( array_diff( $want, array_keys( $out ) ) as $p ) { $pid = (int) url_to_postid( home_url( $p ) ); if ( $pid > 0 ) { $out[ $p ] = array( 'type' => (string) get_post_type( $pid ), 'id' => $pid ); } } } return $out; } private static function pick( array $cands ) { usort( $cands, static function ( $a, $b ) { $ra = array_search( $a['type'], self::TYPE_PREFERENCE, true ); $rb = array_search( $b['type'], self::TYPE_PREFERENCE, true ); $ra = ( false === $ra ) ? PHP_INT_MAX : $ra; $rb = ( false === $rb ) ? PHP_INT_MAX : $rb; if ( $ra !== $rb ) { return $ra - $rb; } $c = strcmp( $a['type'], $b['type'] ); return ( 0 !== $c ) ? $c : ( $a['id'] - $b['id'] ); } ); return $cands[0]; } }