() translation by (you can also view the original English article)
In dieser Reihe haben wir ein Plugin erstellt, mit dem Autoren Ideen und Verweise auf Inhalte, die sie in WordPress erstellen, sammeln, verwalten und speichern können.
Dabei suchen wir auch nach Möglichkeiten, wie wir unser Plugin so organisieren können, dass der Code und die Dateiorganisation klar und wartbar sind, sodass wir das Plugin im weiteren Verlauf der Entwicklung problemlos hinzufügen, entfernen und warten können Eigenschaften.
Bis zu diesem Punkt haben wir die grundlegende Dateiorganisation des Plugins sowie das Front-End zusammengestellt, aber wir haben keine Funktionen zum Speichern von Informationen in der Datenbank implementiert. Und wenn Sie keine Informationen speichern können, ist das Plugin für niemanden von Vorteil.
In diesem Beitrag kehren wir zum serverseitigen Code zurück und beginnen mit der Implementierung der folgenden Funktionen:
- Stellen Sie sicher, dass der Benutzer Post-Metadaten speichern kann
- Bereinigen Sie die Post-Metadaten
- Speichern Sie die Post-Metadaten
- Überprüfen Sie die Post-Metadaten und rufen Sie sie ab
Wir haben unsere Arbeit für uns ausgeschnitten. In diesem Artikel werden wir uns die ersten beiden Schritte ansehen und im nächsten Beitrag werden wir uns die letzten beiden Schritte ansehen.
Überprüfen von Berechtigungen
Um zu überprüfen, ob der Benutzer veröffentlichen kann, um Post-Metadaten zu speichern, müssen wir während des Serialisierungsprozesses eine Sicherheitsüberprüfung durchführen. Dazu müssen wir einen Nonce-Wert nutzen.
Ein Nonce ist eine "einmal verwendete Nummer", um URLs und Formulare vor Missbrauch zu schützen.
1. Fügen Sie eine Nonce hinzu
Um eine in unsere Meta-Box einzuführen, können wir die Funktionalität in dem Markup implementieren, das für das Rendern der Post-Vorlage verantwortlich ist. Laden Sie dazu admin/views/users-comment-navigation.php
und aktualisieren Sie die Vorlage so, dass sie einen Aufruf von wp_nonce_field
enthält:
1 |
<div id="authors-commentary-navigation"> |
2 |
|
3 |
<h2 class="nav-tab-wrapper current"> |
4 |
<a class="nav-tab nav-tab-active" href="javascript:;">Draft</a> |
5 |
<a class="nav-tab" href="javascript:;">Resources</a> |
6 |
<a class="nav-tab" href="javascript:;">Published</a> |
7 |
</h2>
|
8 |
|
9 |
<?php
|
10 |
|
11 |
// Include the partials for rendering the tabbed content
|
12 |
include_once( 'partials/drafts.php' ); |
13 |
include_once( 'partials/resources.php' ); |
14 |
include_once( 'partials/published.php' ); |
15 |
|
16 |
// Add a nonce field for security
|
17 |
wp_nonce_field( 'authors_commentary_save', 'authors_commentary_nonce' ); |
18 |
|
19 |
?>
|
20 |
|
21 |
</div>
|
Im obigen Code haben wir eine Nonce eingeführt, die der Aktion zum Speichern des Kommentars des Autors (den wir authors_commentary_nonce
genannt haben) entspricht, und ihn einem Wert zugeordnet, der von authors_commentary
identifiziert wird.
Wir werden sehen, wo dies für einen Moment ins Spiel kommt. Wenn Sie Ihren Browser laden, wird vorerst nichts Neues angezeigt. Dies liegt daran, dass die Nonce-Werte in einem ausgeblendeten Feld angezeigt werden.
Für diejenigen, die neugierig sind, können Sie die Entwicklungstools Ihres Lieblingsbrowsers starten, die Meta-Box überprüfen und im Markup Folgendes finden:
1 |
<input type="hidden" id="authors_commentary_nonce" name="authors_commentary_nonce" value="f3cd131d28"> |
Natürlich wird der value
Ihrer Nonce unterschiedlich sein.
2. Überprüfen Sie die Nonce
Um sicherzustellen, dass der Benutzer die Berechtigung zum Speichern des Beitrags hat, möchten wir drei Dinge überprüfen:
- dass der Benutzer Informationen für einen Post-Post-Typ speichert
- dass der Beitrag nicht automatisch von WordPress gespeichert wird
- dass der Benutzer tatsächlich die Berechtigung zum Speichern hat
Wir werden zwei Hilfsfunktionen schreiben, um die erste und dritte zu erreichen, und wir werden einige integrierte Funktionen verwenden, um Nummer zwei zu überprüfen (die tatsächlich in der zweiten Hilfsfunktion verwendet werden).
Lassen Sie uns zunächst den Hook und die Funktion einrichten, mit denen die Hilfsfunktionen genutzt und die Metadaten gespeichert werden. Fügen Sie im Konstruktor für Authors_Commentary_Meta_Box
die folgende Codezeile hinzu:
1 |
<?php add_action( 'save_post', array( $this, 'save_post' ) ); ?> |
Als nächstes definieren wir die Funktion. Beachten Sie, dass ich zwei Funktionen im folgenden Codeblock aufrufe. Wir werden sie gleich definieren:
1 |
<?php
|
2 |
/**
|
3 |
* Sanitizes and serializes the information associated with this post.
|
4 |
*
|
5 |
* @since 0.5.0
|
6 |
*
|
7 |
* @param int $post_id The ID of the post that's currently being edited.
|
8 |
*/
|
9 |
public function save_post( $post_id ) { |
10 |
|
11 |
/* If we're not working with a 'post' post type or the user doesn't have permission to save,
|
12 |
* then we exit the function.
|
13 |
*/
|
14 |
if ( ! $this->is_valid_post_type() || ! $this->user_can_save( $post_id, 'authors_commentary_nonce', 'authors_commentary_save' ) ) { |
15 |
return; |
16 |
}
|
17 |
|
18 |
}
|
In Anbetracht des obigen Codes weisen wir WordPress an, unsere Funktion save_post
immer dann auszulösen, wenn die Aktion save_post
aufgerufen wird. Innerhalb der Funktion sagen wir: "Wenn der Beitrag, der gespeichert wird, kein Beitragstyp" Beitrag "ist oder wenn der Benutzer keine Berechtigung zum Speichern hat, beenden Sie die Funktion."
Natürlich müssen wir die Funktionen definieren, damit die Logik funktioniert. Zuerst schreiben wir die Funktion is_valid_post_type
als private
Funktion der aktuellen Klasse. Das Array $_POST
wird überprüft, um sicherzustellen, dass es sich bei dem gespeicherten Beitragstyp tatsächlich um einen Beitrag handelt.
1 |
<?php
|
2 |
|
3 |
/**
|
4 |
* Verifies that the post type that's being saved is actually a post (versus a page or another
|
5 |
* custom post type.
|
6 |
*
|
7 |
*
|
8 |
* @since 0.5.0
|
9 |
* @access private
|
10 |
* @return bool Return if the current post type is a post; false, otherwise.
|
11 |
*/
|
12 |
private function is_valid_post_type() { |
13 |
return ! empty( $_POST['post_type'] ) && 'post' == $_POST['post_type']; |
14 |
}
|
Dann fügen wir die Funktion user_can_save
hinzu. Dies ist die Funktion, die sicherstellt, dass der Beitrag nicht von WordPress gespeichert wird. Wenn ein Benutzer die Funktion speichert, wird der mit der Beitragsaktion verknüpfte Nonce-Wert ordnungsgemäß festgelegt.
1 |
<?php
|
2 |
|
3 |
/**
|
4 |
* Determines whether or not the current user has the ability to save meta data associated with this post.
|
5 |
*
|
6 |
* @since 0.5.0
|
7 |
* @access private
|
8 |
* @param int $post_id The ID of the post being save
|
9 |
* @param string $nonce_action The name of the action associated with the nonce.
|
10 |
* @param string $nonce_id The ID of the nonce field.
|
11 |
* @return bool Whether or not the user has the ability to save this post.
|
12 |
*/
|
13 |
private function user_can_save( $post_id, $nonce_action, $nonce_id ) { |
14 |
|
15 |
$is_autosave = wp_is_post_autosave( $post_id ); |
16 |
$is_revision = wp_is_post_revision( $post_id ); |
17 |
$is_valid_nonce = ( isset( $_POST[ $nonce_action ] ) && wp_verify_nonce( $_POST[ $nonce_action ], $nonce_id ) ); |
18 |
|
19 |
// Return true if the user is able to save; otherwise, false.
|
20 |
return ! ( $is_autosave || $is_revision ) && $is_valid_nonce; |
21 |
|
22 |
}
|
Beachten Sie hier, dass wir die nonce_action
und die nonce_id
übergeben, die wir im ersten Schritt in der Vorlage definiert haben. Wir verwenden auch wp_verify_nonce
in Verbindung mit diesen Informationen.
Auf diese Weise können wir überprüfen, ob der gespeicherte Beitrag von einem Benutzer erstellt wurde, der über den richtigen Zugriff und die richtigen Berechtigungen verfügt.
Bereinigen Sie die Daten
Angenommen, der Benutzer arbeitet mit einem Standardposttyp und der Benutzer hat die Berechtigung zum Speichern von Informationen, müssen wir die Daten bereinigen.
Dazu müssen wir Folgendes tun:
- Stellen Sie sicher, dass keine der Informationen in den Post-Metadaten leer ist
- Entfernen Sie alles, was gefährlich sein könnte, um in die Datenbank zu schreiben
Nachdem wir dies getan haben, werden wir versuchen, die Informationen für jede der Meta-Boxen zu speichern. Aber zuerst arbeiten wir an der Desinfektion. Es gibt verschiedene Möglichkeiten, dies umzusetzen. Für die Zwecke dieses Beitrags werden wir dies auf möglichst einfache Weise tun: Wir werden anhand des Schlüssels prüfen, ob die Informationen vorhanden sind, und sie dann, falls vorhanden, bereinigen.
Für erfahrene Programmierer werden Sie wahrscheinlich einige Codegerüche mit dem Code bemerken, den wir schreiben werden. Später in dieser Serie werden wir einige Umgestaltungen vornehmen, um zu sehen, wie wir das Plugin wartbarer machen können, damit alles Teil der Absicht dieses bestimmten Beitrags ist.
Wenn dies gesagt ist, kehren Sie in die Funktion save_post
zurück.
1. Drafts
Da die erste Registerkarte im Meta-Feld die Registerkarte Drafts ist, beginnen wir damit. Beachten Sie, dass es sich um einen textarea
handelt. Daher sollte die Logik zur Bereinigung dieser Informationen wie folgt lauten:
- Entfernen Sie alle HTML-Tags
- Entfliehen Sie dem Inhalt des Textbereichs
Denken Sie daran, dass der textarea
als authors-commentary-drafts
bezeichnet wird, damit wir innerhalb des $_POST
-Arrays darauf zugreifen können. Um dies zu erreichen, verwenden wir den folgenden Code:
1 |
<?php
|
2 |
|
3 |
// If the 'Drafts' textarea has been populated, then we sanitize the information.
|
4 |
if ( ! empty( $_POST['authors-commentary-drafts'] ) ) { |
5 |
|
6 |
// We'll remove all white space, HTML tags, and encode the information to be saved
|
7 |
$drafts = trim( $_POST['authors-commentary-drafts'] ); |
8 |
$drafts = esc_textarea( strip_tags( $drafts ) ); |
9 |
|
10 |
// More to come...
|
11 |
|
12 |
}
|
Einfach ausgedrückt, wir prüfen, ob die Informationen im Array $_POST
leer sind. Wenn nicht, bereinigen wir die Daten.
2. Ressourcen
Dieses spezielle Feld ist etwas formvoller, weil es dynamisch ist. Das heißt, der Benutzer kann alles von null bis zu vielen Eingabefeldern haben, die wir alle verwalten müssen. Denken Sie daran, dass diese Registerkarte hauptsächlich für URLs gedacht ist. Daher müssen wir sicherstellen, dass die Informationen auf diese Weise sicher bereinigt werden.
Zunächst müssen wir eine kleine Änderung an der Funktion createInputElement
vornehmen, die in der Datei admin/assets/js/resources.js
vorhanden ist. Insbesondere müssen wir sicherstellen, dass das Namensattribut ein Array verwendet, damit wir beim Betrachten von $_POST
-Daten ordnungsgemäß darauf zugreifen und es durchlaufen können.
Stellen Sie sicher, dass die Codezeilen, die für die Erstellung des eigentlichen Elements verantwortlich sind, folgendermaßen aussehen:
1 |
// Next, create the actual input element and then return it to the caller
|
2 |
$inputElement = |
3 |
$( '<input />' ) |
4 |
.attr( 'type', 'text' ) |
5 |
.attr( 'name', 'authors-commentary-resources[' + iInputCount + ']' ) |
6 |
.attr( 'id', 'authors-commentary-resource-' + iInputCount ) |
7 |
.attr( 'value', '' ); |
Beachten Sie, dass der Schlüssel zu dem, was wir getan haben, in der Zeile liegt, in der der name
aktualisiert wird. Insbesondere platzieren wir die Anzahl der Eingaben und Indizes des Arrays.
Kehren Sie als Nächstes zur Funktion save_post
zurück und fügen Sie den folgenden Code hinzu (den wir nach dem Block diskutieren werden):
1 |
<?php
|
2 |
|
3 |
// If the 'Resources' inputs exist, iterate through them and sanitize them
|
4 |
if ( ! empty( $_POST['authors-commentary-resources'] ) ) { |
5 |
|
6 |
$resources = $_POST['authors-commentary-resources']; |
7 |
foreach ( $resources as $resource ) { |
8 |
|
9 |
$resource = esc_url( strip_tags( $resource ) ); |
10 |
|
11 |
// More to come...
|
12 |
|
13 |
}
|
14 |
|
15 |
}
|
Da wir mit einem Array von Eingaben arbeiten, müssen wir zuerst überprüfen, ob das Array nicht leer ist. Wenn dies nicht der Fall ist, müssen wir es durchlaufen, da wir nicht sicher sind, wie viele Eingaben wir verwalten müssen.
Ähnlich wie im vorherigen Block führen wir eine grundlegende Ebene der Desinfektion und Flucht durch. Dies ist etwas, das Sie so aggressiv oder entspannt machen können, wie Sie möchten. Wir werden im nächsten Beitrag auf diese Bedingung zurückkommen, wenn es Zeit ist, die Daten zu speichern.
3. Veröffentlicht
Diese Registerkarte ähnelt den vorherigen Registerkarten, da es sich um eine unbestimmte Anzahl von Elementen handelt, die bereinigt werden müssen. Dies bedeutet, dass wir eine kleine Aktualisierung des Teils vornehmen müssen, der für das Rendern dieser Eingabe verantwortlich ist.
Auf der anderen Seite haben wir es nur mit einem Kontrollkästchen zu tun, das den booleschen Wert hat, aktiviert oder nicht aktiviert zu sein (oder insbesondere "Ein" oder leer), sodass die Bereinigung der Informationen wirklich einfach ist.
Lassen Sie uns zuerst den Teil aktualisieren. Suchen Sie admin/views/partials/published.php
. Suchen Sie als Nächstes die Zeile, die das input
-Kontrollkästchen definiert, und ändern Sie sie so, dass sie folgendermaßen aussieht:
1 |
<label for="authors-commentary-comment-<?php echo $comment->comment_ID ?>"> |
2 |
<input type="checkbox" name="authors-commentary-comments[<?php echo $comment->comment_ID ?>]" id="authors-commentary-comment-<?php echo $comment->comment_ID ?>" /> |
3 |
This comment has received a reply. |
4 |
</label>
|
Beachten Sie, dass wir das name
-Attribut so geändert haben, dass ein Array mit einem Index als Wert verwendet wird. Als nächstes kehren wir noch einmal in die Funktion save_post
zurück, um die Validierung für dieses bestimmte Element einzuführen:
1 |
<?php
|
2 |
|
3 |
// If there are any values saved in the 'Resources' input, save them
|
4 |
if ( ! empty( $_POST['authors-commentary-comments'] ) ) { |
5 |
|
6 |
$comments = $_POST['authors-commentary-comments']; |
7 |
foreach ( $comments as $comment ) { |
8 |
|
9 |
$comment = strip_tags( stripslashes( $comment ) ); |
10 |
// More to come...
|
11 |
|
12 |
}
|
13 |
|
14 |
}
|
Genau wie bei den vorherigen Daten überprüfen wir zunächst, ob der Inhalt vorhanden ist. Wenn ja, dann bereinigen wir es, um es für das Speichern vorzubereiten. Wenn nicht, machen wir nichts.
Weiter zum Speichern
An diesem Punkt sind wir in der Lage, die letzten beiden Punkte der Serie zu übernehmen:
- Speichern und Abrufen
- Refactoring
Ab dem nächsten Beitrag überprüfen wir den Code, den wir in diesem Beitrag geschrieben haben, erneut, um zu sehen, wie wir ihn in der Datenbank speichern und aus der Datenbank abrufen können, um ihn im Front-End anzuzeigen.
Dann fahren wir mit dem Refactoring fort. Schließlich besteht ein Teil des Schreibens von wartbarem Code darin, sicherzustellen, dass er gut organisiert und leicht änderbar ist. Da der Code, mit dem wir täglich arbeiten, bereits geschrieben wurde und möglicherweise überarbeitet werden könnte, werden wir am Ende der Serie sehen, wie das geht.
Überprüfen Sie in der Zwischenzeit den obigen Code, überprüfen Sie die Quelle von GitHub und hinterlassen Sie alle Fragen und Kommentare im Feld unten.