Erstellen eines WordPress-Plugins, das Service-APIs verwendet, „From Soup To Nuts“
Veröffentlicht: 2022-03-10Eine immer größere Anzahl öffentlich verfügbarer APIs bietet leistungsstarke Dienste, um die Funktionalität unserer Anwendungen zu erweitern. WordPress ist ein unglaublich dynamisches und flexibles CMS, das alles unterstützt, von kleinen persönlichen Blogs bis hin zu großen E-Commerce-Websites und allem dazwischen. Ein Teil dessen, was WordPress so vielseitig macht, ist sein leistungsstarkes Plugin-System , das es unglaublich einfach macht, Funktionen hinzuzufügen.
Wir werden durchgehen, wie ich GitHub Pipeline erstellt habe, ein Plugin, mit dem Sie Daten von der GitHub-API auf WordPress-Seiten mithilfe von Shortcodes anzeigen können. Ich werde spezifische Beispiele und Code-Snippets geben, aber betrachten Sie die hier beschriebene Technik als eine Blaupause dafür, wie Sie eine beliebige Service-API mit einem Plug-in nutzen können.
Weiterführende Literatur zu SmashingMag:
- WordPress Essentials: So erstellen Sie ein WordPress-Plugin
- So stellen Sie WordPress-Plugins mit GitHub mithilfe von Transienten bereit
- Drei Ansätze zum Hinzufügen konfigurierbarer Felder zu Ihrem Plugin
Wir beginnen von vorne, aber ein gewisses Maß an Vertrautheit mit WordPress und der Plugin-Entwicklung wird vorausgesetzt, und wir werden keine Zeit mit Anfängerthemen wie der Installation von WordPress oder Composer verbringen.
Du brauchst:
- eine PHP-Umgebung mit einer Neuinstallation von WordPress;
- ein GitHub-Konto (oder ein anderer API-Anbieter, wenn Sie improvisieren möchten);
- Komponist (empfohlen).
Auswahl einer API
Der erste Schritt beim Schreiben dieser Art von Plugin ist die Auswahl einer API. In diesem Tutorial verwenden wir die GitHub-API. Wenn Sie daran denken, eine andere API zu verwenden, sollten Sie einige wichtige Faktoren berücksichtigen, die sich darauf auswirken können, wie lohnend Ihr Projekt sein wird.
Eines der ersten Dinge, auf die ich schaue, ist die Gründlichkeit und Qualität der API-Dokumentation. Wenn es spärlich oder veraltet ist, seien Sie bereit, Zeit damit zu verbringen, den Quellcode zu sichten, um Ihre eigenen Fragen zu beantworten. Überlegen Sie auch, wie ausgereift die API ist und wie verantwortungsbewusst der Anbieter sie versioniert hat. Nichts ist schlimmer, als Zeit zu investieren, um etwas Großartiges zu schaffen, nur damit es aufgrund von Änderungen an der Upstream-API kaputt geht. Suchen Sie in den Endpunkt-URLs nach einem Versionsverwaltungssystem.
// good https://api.stable.com/v1/user/ // danger https://api.dodgy.com/user/
Auf die Gefahr hin, das Offensichtliche zu betonen, beinhaltet die Programmierung mit einer Drittanbieter-API eine Vertrauensbeziehung, und nicht alle APIs sind gleich.
Einkaufen für eine Bibliothek
Etablierte Marken verteilen oft Bibliotheken oder SDKs, um die Arbeit mit ihrer API zu erleichtern. Wenn dies nicht der Fall ist, denken Sie daran zu recherchieren, ob jemand anderes bereits eine Bibliothek geschrieben hat, bevor Sie das Rad neu erfinden. Google und GitHub sind zwei großartige Orte, um mit der Recherche zu beginnen. Die Anzahl der Sterne oder Forks auf GitHub ist ein guter Hinweis darauf, wie effektiv eine Bibliothek ist. Das Alter der letzten Commits und/oder die Anzahl der offenen Probleme sind ein Hinweis darauf, wie aktiv sie gepflegt werden. In meinem Fall hatte ich das Glück, die schöne PHP GitHub API von KNP Labs zu finden.
Eigenes Schreiben mit Guzzle
Wenn es für Ihren Anbieter keine zufriedenstellende Bibliothek gibt, sollten Sie dennoch nicht bei Null anfangen, da Tools wie Guzzle die Arbeit mit HTTP-Anfragen erheblich erleichtern. Guzzle umschließt die cURL-Bibliothek von PHP und beseitigt viele der Probleme, die normalerweise mit der manuellen Konfiguration und dem manuellen Stellen von Anfragen verbunden sind. Selbst wenn Sie nur ein oder zwei Anfragen stellen, würde ich dennoch empfehlen, es zu verwenden, da es Ihren Code robuster macht und die Installation mit Composer ein Kinderspiel ist.
Einrichten des Plugins
Wir beginnen mit dem Grundgerüst eines minimalen WordPress-Plugins, einem Verzeichnis mit zwei Dateien. Die Wahl eines aussagekräftigen und eindeutigen Ordnernamens ist wichtig, um Konflikte mit anderen Plugins zu vermeiden. Wenn der Name Ihres Plugins etwas generisch ist, sollten Sie ein eindeutiges Präfix hinzufügen.
github-api/ readme.txt github-api.php
Die readme.txt
enthält die Metadaten für Ihr Plugin, die auf wordpress.org
erscheinen, wenn Sie sich entscheiden, es dort zu veröffentlichen. Lesen Sie mehr über das Veröffentlichen von WordPress-Plug-ins in der Dokumentation oder sehen Sie sich das umfassende Beispiel readme.txt an.
Die PHP-Datei enthält auch einige Metadaten im Header, die verwendet werden, um Informationen über Ihr Plugin im Dashboard anzuzeigen. Beginnen Sie mit einer Überschrift, die so aussieht:
<?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 */
Aus Sicherheitsgründen ist es auch eine gute Idee, den direkten Zugriff auf die Datei wie folgt zu verweigern:
defined( 'ABSPATH' ) or die( 'No script kiddies please!' );
An diesem Punkt wird das Plugin nichts tun, aber wenn Sie die Dateien nach wp-content/plugins
kopieren, sollte es in der Plugin-Liste erscheinen und Sie sollten es aktivieren können.

