Создание WordPress Плагин, который использует услугу AIS, “От супа к орехам”

Все большее число общедоступных AA предоставляют мощные услуги для расширения функциональности наших приложений. WordPress является невероятно динамичным и гибким CMS, что полномочия все, от небольших личных блогов на основные веб-сайты электронной коммерции и все между ними. Часть того, что делает WordPress настолько универсальным является его мощная плагинная система,что делает его невероятно легко добавить функциональность.

Мы будем ходить через, как я сделал GitHub трубопровода, плагин, который позволяет отображать данные из API GitHub на страницах WordPress с помощью коротких кодов. Я приведу конкретные примеры и фрагменты кода, но рассмотреть описанный здесь метод — план того, как использовать aPI-сервис с плагином.

Дальнейшее чтение на SmashingMag:

Мы начнем с самого начала, но степень знакомства с WordPress и плагин развития предполагается, и мы не будем тратить время на начинающих темах, как установка WordPress или композитор.

Вам понадобится:

Выбор API

Первым шагом в написании такого рода плагина является выбор API. В этом уроке мы будем использовать API GitHub. Если вы думаете об использовании другого API, рассмотрим несколько важных факторов, которые могут повлиять на то, насколько полезным будет ваш проект.

Одна из первых вещей, которые я смотрю на это тщательность и качество документации API. Если он является редким или устаревшим, будьте готовы потратить время на просеивание через исходный код, чтобы ответить на свои собственные вопросы. Кроме того, подумайте о том, насколько зрелым является API и насколько ответственно его версия сделала поставщику. Нет ничего хуже, чем инвестировать время в создание чего-то великого, только для того, чтобы сломать из-за изменений в восходящем API. Ищите систему версий в URL-адресах конечных точек.

// good
http://api.stable.com/v1/user/

// danger
http://api.dodgy.com/user/

Рискуя заявить очевидное, что программирование против стороннего API предполагает доверительные отношения, и не все API созданы равными.

Покупки для библиотеки

Учрежденные бренды часто распространяют библиотеки или SDK, чтобы облегчить работу с их API. Если это не так, не забудьте исследовать ли кто-то другой написал библиотеку уже до того, как вы идете и изобретать колесо. Google и GitHub являются двумя отличными местами, чтобы начать свои исследования. Количество звезд или вилок на GitHub является хорошим показателем того, насколько эффективна библиотека. Возраст последних коммитов и/или количество открытых выпусков свидетельствуют о том, насколько активно они поддерживаются. В моем случае, мне посчастливилось найти прекрасный PHP GitHub API, по KNP Labs.

Дать свой собственный с Guzzle

Если нет удовлетворительной библиотеки для вашего провайдера, вы все равно не должны начинать с нуля, потому что такие инструменты, как Guzzle сделать работу с запросами HTTP гораздо проще. Guzzle обертывает библиотеку CURL PHP и удаляет многие головные боли, обычно связанные с настройкой и запросами вручную. Даже если вы делаете только один или два запроса, я бы все равно рекомендую использовать его, потому что это сделает ваш код более надежным, и установка его с композитором кусок пирога.

Настройка плагина

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


github-api/
   readme.txt
   github-api.php 

Содержит readme.txt мета данные для вашего плагина, который появится, wordpress.org если вы решите опубликовать его там. Читайте о публикации плагинов WordPress в документации, или проверить всеобъемлющий образец readme.txt.

Файл PHP также содержит некоторые метаданные в заголовке, которые будут использоваться для отображения информации о вашем плагине в панели мониторинга. Начните с заголовка, который выглядит следующим образом:


<?php
/**
Plugin Name: GitHub API
description: >-
  Add GitHub project information using shortcode
Version: 1.0
Author: Your Name
License: GPLv2 or later
Text Domain: github-api
*/

По соображениям безопасности также рекомендуется отказать в прямом доступе к файлу:

defined( 'ABSPATH' ) or die( 'No script kiddies please!' );

На данный момент, плагин не будет ничего делать, но когда вы копируете wp-content/plugins файлы, он должен появиться в списке плагинов, и вы должны быть в состоянии активировать его.

