Статьи

Взаимодействие с WordPress ‘Plug-in & Theme API

WordPress Repository API — это API, используемый для получения информации о плагине и теме для использования на ваших страницах администратора. Например, он отображает последние подключаемые модули на панели инструментов, позволяет просматривать темы на вкладке темы и позволяет искать и устанавливать подключаемые модули прямо из хранилища. В этом уроке мы рассмотрим, как работает этот API и как его можно использовать для доступа к такой информации, как рейтинг вашего плагина, сколько раз он был загружен или даже его разделы ReadMe. С помощью этого API, например, вы можете разместить на своем веб-сайте ссылку, которая всегда будет указывать на последнюю версию вашего плагина или темы.

Когда WordPress собирает информацию о плагинах и темах из репозитория, он делает это, отправляя запрос на один из двух URL-адресов.

  • Для плагинов: http://api.wordpress.org/plugins/info/1.0/
  • По темам: http://api.wordpress.org/themes/info/1.0/

Запрос принимает форму массива с ключами ‘ action ‘ и ‘ request ‘.

1
2
3
4
5
6
7
8
9
$response = wp_remote_post(
    ‘http://api.wordpress.org/plugins/info/1.0/’,
    array(
        ‘body’ => array(
            ‘action’ => $action,
            ‘request’=>serialize((object)$args)
        )
    )
);

При получении данных о плагине или теме, ‘ action ‘ должен быть установлен соответственно на plugin_information или theme_information . Значением ключа запроса должен быть сериализованный объект со свойством slug (кусок темы / плагина) и свойством поля, которое указывает, какие данные нам нужны (доступные поля подробно описаны ниже). В приведенном выше фрагменте $args должен быть ассоциативным массивом с ключами, заданными этими свойствами.

Возвращаемое значение из wp_remote_post , $response , может быть ошибкой WP_Query или же подлинным ответом из репозитория, содержащим сообщение об ошибке. Но если все прошло хорошо, то возвращаемый плагин или объект темы можно извлечь из него следующим образом:

1
$returned_object = maybe_unserialize(wp_remote_retrieve_body($response));

Чтобы получить список тем / плагинов, соответствующих определенным критериям, для действия должно быть установлено значение query_themes или query_plugins . Это должно сопровождаться соответствующим ключом (например, « author », чтобы получить плагины / темы от конкретного автора) в массиве $args . Возможные критерии приведены ниже.

Опять же (при условии отсутствия ошибок), массив соответствующих плагинов должен быть задан как:

1
2
$returned_object = maybe_unserialize(wp_remote_retrieve_body($response));
$plugins = $returned_object->plugins;

и аналогично для тем:

1
2
$returned_object = maybe_unserialize(wp_remote_retrieve_body($response));
$themes = $returned_object->themes;

Каждый объект темы / плагина в массиве имеет те же свойства, которые определены ключом fields в массиве $args . Доступные поля перечислены ниже, а также поля по умолчанию (для *_information запросов). Обратите внимание, что значения по умолчанию отличаются для разных действий.


Как отмечалось выше, $args — это ассоциативный массив, который может содержать следующие поля:

  • slug — (когда действием является plugin_information ). Плагин плагина, для которого возвращаются данные.
  • browse — (когда действие — query_plugins ). Принимает значения featured , popular или new .
  • author — (когда действие — query_plugins ). Имя пользователя WordPress автора, чтобы получить плагины определенного автора.
  • tag — (когда действие — query_plugins ). Тег, с помощью которого можно получить плагины.
  • search — (когда действие — query_plugins ). Термин поиска, с помощью которого можно искать в хранилище.
  • fields — массив с возможными полями (перечисленными ниже) в качестве ключей и значениями true или false чтобы возвращать данные для этого поля или нет. Включенные поля составляют свойства возвращенного объекта выше. Возможные поля: (по умолчанию установлено значение true , если не указано иное):
    • version — последняя
    • author — имя автора и ссылка на профиль
    • requires — минимальная версия WordPress требуется
    • testedtested последняя версия WordPress
    • compatibility — массив, который содержит массив для каждой версии вашего плагина. В этом массиве хранится количество голосов, количество «рабочих» голосов и это число в процентах.
    • downloaded — количество скачиваний
    • rating — в процентах
    • num_ratings — количество оценок
    • sections — это массив с HTML для каждого раздела на странице плагина WordPress в качестве значений, ключи могут включать в себя « description », « installation », « screenshots », « changelog » и « faq ».
    • download_link — указывает на размещенный в репозитории ZIP-файл последней версии плагина
    • description — (по умолчанию false )
    • short_description — (по умолчанию false )