Als Nächstes möchten wir die Bibliothek einbinden, die die API-Anforderungen verarbeitet. Im folgenden Codebeispiel schließen wir die PHP-GitHub-API von KNP Labs ein, aber Sie können jede Abhängigkeit einschließen, indem Sie knplabs/github-api
durch das von Ihnen verwendete Paket ersetzen.
$ cd wp-content/plugins/github-api $ composer require knplabs/github-api
Nun sollte Ihre Dateistruktur wie folgt aussehen:
github-api/ composer.json composer.lock github-api.php readme.txt vendor/
Jetzt, da die Dateien vorhanden sind, müssen wir die bei der Installation erstellte " vendor/autoload.php
" benötigen.
require_once 'vendor/autoload.php';
Wenn alles richtig eingerichtet wurde, sollten Sie in der Lage sein, eine Klasse aus der Bibliothek zu instanziieren, ohne dass ein schwerwiegender Fehler ausgegeben wird.
$testing = new \Github\Client();
Dies ist jedoch nur ein schneller Weg, um zu testen, ob Ihre Abhängigkeiten verfügbar sind. Ich empfehle, eine neue Klasse zu definieren, die die Bibliothek erweitert.
class MyGithub extends \Github\Client {};
Dies ist nicht kritisch, aber es macht Ihren Code in mehrfacher Hinsicht flexibler. Der naheliegendste Weg ist, dass Sie bei Bedarf neue Funktionen ändern oder hinzufügen können. Aber es erleichtert auch das Leben, falls Sie in Zukunft jemals die Bibliotheken wechseln möchten, da Sie die Änderungen nur an einer Stelle vornehmen müssen, anstatt im gesamten Code.
WordPress-Shortcodes
Jetzt ist es an der Zeit, unseren ersten Shortcode einzurichten, bei dem es sich um ein spezielles Snippet handelt, mit dem Sie Inhalte generieren können, indem Sie sie in einem Beitrag oder einer Seite platzieren. Wenn Shortcodes für Sie völlig neu sind oder Sie ein tieferes Verständnis ihrer Funktionsweise wünschen, sehen Sie sich die offizielle Shortcode-Dokumentation an. In meinem Beispiel werde ich eine Liste von GitHub-Problemen anzeigen, wo immer der Autor diesen Shortcode platziert: [github_issues]
Beginnen wir wie zuvor mit einem Minimalbeispiel, um sicherzustellen, dass der Shortcode korrekt registriert ist, bevor wir an der Durchführung des API-Aufrufs arbeiten.
function github_issues_func( $atts ) { return "Hello world!"; } add_shortcode( "github_issues", "github_issues_func" );
Wenn Sie nun eine Seite veröffentlichen, die [github_issues]
enthält, sollten Sie „Hello world“ sehen, wenn Sie die Seite besuchen. Jetzt, da dies funktioniert, richten wir den API-Aufruf ein.
Im vorherigen Abschnitt haben wir das automatische Laden für unsere GitHub-Bibliothek eingerichtet und unsere eigene Klasse definiert, um sie zu erweitern. Jetzt können wir damit beginnen, API-Aufrufe zu tätigen. Also fügen wir es der Callback-Funktion des Shortcodes hinzu. Lassen Sie uns als Machbarkeitsnachweis alle Probleme im GitHub-Pipeline-Repository abrufen. Dokumentation für diese Methode ist verfügbar.
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' );
Jetzt sollten Sie dieselbe Seite sehen können, die wir oben zum Testen des Shortcodes verwendet haben, und dieses Mal sollten Sie eine ungeordnete Liste von Problemen sehen. Aber warte! Bevor wir fortfahren, nehmen wir eine Optimierung vor, damit unser Code einfacher zu testen ist. (Sie testen, richtig?!) Anstatt new
in unserer Funktion zu verwenden, um die GitHub-Bibliotheksklasse zu instanziieren, übergeben wir sie als Parameter und instanziieren sie nur, wenn wir müssen.
function github_issues_func( $atts, $gh=null ) { // Conditionally instantiate our class $gh = ( $gh ) ? $gh : new MyGithub(); …
Diese Modifikation ähnelt dem Abhängigkeitsinjektionsmuster, wodurch unsere Funktion viel einfacher zu testen ist. Das Testen von WordPress-Einheiten würde den Rahmen dieses Tutorials sprengen, aber es ist leicht zu erkennen, wie diese neue Version es uns leicht macht, „gefälschte“ API-Daten an die Funktion zu übergeben, damit die Behauptungen unseres Tests genau wissen, was zu erwarten ist.
Was wir bisher gemacht haben, ist gut und gut für ein internes Projekt, das nur auf einem einzigen Repository verwendet wird, aber es wäre viel nützlicher, wenn Benutzer konfigurieren könnten, aus welchem Repository Probleme abgerufen werden sollen. Richten wir das ein.
Zuerst verwenden wir einen WordPress-Hook, um unsere neue Einstellungsseite zu registrieren, und die Callback-Funktion definiert die Beschriftungen und Titel des Menüs. Wir verwenden den gleichen inkrementellen Ansatz, damit es funktioniert.
// 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!"; }
Jetzt sollten Sie sich beim Dashboard anmelden und das neue GitHub-Menü unter „Einstellungen“ sehen und dann darauf klicken können, um eine leere Einstellungsseite mit „Hello world!“ anzuzeigen.


Als Nächstes ersetzen wir das Hello word
durch das eigentliche Markup des Formulars. Ich gebe Ihnen ein Barebone-Beispiel, das Sie so wenig oder so viel stylen können, wie Sie möchten.
?> <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
Die CSS-Klassen, die ich eingeschlossen habe, stimmen mit denen überein, die vom WordPress-Kern verwendet werden, was eine gute Möglichkeit ist, Ihre Seite mit benutzerdefinierten Optionen ohne zusätzlichen Aufwand anständig aussehen zu lassen.

Es gibt zwei wichtige Dinge, die Sie über dieses Formular verstehen sollten. Erstens muss der Endpunkt, an den es übermittelt wird, /wp-admin/admin-post.php
sein. Sie könnten diesen Pfad fest codieren, aber wenn die Website in einem Unterverzeichnis installiert ist, funktioniert es nicht. Daher verwenden wir die integrierte admin_url()
, um sie dynamisch zu erstellen.
Beachten Sie zweitens die versteckte Eingabe mit dem Namen action
. Über dieses Feld weiß WordPress, was mit der Post-Anfrage zu tun ist, die vom Formular gesendet wird. Der value
entspricht dem Namen des Action-Hooks, den wir zum Setzen der Callback-Funktion verwenden werden. Der Name der Aktion, in die wir uns einklinken, ist dieser Wert mit dem Präfix admin post
. In unserem Fall müssen wir also Folgendes hinzufügen:
add_action( 'admin_post_update_github_settings', 'github_handle_save' );
Ich finde, dass dies einer der skurrileren, weniger intuitiven Aspekte beim Erstellen benutzerdefinierter Verwaltungsmenüs ist, aber sobald Sie sich daran gewöhnt haben, ist es ziemlich schmerzlos. Wie Sie vielleicht erraten haben, ist der zweite Parameter von add_action()
der Name unserer Callback-Funktion, die die Werte tatsächlich in der Datenbank speichert.
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; }
Das Beispiel ist auch ziemlich minimal. In einer Produktionsumgebung möchten Sie wahrscheinlich eine gewisse Validierung hinzufügen. Außerdem geben wir in diesem Beispiel automatisch status=success
an die URL zurück. Das Markup des Formulars verwendet es noch nicht. Um eine Erfolgsmeldung bedingt anzuzeigen, fügen Sie etwas wie das Folgende über dem Formular in gh_plugin_options()
:
if ( isset($_GET['status']) && $_GET['status']=='success') { ?> <div 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 }
Wenn Sie eine Validierung hinzufügen, verwenden Sie dasselbe Muster, um verschiedene Status und Nachrichten zurückzugeben, damit der Benutzer weiß, ob und warum die Übermittlung des Formulars fehlgeschlagen ist.
Jetzt sollten Sie in der Lage sein, neue Eigentümer- und Repository-Werte zu speichern. Testen Sie es, indem Sie den Eigentümer und das Repository eines beliebigen öffentlichen Projekts auf GitHub eingeben. Der letzte Schritt besteht darin, zur Shortcode-Callback-Funktion github_issues_func()
und die hartcodierten Eigentümer- und Repository-Werte zu ersetzen.
… $issues = $gh->api("issue")->all(get_option("gh_org"), get_option("gh_repo")); …
Sobald dies eingerichtet ist, besuchen Sie erneut die Seite, auf der Sie den Shortcode hinzugefügt haben. Sie sollten jetzt Probleme aus dem von Ihnen festgelegten Projekt sehen.
Bonusrunde: OAuth 2.0-Authentifizierung
Der oben verwendete Ansatz funktioniert hervorragend für öffentliche Repositorys, aber was ist, wenn wir dieses Plugin mit einem privaten Repository verwenden möchten, das eine Authentifizierung erfordert? Die GitHub-API authentifiziert sich mithilfe des OAuth 2.0-Protokolls, was Ihnen heutzutage bei der Arbeit mit den gängigsten APIs begegnen wird. Der grundlegende OAuth 2.0-Workflow sieht folgendermaßen aus:
- Sie registrieren eine Anwendung (manchmal auch als „Client“ bezeichnet) beim Anbieter und erhalten eine eindeutige ID und einen geheimen Schlüssel.
- Ihre Anwendung stellt eine Anfrage an den Authentifizierungsendpunkt des Anbieters und übergibt die oben genannten Anmeldeinformationen sowie eine Umleitungs-URL, die der Anbieter verwendet, um die Anfrage zurück an einen Endpunkt Ihrer Anwendung umzuleiten.
- Der Benutzer wird dann aufgefordert, Ihre Zugriffsanfrage zu akzeptieren. Wenn dies der Fall ist, verwendet der Anbieter die URL, die Sie mit der Anfrage gesendet haben, um den Benutzer zusammen mit einem temporären Code zurück zu Ihrer Anwendung umzuleiten.
- Ihre Anwendung erfasst diesen Code und stellt dann eine zweite Anforderung, wobei sie diesen Code an den Anbieter zurückgibt. Der Anbieter antwortet mit einem Zugriffstoken, das Ihre Anwendung dann verwendet, um sich beim Anbieter zu authentifizieren.
Wir beginnen mit der Registrierung einer Anwendung bei GitHub. Wie bei den meisten gängigen APIs befindet sich dieser Abschnitt im Entwicklerbereich der Website.