WordPress dashboard plugins page
WordPress приборной панели плагины страницы. (Посмотреть большую версию)

Далее мы хотим включить библиотеку, которая будет обрабатывать запросы API. В следующем примере кода мы включаем API PHP GitHubот KNP Labs, но вы можете включить любую зависимость, заменив пакет, который knplabs/github-api вы используете.


$ cd wp-content/plugins/github-api
$ composer require knplabs/github-api

Теперь структура файла должна выглядеть следующим образом:


github-api/
   composer.json
   composer.lock
   github-api.php 
   readme.txt
   vendor/

Теперь, когда файлы на месте, мы должны vendor/autoload.php требовать, что было создано, когда вы установили его.

require_once 'vendor/autoload.php';

Если все было настроено правильно, вы должны быть в состоянии мгновенного класса из библиотеки без фатальной ошибки быть брошены.

$testing = new GithubClient();

Но это всего лишь быстрый способ проверить, что ваши зависимости доступны. Я рекомендую определить новый класс, который расширяет библиотеку.

class MyGithub extends GithubClient {};

Это не критично, но это делает ваш код более гибким в нескольких отношениях. Наиболее очевидным способом является то, что вы можете изменить или добавить новую функциональность, если это необходимо. Но это также облегчает жизнь, если вы когда-нибудь захотите переключить библиотеки в будущем, потому что вам придется вносить изменения только в один раз, а не во всем коде.

WordPress Короткие коды

Теперь пришло время настроить наш первый короткий код, который представляет собой специальный фрагмент, который позволяет создавать содержимое, размещая его в должности или странице. Если вы совершенно новичок в коротких кодах или хотите более глубокое понимание того, как они работают, ознакомьтесь с официальной документацией shortcode. В моем примере я отобразю список проблем GitHub, где бы автор не размещал этот короткий код:[github_issues]

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


function github_issues_func( $atts ) {
   return "Hello world!";
}
add_shortcode( "github_issues", "github_issues_func" );

Теперь, если вы публикуете страницу, содержащую, [github_issues] вы должны увидеть “Привет мир”, когда вы посещаете страницу. Теперь, когда это работает, давайте навескажем вызов API.

В предыдущем разделе мы создали автозагрузку для нашей библиотеки GitHub и определили наш собственный класс, чтобы расширить ее. Теперь мы можем начать использовать его для вызовов API. Таким образом, мы добавим его в функцию обратного вызова шорт-кода. В качестве доказательства концепции, давайте забираем все проблемы в репозитории GitHub Pipeline. Доступна документация для этого метода.


function github_issues_func( $atts ) {

   // Instantiate our class
   $gh = new MyGithub();

   // Make the API call to get issues, passing in the GitHub owner and repository
   $issues = $gh->api('issue')->all('TransitScreen', 'wp-github-pipeline');

   // Handle the case when there are no issues
   if ( empty($issues) )
      return "<strong>" . __("No issues to show", 'githup-api') . "</strong>";

   // We're going to return a string. First, we open a list.
   $return = "<ul>";

   // Loop over the returned issues
   foreach( $issues as $issue ) {

      // Add a list item for each issue to the string
      // (Feel free to get fancier here)
      // Maybe make each one a link to the issue issuing $issue['url] )
      $return .= "<li>{$issue['title']}</li>";

   }

   // Don't forget to close the list
   $return .= "</ul>";

   return $return;

}
add_shortcode( 'github_issues', 'github_issues_func' );

Теперь вы должны иметь возможность просматривать ту же страницу, что мы использовали выше, чтобы проверить короткий код, и на этот раз вы должны увидеть неупорядоченный список проблем. Но подождите! Прежде чем двигаться дальше, давайте сделаем одну оптимизацию, чтобы наш код было проще в тестировании. (Вы тестируете, не так ли?!) Вместо того, чтобы использовать new в нашей функции мгновенный класс библиотеки GitHub, давайте передадим его в качестве параметра и мгновенно его только в том случае, если это необходимо.