Другие поля включают « name », « slug », « author_profile », « tags », « homepage », « contributors », « last_updated » и « last_updated ».

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

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
// Set the arguments.
$args = array(
    ‘author’ => ‘stephenh1988’,
    ‘fields’ => array(
        ‘downloaded’ => true,
        ‘downloadlink’ => true
    )
);
 
// Make request and extract plug-in object.
$response = wp_remote_post(
    ‘http://api.wordpress.org/plugins/info/1.0/’,
    array(
        ‘body’ => array(
            ‘action’ => ‘query_plugins’,
            ‘request’ => serialize((object)$args)
        )
    )
);
 
if ( !is_wp_error($response) ) {
    $returned_object = unserialize(wp_remote_retrieve_body($response));
    $plugins = $returned_object->plugins;
    if ( !is_array($plugins) ) {
        // Response body does not contain an object/array
        echo «An error has occurred»;
    }
    else {
        // Display a list of the plug-ins and the number of downloads
        if ( $plugins ) {
            echo ‘<ul>’;
            foreach ( $plugins as $plugin ) {
                echo «<li>».esc_html($plugin->name).» (downloaded «.esc_html($plugin->downloaded).» times)</li>»;
            }
        }
    }
}
else {
    // Error object returned
    echo «An error has occurred»;
}

Запрос API тем очень похож, хотя есть несколько других доступных полей.

  • slug — (когда действие — theme_information ) theme_information темы, для которого возвращаются данные.
  • browse — (когда действие query_themes ). Принимает значения featured , new или updated .
  • author — (когда действием является query_themes ). Имя пользователя автора, чтобы получить темы от конкретного автора.
  • tag — (когда действие — query_themes ). Массив тегов для поиска тем.
  • search — (когда действием является query_themes ). Термин поиска, с помощью которого можно искать в хранилище.
  • fields — снова массив с true или false значением для каждого ключа (поля). Включенные поля составляют свойства возвращенного объекта выше. Возможные поля: (по умолчанию установлено значение true , если не указано иное):
    • version — (последняя)
    • author
    • preview_url — URL для предварительного просмотра на wp-themes.com
    • screenshot_url — URL к изображению скриншота
    • screenshot_count * — количество скриншотов темы
    • screenshots * — массив URL скриншотов
    • rating — (в процентах)
    • num_ratings — количество оценок
    • downloaded — количество скачиваний
    • sections
    • description
    • download_link

Другие поля включают в себя « name », « slug », « tags », « homepage », « contributors » и « last_updated ».

* Обращаем ваше внимание, что в будущих темах будет [разрешено несколько скриншотов] [1].

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
// Set the arguments.
$args = array(
    ‘slug’ => ‘Desk Mess Mirrored’,
    ‘fields’ => array( ‘screenshot_url’=> true )
);
 
// Make request and extract plug-in object
$response = wp_remote_post(
    ‘http://api.wordpress.org/themes/info/1.0/’,
    array(
        ‘body’ => array(
            ‘action’ => ‘theme_information’,
            ‘request’ => serialize((object)$args)
        )
    )
);
 
if ( !is_wp_error($response) ) {
    $theme = unserialize(wp_remote_retrieve_body($response));
    if ( !is_object($theme) && !is_array($theme) ) {
        // Response body does not contain an object/array
        echo «An error has occurred»;
    }
    else {
        // Sanitize data:
        $preview_url = esc_url($theme->preview_url);
        $screenshot_url = esc_attr($theme->screenshot_url);
        $rating = esc_attr($theme->rating);
 
        // Display the rating of the theme, a screenshot and link to the preview of the theme
        echo «This theme has a rating of {$rating}%. <a href=’$preview_url’> View a preview</a>»;
        echo «<img src=’$screenshot_url’ />»;
    }
}
else {
    // Error object returned
    echo «An error has occurred»;
}

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


Это отличный пример того, где может (и должно) использоваться кэширование, особенно переходные процессы. Кэширование данных означает, что мы не будем извлекать информацию из хранилища при каждой загрузке страницы, что замедлит загрузку сайта. В качестве простого примера, когда я запустил приведенный выше пример без кэширования, потребовалось 0,522 секунды для извлечения данных (что является респектабельным). Как только я начал использовать переходные процессы, он снизился до 0,001 секунды. В любом случае нам не нужно получать эту информацию при каждой загрузке страницы — на самом деле нет особых причин обновлять эти данные чаще, чем раз в день (или, возможно, дольше).

Если вы не уверены, как использовать переходные процессы, вы можете прочитать о них в этой статье .

Давайте реализуем переходные процессы в универсальной функции, которая будет извлекать информацию о теме, учитывая конкретную тему (и другие аргументы):

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
/**
* Returns a theme object given an array $args or WP_Error object if there is an error
* $args should contain a ‘slug’ key with the theme’s name
* and ‘fields’ key holding an array of fields to retrieve.
*/
function sh_get_theme_information( $args ) {
    // Set the $request array
    $request = array(
        ‘body’ => array(
            ‘action’ => ‘theme_information’,
            ‘request’ => serialize((object)$args)
        )
    );
 
    // Generate a cache key that would hold the response for this request:
    $key=’sh_theme_’.md5(serialize($request));
 
    // Check transient.
    if ( false === ($theme = get_transient($key)) ) {
 
        // Theme not found — we need to re-fetch it
        $response = wp_remote_post(‘http://api.wordpress.org/themes/info/1.0/’,$request);
 
        if ( is_wp_error($response) )
            return $response;
 
        $theme = unserialize(wp_remote_retrieve_body($response));
 
        if ( !is_object($theme) && !is_array($theme) )
            return new WP_Error(‘theme_api_error’, ‘An unexpected error has occurred’);
 
        // Set transient for next time… keep it for 24 hours should be good
        set_transient($key, $theme, 60*60*24);
    }
 
    return $theme;
}

Чтобы использовать эту функцию:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// Set the arguments.
$args = array(
    ‘slug’ => ‘Desk Mess Mirrored’,
    ‘fields’ => array( ‘screenshot_url’ => true )
);
 
// Get the theme
$theme = sh_get_theme_information( $args );
 
// Display theme information (or error message).
if ( is_wp_error($theme) ) {
    echo ‘An unexpected error has occurred’;
 
}
else {
    // Sanitize data:
    $preview_url = esc_url($theme->preview_url);
    $screenshot_url = esc_attr($theme->screenshot_url);
    $rating = esc_attr($theme->rating);
 
    // Display theme rating, screenshot and preview link
    echo «This theme has a rating of {$rating}%.<a href='{$preview_url}’> View a preview </a>»;
    echo «<img src='{$screenshot_url}’/>»;
}

Основной шаблон для извлечения данных из любого API в целом одинаков. Превратите запрос в уникальный, с помощью которого можно кешировать результаты. Затем проверьте, существуют ли данные для ключа, если это так — отлично, мы можем просто вернуть эти данные. В противном случае извлекайте данные удаленно. Как только вы получили ответ, проверьте на наличие ошибок, и если нет никаких обновлений переходного процесса и вернуть вновь полученные данные.

В качестве второго примера мы можем построить функцию, которая возвращает массив плагинов определенного автора:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
function sh_get_plugins_by_author($author=») {
 
    if ( empty($author) )
        return false;
 
    $key = sanitize_key(‘sh_plugins_’.$author);
 
    if ( false === ( $plugins = get_transient($key) ) ) {
        $args = array(‘author’=>$author, ‘fields’=>array(‘downloaded’=>true,’downloadlink’=>true));
        $response = wp_remote_post(
            ‘http://api.wordpress.org/plugins/info/1.0/’,
            array(
                ‘body’ => array(
                    ‘action’ => ‘query_plugins’,
                    ‘request’ => serialize((object)$args)
                )
            )
        );
        $plugin_response = unserialize(wp_remote_retrieve_body($response));
        $plugins = $plugin_response->plugins;
 
        // Set transient for next time… keep it for 24 hours should be good
        set_transient($key, $plugins, 60*60*24);
    }
 
    return $plugins;
}

(Конечно, вы всегда можете использовать API WordPress в сочетании с программным кэшированием , о котором я говорил в этой статье ).

Вы можете увидеть живую демонстрацию использования API репозитория WordPress на странице плагинов WordPress моего сайта.