Das Wichtigste hier ist die Autorisierungs-Callback-URL. Die in Schritt 3 übergebene Umleitungs-URL muss mit der hier eingegebenen übereinstimmen oder sie enthalten. Während der Entwicklung betrete ich also normalerweise die Startseite der Website. Auf diese Weise kann meine App auf einen beliebigen Pfad umleiten.
Als Nächstes fügen wir unserer Einstellungsseite in gh_plugin_options()
ein zweites Formular hinzu, um die Client-ID und das Geheimnis der Anwendung zu übermitteln.
<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>
Um das Leben einfacher zu machen, verwende ich den GitHub-Anbieter für den OAuth 2.0-Client von The League of Extraordinary Packages. Verwenden wir also zuerst Composer erneut, um die Abhängigkeit hinzuzufügen:
composer require league/oauth2-github
Beachten Sie, dass die GitHub-Bibliothek von KNP Labs auch OAuth 2.0-Unterstützung integriert hat. In meinem speziellen Beispiel ist dies also etwas überflüssig. Aber ich wollte diese Bibliothek vorstellen, weil sie zu einer Reihe von anbieterspezifischen OAuth 2.0-Client-Bibliotheken gehört, die alle dasselbe Framework erweitern, das von der mächtigen League of Extraordinary Packages verwaltet wird. Sie können eine vollständige Liste der unterstützten Anbieter anzeigen oder Anweisungen zum Erweitern des Frameworks lesen, um einen neuen Anbieter zu unterstützen.
Erstellen wir eine Funktion zum Anfordern und Speichern des Tokens, wenn der Benutzer das Formular absendet. Da GitHub einer der bereits unterstützten Anbieter ist, kann ich das Beispiel in seiner Dokumentation mit nur wenigen Änderungen kopieren.
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 League\OAuth2\Client\Provider\Github([ "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 ); } }
Und genau wie bei dem anderen Formular müssen wir den Action-Hook hinzufügen, damit die Funktion aufgerufen wird, wenn das Formular gespeichert wird.
add_action( "admin_post_oauth_submit", "handle_oauth" );
Beim Speichern des Formulars sollten Sie nun zur Autorisierungsseite des API-Anbieters weitergeleitet werden. Nach der Autorisierung kann Ihre Anwendung das gespeicherte Token verwenden, um Daten aus privaten Repositories anzufordern, auf die Sie Zugriff haben. Die Bibliothek, die ich von KNP Labs verwende, hat dafür eine praktische Methode.
$gh = new MyGithub(); $gh->authenticate( get_option("github_token"), NULL, Github\Client::AUTH_HTTP_TOKEN);
Bibliotheken unterscheiden sich genau darin, wie sie die Authentifizierung handhaben, aber auf die eine oder andere Weise werden Sie das Token weitergeben, das dann authentifizierte Anforderungen im Namen eines Benutzers stellt.
Fazit
Wir haben viele Bereiche abgedeckt, und ich habe versucht, die Beispiele so gering wie möglich zu halten, damit der gesamte Arbeitsablauf klar bleibt. Der vollständige Quellcode aus diesem Tutorial ist verfügbar. Ich hoffe, Sie haben jetzt ein klares Verständnis für die beweglichen Teile, die beim Erstellen eines WordPress-Plugins erforderlich sind, das Dienst-APIs von Drittanbietern nutzt, und hoffentlich sind Sie inspiriert, Ihr eigenes WordPress-API-Plugin zu schreiben.
Schlussbemerkungen
- WordPress Codex (Dokumentation)
- GitHub-API (Dokumentation)
- OAuth 2.0 (Dokumentation)
- Komponist (Dokumentation)
- Die Liga der außergewöhnlichen Pakete
- Guzzle-Dokumentation