function github_issues_func( $atts, $gh=null ) {

   // Conditionally instantiate our class
   $gh = ( $gh ) ? $gh : new MyGithub();

   …

Эта модификация напоминает шаблон впрыска зависимости, что значительно облегчает тестирование нашей функции. WordPress единицы тестирования выходит за рамки этого учебника, но это легко увидеть, как эта новая версия делает его легким для нас, чтобы передать “поддельные” данные API к функции, так что наши утверждения теста точно знать, чего ожидать.

То, что мы сделали до сих пор хорошо и хорошо для внутреннего проекта, который будет использоваться только на одном репозитории, но было бы гораздо более полезным, если пользователи могли бы настроить какой репозиторий, чтобы получить проблемы из. Давайте учредим это.

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


// Register the menu.
add_action( "admin_menu", "gh_plugin_menu_func" );
function gh_plugin_menu_func() {
   add_submenu_page( "options-general.php",  // Which menu parent
                  "GitHub",            // Page title
                  "GitHub",            // Menu title
                  "manage_options",       // Minimum capability (manage_options is an easy way to target administrators)
                  "github",            // Menu slug
                  "gh_plugin_options"     // Callback that prints the markup
               );
}

// Print the markup for the page
function gh_plugin_options() {
   if ( !current_user_can( "manage_options" ) )  {
      wp_die( __( "You do not have sufficient permissions to access this page." ) );
   }
   echo "Hello world!";
}

Теперь вы должны иметь возможность войти в панель мониторинга и увидеть новое меню GitHub в соответствии с “Настройки”, а затем нажмите на него, чтобы увидеть пустую страницу настроек с “Привет мир!”

Empty WordPress plugins page
Пустые WordPress плагины страницы. (Посмотреть большую версию)

Далее мы заменим Hello word фактическую разметку формы. Я приведу вам пример barebones, что вы можете стиль, как мало или столько, сколько вам нравится.


?>
<form method="post" action="<?php echo admin_url( 'admin-post.php'); ?>">

   <input type="hidden" name="action" value="update_github_settings" />

   <h3><?php _e("GitHub Repository Info", "github-api"); ?></h3>
   <p>
   <label><?php _e("GitHub Organization:", "github-api"); ?></label>
   <input class="" type="text" name="gh_org" value="<?php echo get_option('gh_org'); ?>" />
   </p>

   <p>
   <label><?php _e("GitHub repository (slug):", "github-api"); ?></label>
   <input class="" type="text" name="gh_repo" value="<?php echo get_option('gh_repo'); ?>" />
   </p>

   <input class="button button-primary" type="submit" value="<?php _e("Save", "github-api"); ?>" />

</form>
<?php

CSS классов я включил аттек тех, которые используются WordPress ‘ядро, которое является хорошим способом, чтобы получить пользовательские варианты страницы выглядеть достойно, без каких-либо дополнительных усилий.

Custom WordPress settings page with basic styles
Пользовательские WordPress настройки страницы с основными стилями. (Посмотреть большую версию)

Есть две важные вещи, чтобы понять об этой форме. Во-первых, конечная точка, на которая она подчиняется, должна /wp-admin/admin-post.php быть. Вы можете жестко горечью этот путь, но если веб-сайт установлен в субдиректории он не будет работать. Таким образом, мы используем admin_url() встроенный, чтобы создать его динамически.

Во-вторых, обратите внимание на скрытый вход с именем action . Эта область, как WordPress знает, что делать с должностью запрос, который получает представленные формы. Соответствует value названию крючка действия, который мы будем использовать для настройки функции обратного вызова. Название действия мы будем подключить в будет это значение, прикреплён adminpost с . Итак, в нашем случае, мы должны добавить это:


add_action( 'admin_post_update_github_settings', 'github_handle_save' );

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


function github_handle_save() {

   // Get the options that were sent
   $org = (!empty($_POST["gh_org"])) ? $_POST["gh_org"] : NULL;
   $repo = (!empty($_POST["gh_repo"])) ? $_POST["gh_repo"] : NULL;

   // Validation would go here

   // Update the values
   update_option( "gh_repo", $repo, TRUE );
   update_option("gh_org", $org, TRUE);

   // Redirect back to settings page
   // The ?page=github corresponds to the "slug" 
   // set in the fourth parameter of add_submenu_page() above.
   $redirect_url = get_bloginfo("url") . "/wp-admin/options-general.php?page=github&status=success";
   header("Location: ".$redirect_url);
   exit;
}

Пример также довольно минимален. В производственной настройке, вероятно, вы хотите добавить некоторую проверку. Кроме того, в этом примере мы автоматически переходим status=success обратно к URL- Разметка формы на самом деле не использовать его еще. Чтобы условно показать сообщение об успехе, добавьте что-то вроде следующей формы gh_plugin_options() в:


if ( isset($_GET['status']) && $_GET['status']=='success') { 
?>
   <div id="message" class="updated notice is-dismissible">
      <p><?php _e("Settings updated!", "github-api"); ?></p>
      <button type="button" class="notice-dismiss">
         <span class="screen-reader-text"><?php _e("Dismiss this notice.", "github-api"); ?></span>
      </button>
   </div>
<?php
}

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

Теперь вы должны быть в состоянии сохранить новый владелец и значения репозитория. Проверьте его, введя владельца и репозитория любого публичного проекта на GitHub. Последним шагом является возвращение к функции обратного вызова шорт-кода github_issues_func() и замена жестких значений владельца и репозитория.

…   
$issues = $gh->api("issue")->all(get_option("gh_org"), get_option("gh_repo"));
…

После того, как это на месте, вернуться на страницу, где вы добавили короткий код. Теперь вы должны видеть проблемы из того, какой проект вы установите.

Бонусный раунд: OAuth 2.0 Аутентификация

Подход, который мы использовали выше, отлично подходит для публичных репозиториев, но что делать, если мы хотим использовать этот плагин с частным репозиторием, который требует проверки подлинности? API GitHub аутентифицирует сядки с помощью протокола OAuth 2.0,который является то, что вы столкнетесь с работой с наиболее популярными API в эти дни. Основной рабочий процесс OAuth 2.0 выглядит следующим образом:

  1. Вы регистрируете приложение (иногда называемое «клиентом») у поставщика и получаете уникальный идентификатор и секретный ключ.
  2. Ваше приложение направляет запрос в конечную точку проверки подлинности поставщика, передавая приведенные выше учетные данные, а также перенаправляя URL-адрес, который провайдер использует для перенаправления запроса обратно в конечную точку приложения.
  3. Затем пользователю предлагается принять ваш запрос на доступ. В этом случае поставщик использует URL-адрес, отправленный с просьбой перенаправить пользователя обратно в приложение, а также временный код.
  4. Приложение захватывает этот код, а затем делает второй запрос, передавая этот код обратно поставщику. Поставщик отвечает с помощью токена доступа, который приложение затем использует для проверки подлинности с поставщиком.

Начнем с регистрации приложения в GitHub. Как и в случае с большинством популярных AA, этот раздел находится в зоне разработчика сайта.

GitHub new application registration page
Новая страница регистрации заявок GitHub. (Посмотреть большую версию)

Самое главное здесь является авторизация обратный url. Url-адрес перенаправления, пройдено в третий шаг, должен соответствовать тому, что вы вводите здесь, или включать его. Таким образом, во время разработки, я обычно вхожу на главную страницу сайта. Таким образом, мое приложение может перенаправить на любой путь.

Далее, мы добавим вторую форму на нашу страницу настроек, в gh_plugin_options() , для представления клиента идентификатор автором приложения и секрет.


<form method="post" action="<?php echo admin_url( 'admin-post.php'); ?>">

   <input type="hidden" name="action" value="oauth_submit" />

   <h3>Oauth 2.0</h3>

   <p>
      <label><?php _e("GitHub Application Client ID:", "github-api"); ?></label>
      <input class="" type="text" name="client_id" value="<?php echo get_option('client_id')?>" />
   </p>
   <p>
      <label><?php _e("GitHub Application Client Secret:", "github-api"); ?></label>
      <input class="" type="password" name="client_secret" value="<?php echo get_option('client_secret')?>" />
   </p>

   <input class="button button-primary" type="submit" value="<?php _e("Authorize", "github-api"); ?>" />

</form>

Чтобы облегчить жизнь, я буду использовать gitHub провайдера для OAuth 2.0 Клиент Лиги Чрезвычайных пакетов. Итак, во-первых, давайте снова воспользуем Composer для добавления зависимости:


composer require league/oauth2-github

Обратите внимание, что библиотека GitHub от KNP Labs также имеет поддержку OAuth 2.0. Таким образом, в моем конкретном примере, это несколько излишним. Но я хотел бы представить эту библиотеку, потому что она принадлежит к набору поставщиков конкретных OAuth 2.0 клиентских библиотек, которые все расширить те же рамки поддерживается могучей Лиги Чрезвычайных пакетов. Вы можете просмотреть полный список поддерживаемых поставщиков или прочитать инструкции о том, как расширить фреймворк для поддержки нового поставщика.

Давайте создадим функцию для запроса и сохранения маркера, когда пользователь представит форму. Поскольку GitHub является одним из провайдеров, уже поддерживаемых, я могу скопировать пример в его документации только с парой изменений.


function handle_oauth() {

   // If the form was just submitted, save the values
   // (Step 1 above)
   if ( isset($_POST["client_id"]) && 
         isset($_POST["client_secret"])
   ) {

   update_option( "client_id", $_POST["client_id"], TRUE );
   update_option("client_secret", $_POST["client_secret"], TRUE);

   }

   // Get the saved application info
   $client_id = get_option("client_id");
   $client_secret = get_option("client_secret");

   if ($client_id && $client_secret)   
   {
      $provider = new LeagueOAuth2ClientProviderGithub([
         "clientId"          =>  $client_id,
         "clientSecret"      =>  $client_secret,
         "redirectUri"       => admin_url("options-general.php?page=github"),
      ]);

   }   

   // If this is a form submission, start the workflow
   // (Step 2)
   if (!isset($_GET["code"]) && $_SERVER["REQUEST_METHOD"] === "POST") {

      // If we don't have an authorization code, then get one
      $authUrl = $provider->getAuthorizationUrl();
      $_SESSION["oauth2state"] = $provider->getState();
      header("Location: ".$authUrl);
      exit;

   // Check given state against previously stored one to mitigate CSRF attack
   // (Step 3 just happened and the user was redirected back)
   } elseif (empty($_GET["state"]) || ($_GET["state"] !== $_SESSION["oauth2state"])) {

      unset($_SESSION["oauth2state"]);
      exit("Invalid state");

   } else {

      // Try to get an access token (using the authorization code grant)
      // (Step 4)
      $token = $provider->getAccessToken("authorization_code", [
         "code" => $_GET["code"]
      ]);

      // Save the token for future use
      update_option( "github_token", $token->getToken(), TRUE );

   }
}

И, так же, как мы сделали с другой формой, мы должны добавить эквалд, чтобы функция была вызвана, когда форма сохраняется.


add_action( "admin_post_oauth_submit", "handle_oauth" );

Сохранение формы теперь должно отправить вас на страницу авторизации поставщика API. После авторизации приложение может использовать сохраненный маркер для запроса данных из частных репозиторий, к которым у вас есть доступ. Библиотека, которую я использую в KNP Labs, имеет удобный для этого метод.


$gh = new MyGithub();
$gh->authenticate( get_option("github_token"), NULL, GithubClient::AUTH_HTTP_TOKEN);

Библиотеки будут отличаться от того, как именно они обрабатывают аутентификацию, но так или иначе, вы пройдете в маркере, который затем сделает аутентифицированные запросы от имени пользователя.

Заключение

Мы рассмотрели много места, и я старался держать примеры как можно более минимальными, чтобы общий рабочий процесс оставался ясным. Полный исходный код из этого учебника доступен. Я надеюсь, что теперь у вас есть четкое понимание движущихся частей, участвующих в создании WordPress плагин, который потребляет сторонних услуг API, и, надеюсь, вы вдохновили, чтобы написать свой собственный WordPress API плагин.

Заключительные заметки

Источник: smashingmagazine.com

Великолепный Журнал

Великолепный, сокрушительный, разящий (см. перевод smashing) независимый журнал о веб-разработке. Основан в 2006 году в Германии. Имеет няшный дизайн и кучу крутых авторов, которых читают 2 млн человек в месяц.

Добавить комментарий

%d такие блоггеры, как: