() translation by (you can also view the original English article)
Im vorherigen Beitrag dieser Reihe haben wir das Thema der Arbeit mit Ajax in WordPress erneut aufgegriffen. Letztendlich ist es das Ziel, eine frühere Serie zu verbessern, die vor einigen Jahren auf der Website lief.
Um es noch einmal zu wiederholen: Es ist nicht so, dass die in der Originalserie gelehrten Techniken falsch waren, aber es ist so, dass sich die Software im Laufe der Zeit ändert. Daher ist es immer gut, Konzepte, die vor Jahren behandelt wurden, erneut zu betrachten und zu versuchen, sie auf etwas zu aktualisieren, das etwas aktueller und belastbarer ist für unsere Entwicklungsbemühungen.
Wir erinnern uns an den vorherigen Beitrag und haben uns den folgenden Kommentar aus der Originalserie angesehen:
Wir werden einen sehr kurzen Überblick darüber geben, was Ajax ist, wie es funktioniert, wie es auf der Vorderseite eingerichtet wird und welche Hooks WordPress bietet. Wir werden auch ein kleines Projekt bauen, das die Theorie in die Praxis umsetzt. Wir werden den Quellcode durchgehen und sicherstellen, dass er auch auf GitHub verfügbar ist.
In diesem Beitrag haben wir einige erweiterte Möglichkeiten zur Integration der WordPress Ajax-API in unsere Projekte mithilfe der prozeduralen Programmierung besprochen. In diesem Beitrag nehmen wir den Code, den wir im ersten Teil dieser Serie geschrieben haben, und überarbeiten ihn so, dass er einen objektorientierten Ansatz verwendet.
Letztendlich geht es nicht darum, zu begründen, warum ein Paradigma über das andere angewendet werden sollte; Stattdessen soll gezeigt werden, wie wir dieselbe Funktionalität erreichen können, unabhängig davon, welchen Ansatz Sie beim Erstellen Ihrer Plugins wählen.
Plugin planen
Bevor wir mit der Überarbeitung des Codes beginnen, müssen wir uns überlegen, wie wir die verschiedenen Dateien anordnen. Schließlich besteht ein Teil des Prozesses, ein neues Projekt zu beginnen - oder sogar in ein altes zu springen - darin, zu planen, wie die Arbeit erledigt werden soll.
Für dieses spezielle Plugin benötigen wir Folgendes:
- Eine Bootstrap-Datei, die für die Initialisierung der Hauptklasse und den Start des Plugins verantwortlich ist
- Eine Klasse, die für das Laden der Abhängigkeiten verantwortlich ist, z. B. JavaScript
- Eine Klasse, die als Haupt-Plugin-Klasse dient
Wie Sie sehen, müssen wir nicht zu viel mit dem Plugin tun. Wir werden auch einige der Dateien neu organisieren, um eine konsistente Verzeichnisstruktur zu erhalten, und wir werden sicherstellen, dass der gesamte Code ordnungsgemäß dokumentiert wird, damit er den WordPress-Codierungsstandards entspricht.
Nachdem dies gesagt ist, fangen wir an.
Organisieren der Dateien
Bevor wir mit dem Schreiben von Code beginnen, gehen wir wie folgt vor:
- Erstellen Sie ein
assets
-Verzeichnis. - Erstellen Sie ein
js
-Verzeichnis, das sich imassets
-Verzeichnis befindet. - Verschieben Sie
frontend.js
in das Verzeichnisjs
.



