Использование стороннего сервиса для заполнения и поиска постов WordPress - PullRequest
1 голос
/ 10 января 2020

Я использую сторонний сервис для заполнения постов на моем сайте WordPress. Большая часть информации, поступающей из сервиса, хранится в виде свойств поста WordPress (заголовок, контент, изображения и т. Д. c), но часть из них хранится в виде метаданных поста (уникальные идентификаторы сервиса для каждого поста и другие метаданные). Служба предлагает поиск по радиусу, чтобы найти сообщения, которые соответствуют определенному местоположению, и возвращает идентификаторы для соответствующих сообщений. Моя цель состоит в том, чтобы взять эти идентификаторы и вернуть постраничный набор результатов из сообщений WP, чтобы все форматировалось, как любая другая страница поиска на сайте WP. У меня есть рабочая реализация этого, но она очень медленная, и я ищу совет о том, как ее ускорить, или о различных подходах к достижению sh моей цели.

Моя текущая реализация делает нумерацию страниц oop для всех соответствующих сообщений в сервисе (это может вернуть 10 результатов или 1000 результатов). Затем я беру идентификаторы из этого набора результатов и передаю их в запрос WP, чтобы ограничить запрос мета-значением идентификаторов. Запрос становится медленнее, чем больше набор данных из сервиса. Я делаю это таким образом, чтобы позволить мне использовать нумерацию страниц WP. Если бы я просто вернул одну страницу в разбивке по страницам, WordPress не знал бы, что было бы больше результатов для разбивки на страницы. Буду очень признателен за любые советы или рекомендации о том, как сделать этот процесс более производительным.

Вот код, который у меня есть до сих пор. В настоящее время он работает, но, как уже упоминалось, чем больше набор данных из службы, тем больше времени занимает запрос:

<?php

class Search {
    const SEARCH_PREFIX = 'test';
    protected static $api_params_whitelist = [
        'search',
        'near_zip',
        'near_city',
        'radius',
        'featured_only',
        'currently_listed_only',
        'registrable_only',
        'page',
        'per_page',
        'sort'
    ];

    public static function radius_search($query) {
        $field_prefix = Search::SEARCH_PREFIX;
        $search = $query->get($field_prefix . 'term');
        $location = $query->get($field_prefix . 'location');
        $radius = $query->get($field_prefix . 'radius');
        
        if (
            $query->is_main_query()
            && (strlen($location) > 0)
        ) {
            // Lookup result IDs for radius.
            if ($resultIds = self::get_result_ids($search, $location, $radius)) {
                $query->set( 'meta_query',  array(
                    // Search for the result id stored in `post_meta`.
                    array(
                        'key'     => 'id',
                        'value'   => $resultIds,
                        'compare' => 'IN',
                    ),
                ) );
            } else {
                // Force no results
                $query->set( 'post__in', array(0) );
            }
        } elseif ( strlen( $search ) > 0 ) {
            // Fallback to standard WP search w/o radius search
            $query->set( 's', $search );
        }
    }

    public static function add_query_vars_filter( $vars ) {
        $field_prefix = Search::SEARCH_PREFIX;

        $query_variables = [
            $field_prefix . 'term',
            $field_prefix . 'location',
            $field_prefix . 'radius'
        ];

        foreach ($query_variables as $var) {
            $vars[] = $var;
        }
        
        return $vars;
    }

    private static function get_api_handler() {
        $credentials = Synchronize::get_credentials();

        if( !isset( $credentials['subdomain'] ) ) {
            return false;
        }

        $api = new \My_Api( $credentials['subdomain'] );
        $api->setTimeoutInSeconds( 10 );

        return $api;
    }

    private static function get_result_ids($search, $location, $radius) {
        $api = self::get_api_handler();

        $page = 1;
        $per_page = 60;
        $results = [];

        $params = $_GET;
        $params['per_page'] = $per_page;

        $query_params = $api->getQueryParams( $params, Search::SEARCH_PREFIX, self::$api_params_whitelist );

        do {
            $query_params['page'] = $page;
            $query_params['fields'] = [
                'id'
            ];

            $results = $api->get( '/search', $query_params );
            $resultCount = count($results);

            if ($results && $resultCount > 0) {
                $results = array_merge($results, $results);
            }
            $page++;
        } while ($results && $resultCount > 0);
        
        if (count($results)) {
            return array_column($results, 'id');
        }

        return false;
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...