Der Grund dafür ist, dass wir uns einem objektorientierten Programmierstil zuwenden. Ein Teil davon besteht darin, unsere Dateien so zu organisieren, dass sie Konventionen entsprechen, die oft als Pakete betrachtet werden.
In unserem Fall enthält das assets
-Verzeichnis alle Dinge, die zum Ausführen des Programms erforderlich sind. Bei einigen Plugins kann dies JavaScript, CSS, Bilder, Schriftarten usw. sein. In diesem Fall haben wir eine einzelne JavaScript-Datei.
Der Abhängigkeitslader
Als nächstes müssen wir eine Klasse einführen, die für das Laden der Abhängigkeiten für unser Projekt verantwortlich ist. Für dieses spezielle Plugin ist die einzige Abhängigkeit, die wir haben, die JavaScript-Datei, die wir gerade im assets
-Verzeichnis abgelegt haben.
Ein Teil der objektorientierten Programmierung besteht darin, sicherzustellen, dass jede Klasse einen bestimmten Zweck hat. In diesem Fall ist die Klasse, die wir einführen werden, für das Laden des JavaScript mithilfe der WordPress-API verantwortlich.
Beginnen wir mit der Erstellung der Grundstruktur der Klasse:
1 |
<?php
|
2 |
|
3 |
/**
|
4 |
* Loads and enqueues dependencies for the plugin.
|
5 |
*
|
6 |
* @since 1.0.0
|
7 |
*
|
8 |
* @package WPA/includes
|
9 |
*/
|
10 |
class Dependency_Loader { |
11 |
|
12 |
}
|
Als Nächstes fügen wir eine Methode hinzu, die für das Einreihen des JavaScript gemäß der WordPress-API verantwortlich ist.
1 |
<?php
|
2 |
/**
|
3 |
* Loads and registers dependencies.
|
4 |
*
|
5 |
* @since 1.0.0
|
6 |
*
|
7 |
* @package WPA
|
8 |
* @author Tom McFarlin
|
9 |
* @license https://www.gnu.org/licenses/gpl-2.0.txt
|
10 |
* @link https://tommcfarlin.com/
|
11 |
*/
|
12 |
|
13 |
/**
|
14 |
* Loads and enqueues dependencies for the plugin.
|
15 |
*
|
16 |
* @package WPA
|
17 |
* @subpackage WPA/includes
|
18 |
* @since 1.0.0
|
19 |
* @author Tom McFarlin
|
20 |
* @license http://www.gnu.org/licenses/gpl-2.0.txt
|
21 |
* @link https://tommcfarlin.com/
|
22 |
*/
|
23 |
class Dependency_Loader { |
24 |
|
25 |
/**
|
26 |
* Initializes the plugin by enqueuing the necessary dependencies.
|
27 |
*
|
28 |
* @since 1.0.0
|
29 |
*/
|
30 |
public function initialize() { |
31 |
$this->enqueue_scripts(); |
32 |
}
|
33 |
|
34 |
/**
|
35 |
* Enqueues the front-end scripts for getting the current user's information
|
36 |
* via Ajax.
|
37 |
*
|
38 |
* @access private
|
39 |
*
|
40 |
* @since 1.0.0
|
41 |
*/
|
42 |
private function enqueue_scripts() { |
43 |
|
44 |
wp_enqueue_script( |
45 |
'ajax-script', |
46 |
plugin_dir_url( dirname( __FILE__ ) ) . 'assets/js/frontend.js', |
47 |
array( 'jquery' ) |
48 |
);
|
49 |
|
50 |
wp_localize_script( |
51 |
'ajax-script', |
52 |
'sa_demo', |
53 |
array( 'ajax_url' => admin_url( 'admin-ajax.php' ) ) |
54 |
);
|
55 |
|
56 |
}
|
57 |
}
|
Danach müssen wir die Funktionen übernehmen, die für die Bearbeitung der Ajax-Anforderungen und die Bereitstellung von Antworten verantwortlich sind, und sie dann der Klasse hinzufügen. Da sie sich im Kontext einer Klasse befinden, müssen wir eine neue Funktion hinzufügen, die sie bei WordPress registriert.
Wir erstellen eine setup_ajax_handlers
-Funktion. Es sieht aus wie das:
1 |
<?php |
2 |
|
3 |
/** |
4 |
* Registers the callback functions responsible for providing a response |
5 |
* to Ajax requests setup throughout the rest of the plugin. |
6 |
* |
7 |
* @since 1.0.0 |
8 |
*/ |
9 |
public function setup_ajax_handlers() { |
10 |
|
11 |
add_action( |
12 |
'wp_ajax_get_current_user_info', |
13 |
array( $this, 'get_current_user_info' ) |
14 |
); |
15 |
|
16 |
add_action( |
17 |
'wp_ajax_nopriv_get_current_user_info', |
18 |
array( $this, 'get_current_user_info' ) |
19 |
); |
20 |
|
21 |
} |
Als nächstes müssen wir die Funktionen tatsächlich in diese Klasse verschieben. Beachten Sie, dass die Funktionen, denen ursprünglich _sa
vorangestellt wurde, nicht mehr als solche gekennzeichnet sind. Da sie sich im Kontext der Klasse befinden, können wir das Präfix und den Unterstrich zugunsten des private
Schlüsselworts löschen.
1 |
<?php
|
2 |
|
3 |
public function get_current_user_info() { |
4 |
|
5 |
$user_id = get_current_user_id(); |
6 |
|
7 |
if ( $this->user_is_logged_in( $user_id ) && $this->user_exists( $user_id ) ) { |
8 |
|
9 |
wp_send_json_success( |
10 |
wp_json_encode( get_user_by( 'id', $user_id ) ) |
11 |
);
|
12 |
|
13 |
}
|
14 |
|
15 |
}
|
16 |
|
17 |
private function user_is_logged_in( $user_id ) { |
18 |
|
19 |
$is_logged_in = true; |
20 |
|
21 |
if ( 0 === $user_id ) { |
22 |
|
23 |
wp_send_json_error( |
24 |
new WP_Error( '-2', 'The visitor is not currently logged into the site.' ) |
25 |
);
|
26 |
|
27 |
$is_logged_in = false; |
28 |
|
29 |
}
|
30 |
|
31 |
return $is_logged_in; |
32 |
|
33 |
}
|
34 |
|
35 |
private function user_exists( $user_id ) { |
36 |
|
37 |
$user_exists = true; |
38 |
|
39 |
if ( false === get_user_by( 'id', $user_id ) ) { |
40 |
|
41 |
wp_send_json_error( |
42 |
new WP_Error( '-1', 'No user was found with the specified ID [' . $user_id . ']' ) |
43 |
);
|
44 |
|
45 |
$user_exists = false; |
46 |
|
47 |
}
|
48 |
|
49 |
return $user_exists; |
50 |
|
51 |
}
|
Dann speichern wir diese Datei in einem includes
-Verzeichnis im Stammverzeichnis des Plugin-Verzeichnisses. Im includes
-Verzeichnis befindet sich häufig Code, der im gesamten Projekt verwendet wird. Zu diesem bestimmten Verzeichnis könnte mehr gesagt werden, aber das ist Inhalt für einen längeren Beitrag.
Die endgültige Version dieser Klasse sollte folgendermaßen aussehen:
1 |
<?php
|
2 |
/**
|
3 |
* Loads and registers dependencies.
|
4 |
*
|
5 |
* @since 1.0.0
|
6 |
*
|
7 |
* @package WPA
|
8 |
* @author Tom McFarlin
|
9 |
* @license http://www.gnu.org/licenses/gpl-2.0.txt
|
10 |
* @link https://tommcfarlin.com/
|
11 |
*/
|
12 |
|
13 |
/**
|
14 |
* Loads and enqueues dependencies for the plugin.
|
15 |
*
|
16 |
* @package WPA
|
17 |
* @subpackage WPA/includes
|
18 |
* @since 1.0.0
|
19 |
* @author Tom McFarlin
|
20 |
* @license http://www.gnu.org/licenses/gpl-2.0.txt
|
21 |
* @link https://tommcfarlin.com/
|
22 |
*/
|
23 |
class Dependency_Loader { |
24 |
|
25 |
/**
|
26 |
* Initializes the plugin by enqueuing the necessary dependencies.
|
27 |
*
|
28 |
* @since 1.0.0
|
29 |
*/
|
30 |
public function initialize() { |
31 |
$this->enqueue_scripts(); |
32 |
}
|
33 |
|
34 |
/**
|
35 |
* Enqueues the front-end scripts for getting the current user's information
|
36 |
* via Ajax.
|
37 |
*
|
38 |
* @access private
|
39 |
*
|
40 |
* @since 1.0.0
|
41 |
*/
|
42 |
private function enqueue_scripts() { |
43 |
|
44 |
wp_enqueue_script( |
45 |
'ajax-script', |
46 |
plugin_dir_url( dirname( __FILE__ ) ) . 'assets/js/frontend.js', |
47 |
array( 'jquery' ) |
48 |
);
|
49 |
|
50 |
wp_localize_script( |
51 |
'ajax-script', |
52 |
'sa_demo', |
53 |
array( 'ajax_url' => admin_url( 'admin-ajax.php' ) ) |
54 |
);
|
55 |
|
56 |
}
|
57 |
|
58 |
/**
|
59 |
* Registers the callback functions responsible for providing a response
|
60 |
* to Ajax requests setup throughout the rest of the plugin.
|
61 |
*
|
62 |
* @since 1.0.0
|
63 |
*/
|
64 |
public function setup_ajax_handlers() { |
65 |
|
66 |
add_action( |
67 |
'wp_ajax_get_current_user_info', |
68 |
array( $this, 'get_current_user_info' ) |
69 |
);
|
70 |
|
71 |
add_action( |
72 |
'wp_ajax_nopriv_get_current_user_info', |
73 |
array( $this, 'get_current_user_info' ) |
74 |
);
|
75 |
|
76 |
}
|
77 |
|
78 |
/**
|
79 |
* Retrieves information about the user who is currently logged into the site.
|
80 |
*
|
81 |
* This function is intended to be called via the client-side of the public-facing
|
82 |
* side of the site.
|
83 |
*
|
84 |
* @since 1.0.0
|
85 |
*/
|
86 |
public function get_current_user_info() { |
87 |
|
88 |
$user_id = get_current_user_id(); |
89 |
|
90 |
if ( $this->user_is_logged_in( $user_id ) && $this->user_exists( $user_id ) ) { |
91 |
|
92 |
wp_send_json_success( |
93 |
wp_json_encode( get_user_by( 'id', $user_id ) ) |
94 |
);
|
95 |
|
96 |
}
|
97 |
|
98 |
}
|
99 |
|
100 |
/**
|
101 |
* Determines if a user is logged into the site using the specified user ID. If not,
|
102 |
* then the following error code and message will be returned to the client:
|
103 |
*
|
104 |
* -2: The visitor is not currently logged into the site.
|
105 |
*
|
106 |
* @access private
|
107 |
* @since 1.0.0
|
108 |
*
|
109 |
* @param int $user_id The current user's ID.
|
110 |
*
|
111 |
* @return bool $is_logged_in Whether or not the current user is logged in.
|
112 |
*/
|
113 |
private function user_is_logged_in( $user_id ) { |
114 |
|
115 |
$is_logged_in = true; |
116 |
|
117 |
if ( 0 === $user_id ) { |
118 |
|
119 |
wp_send_json_error( |
120 |
new WP_Error( '-2', 'The visitor is not currently logged into the site.' ) |
121 |
);
|
122 |
|
123 |
$is_logged_in = false; |
124 |
|
125 |
}
|
126 |
|
127 |
return $is_logged_in; |
128 |
|
129 |
}
|
130 |
|
131 |
/**
|
132 |
* Determines if a user with the specified ID exists in the WordPress database. If not, then will
|
133 |
* the following error code and message will be returned to the client:
|
134 |
*
|
135 |
* -1: No user was found with the specified ID [ $user_id ].
|
136 |
*
|
137 |
* @access private
|
138 |
* @since 1.0.0
|
139 |
*
|
140 |
* @param int $user_id The current user's ID.
|
141 |
*
|
142 |
* @return bool $user_exists Whether or not the specified user exists.
|
143 |
*/
|
144 |
private function user_exists( $user_id ) { |
145 |
|
146 |
$user_exists = true; |
147 |
|
148 |
if ( false === get_user_by( 'id', $user_id ) ) { |
149 |
|
150 |
wp_send_json_error( |
151 |
new WP_Error( '-1', 'No user was found with the specified ID [' . $user_id . ']' ) |
152 |
);
|
153 |
|
154 |
$user_exists = false; |
155 |
|
156 |
}
|
157 |
|
158 |
return $user_exists; |
159 |
|
160 |
}
|
161 |
}
|
Die Hauptklasse
Jetzt können wir die Hauptklasse für das Plugin schreiben. Diese bestimmte Klasse befindet sich im Stammverzeichnis des Plugin-Verzeichnisses und die Grundstruktur der Klasse sieht folgendermaßen aus:
1 |
<?php
|
2 |
|
3 |
/**
|
4 |
* Loads and enqueues dependencies for the plugin.
|
5 |
*
|
6 |
* @since 1.0.0
|
7 |
*
|
8 |
* @package WPA
|
9 |
*/
|
10 |
class WP_Simple_Ajax { |
11 |
|
12 |
}
|
Als Nächstes fügen wir einige Eigenschaften hinzu, die wir festlegen, wenn die Klasse instanziiert wird:
1 |
<?php
|
2 |
|
3 |
class WP_Simple_Ajax { |
4 |
|
5 |
private $version; |
6 |
|
7 |
private $loader; |
8 |
|
9 |
}
|
Danach erstellen wir einen Konstruktor und eine Initialisierungsfunktion, mit denen das Plugin in Bewegung gesetzt wird:
1 |
<?php
|
2 |
/**
|
3 |
* The primary class for the plugin
|
4 |
*
|
5 |
* Stores the plugin version, loads and enqueues dependencies
|
6 |
* for the plugin.
|
7 |
*
|
8 |
* @since 1.0.0
|
9 |
*
|
10 |
* @package WPA
|
11 |
* @author Tom McFarlin
|
12 |
* @license http://www.gnu.org/licenses/gpl-2.0.txt
|
13 |
* @link https://tommcfarlin.com/
|
14 |
*/
|
15 |
|
16 |
/**
|
17 |
* Stores the plugin version, loads and enqueues dependencies
|
18 |
* for the plugin.
|
19 |
*
|
20 |
* @package WPA
|
21 |
* @author Tom McFarlin
|
22 |
* @license http://www.gnu.org/licenses/gpl-2.0.txt
|
23 |
* @link https://tommcfarlin.com/
|
24 |
*/
|
25 |
class WP_Simple_Ajax { |
26 |
|
27 |
/**
|
28 |
* Represents the current version of this plugin.
|
29 |
*
|
30 |
* @access private
|
31 |
* @since 1.0.0
|
32 |
* @var string
|
33 |
*/
|
34 |
private $version; |
35 |
|
36 |
/**
|
37 |
* A reference to the Dependency Loader.
|
38 |
*
|
39 |
* @access private
|
40 |
* @since 1.0.0
|
41 |
* @var Dependency_Loader
|
42 |
*/
|
43 |
private $loader; |
44 |
|
45 |
/**
|
46 |
* Initializes the properties of the class.
|
47 |
*
|
48 |
* @access private
|
49 |
* @since 1.0.0
|
50 |
*/
|
51 |
public function __construct() { |
52 |
|
53 |
$this->version = '1.0.0'; |
54 |
$this->loader = new Dependency_Loader(); |
55 |
|
56 |
}
|
57 |
|
58 |
/**
|
59 |
* Initializes this plugin and the dependency loader to include
|
60 |
* the JavaScript necessary for the plugin to function.
|
61 |
*
|
62 |
* @access private
|
63 |
* @since 1.0.0
|
64 |
*/
|
65 |
public function initialize() { |
66 |
|
67 |
$this->loader->initialize(); |
68 |
$this->loader->setup_ajax_handlers(); |
69 |
|
70 |
}
|
71 |
}
|
Im obigen Code legt der Konstruktor die Eigenschaften fest und instanziiert die Abhängigkeiten, die erforderlich sind, um das Plugin in Bewegung zu setzen.
Wenn initialize aufgerufen wird, wird das Plugin gestartet und die initialize
-Methode für die Abhängigkeitsklasse aufgerufen, die wir zuvor in diesem Lernprogramm erstellt haben.
Der Bootstrap
Das Letzte, was wir tun müssen, ist, die Hauptdatei, die wir haben, zu nehmen, die include
-Funktionen von PHP zu verwenden und sicherzustellen, dass sie über die erforderlichen PHP-Dateien informiert sind, die wir haben.
1 |
<?php
|
2 |
|
3 |
/**
|
4 |
* Loads and registers dependencies.
|
5 |
*/
|
6 |
include_once( 'includes/class-dependency-loader.php' ); |
7 |
|
8 |
/**
|
9 |
* The primary class for the plugin
|
10 |
*/
|
11 |
include_once( 'class-wp-simple-ajax.php' ); |
Danach müssen wir eine Methode definieren, die die Haupt-Plugin-Datei initialisiert und alles in Bewegung setzt.
1 |
<?php
|
2 |
|
3 |
/**
|
4 |
* Instantiates the main class and initializes the plugin.
|
5 |
*/
|
6 |
function wpa_start_plugin() { |
7 |
|
8 |
$plugin = new WP_Simple_Ajax(); |
9 |
$plugin->initialize(); |
10 |
|
11 |
}
|
Die endgültige Version der Bootstrap-Datei sollte folgendermaßen aussehen:
1 |
<?php
|
2 |
/**
|
3 |
* This plugin demonstrates how to use the WordPress Ajax APIs.
|
4 |
*
|
5 |
* @package WPA
|
6 |
*
|
7 |
* @wordpress-plugin
|
8 |
* Plugin Name: Simple Ajax Demo
|
9 |
* Description: A simple demonstration of the WordPress Ajax APIs.
|
10 |
* Version: 1.0.0
|
11 |
* Author: Tom McFarlin
|
12 |
* Author URI: https://tommcfarlin.com/
|
13 |
* License: GPL-2.0+
|
14 |
* License URI: http://www.gnu.org/licenses/gpl-2.0.txt
|
15 |
*/
|
16 |
|
17 |
// If this file is called directly, abort.
|
18 |
if ( ! defined( 'WPINC' ) ) { |
19 |
die; |
20 |
}
|
21 |
|
22 |
/**
|
23 |
* Loads and registers dependencies.
|
24 |
*/
|
25 |
include_once( 'includes/class-dependency-loader.php' ); |
26 |
|
27 |
/**
|
28 |
* The primary class for the plugin
|
29 |
*/
|
30 |
include_once( 'class-wp-simple-ajax.php' ); |
31 |
|
32 |
/**
|
33 |
* Instantiates the main class and initializes the plugin.
|
34 |
*/
|
35 |
function wpa_start_plugin() { |
36 |
|
37 |
$plugin = new WP_Simple_Ajax(); |
38 |
$plugin->initialize(); |
39 |
|
40 |
}
|
41 |
wpa_start_plugin(); |
Zunächst prüft die Datei, ob direkt auf sie zugegriffen wird, indem überprüft wird, ob eine WordPress-Konstante definiert wurde. Wenn nicht, wird die Ausführung gestoppt.
Danach enthält es die verschiedenen Klassen, die wir in diesem Tutorial erstellt haben. Schließlich definiert es eine Funktion, die aufgerufen wird, wenn WordPress das Plugin lädt, das das Plugin startet und alles in Bewegung setzt.
Abschluss
Und das bringt uns zum Ende dieser zweiteiligen Serie. Hoffentlich haben Sie nicht nur einige der Best Practices für die Integration von Ajax in Ihre WordPress-Projekte gelernt, sondern auch ein wenig über das Dokumentieren von prozeduralem und objektorientiertem Code sowie über den Unterschied in der Anordnung des Codes.
In einem zukünftigen Beitrag werde ich möglicherweise einige der hier vorgestellten objektorientierten Konzepte erneut betrachten und sie ausführlicher behandeln. Sehen Sie sich jedoch zunächst das Plugin über den GitHub-Link in der Seitenleiste dieser Seite an.
Denken Sie daran, Sie können alle meine Kurse und Tutorials auf meiner Profilseite abrufen und mir auf meinem Blog und/oder Twitter unter @tommcfarlin folgen, wo ich über Softwareentwicklung im Kontext von WordPress spreche.
Bitte zögern Sie nicht, wie üblich Fragen oder Kommentare im unten stehenden Feed zu hinterlassen, und ich werde versuchen, auf jede dieser Fragen zu antworten.