Когда мы подойдем к концу этой серии, у нас появятся еще две темы:
- Сохранение информации и извлечение информации из базы данных
- Рефакторинг кода, чтобы он стал более понятным для нас
В предыдущей статье мы рассмотрели проверку, дезинфекцию и реализацию этой функциональности для элементов, которые мы отображали во внешнем интерфейсе. В этой статье мы продолжим процесс, сохранив информацию в базе данных, извлекая информацию и отображая ее во внешнем интерфейсе.
Попутно мы также рассмотрим некоторые встроенные функции WordPress API, разработанные, чтобы помочь сделать это немного проще для нас, а также несколько советов для двойной проверки нашей работы в базе данных, чтобы убедиться, что наша информация сохраняется. именно так, как мы ожидаем.
Нам нужно еще немного, чтобы воплотить этот плагин в жизнь, так что давайте начнем.
Сохранение данных
Чтобы отобразить данные на внешнем интерфейсе, нам, очевидно, нужно сначала поместить их в базу данных. Поскольку мы работаем с мета-блоками, мы можем использовать функции, которые доступны через Meta Box API, чтобы сохранить эту информацию.
В частности, мы будем работать со следующими функциями:
-
update_post_meta
для сохранения информации в базе данных -
delete_post_meta
для удаления информации из базы данных
Есть еще одна функция, add_post_meta
, которая также доступна для записи информации в базу данных; однако update_post_meta
делает то же самое, если данные еще не существуют в базе данных.
Другой вопрос, который я видел, возникает, когда дело доходит до удаления метаданных поста, почему? То есть зачем удалять информацию, а не сохранять пустое значение?
Вы можете утверждать, что это личное предпочтение — и это так, — но если вы работаете со сложным плагином, который имеет несколько различных полей, и поля не имеют значения, то имеет смысл не поддерживать пустую строку.
Кроме того, если отсутствие значения не имеет смысла для чего-либо в пользовательском интерфейсе, то также нет причин поддерживать пустое значение, поскольку мы позволяем базе данных более точно отражать информацию, отображаемую на экране.
Сохранение пользовательского интерфейса, кода прикладного уровня и базы данных настолько согласованными, насколько это возможно, полезно при попытке написания поддерживаемого кода.
Итак, с учетом сказанного, давайте рассмотрим процесс сохранения полей для каждого из наших полей ввода.
1. Проект
Вспомните из предыдущего поста, что вкладка « Черновик » содержит одну textarea
, предназначенную для того, чтобы авторы могли собирать различные заметки и URL-адреса со всего Интернета, которые имеют отношение к контенту, который они готовят к публикации.
Когда мы последний раз оставляли этот код, у нас было следующее:
01
02
03
04
05
06
07
08
09
10
11
12
|
<?php
// If the ‘Drafts’ textarea has been populated, then we sanitize the information.
if ( ! empty( $_POST[‘authors-commentary-drafts’] ) ) {
// We’ll remove all white space, HTML tags, and encode the information to be saved
$drafts = trim( $_POST[‘authors-commentary-drafts’] );
$drafts = esc_textarea( strip_tags( $drafts ) );
// More to come…
}
|
Здесь мы посмотрим, заполнено ли содержимое массива $_POST
. Если это так, мы затем esc_textarea
информацию, используя trim
и esc_textarea
.
На данный момент мы готовы записать его в базу данных, поэтому давайте заменим строку, которая читает // More to come...
следующим кодом (обратите внимание, что мы более подробно рассмотрим код после блок):
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
|
<?php
// If the ‘Drafts’ textarea has been populated, then we sanitize the information.
if ( ! empty( $_POST[‘authors-commentary-drafts’] ) ) {
// We’ll remove all white space, HTML tags, and encode the information to be saved
$drafts = trim( $_POST[‘authors-commentary-drafts’] );
$drafts = esc_textarea( strip_tags( $drafts ) );
update_post_meta( $post_id, ‘authors-commentary-drafts’, $drafts );
} else {
if ( » !== get_post_meta( $post_id, ‘authors-commentary-drafts’, true ) ) {
delete_post_meta( $post_id, ‘authors-commentary-drafts’ );
}
}
|
Здесь мы используем функцию update_post_meta
для добавления или обновления содержимого в базе данных. Обратите внимание, что функция принимает три параметра:
- Идентификатор поста, который используется для связи этой информации с постом.
- Мета-ключ, который используется для уникальной идентификации значения
- Фактическое мета-значение, связанное с мета-ключом
Также обратите внимание, что если значение массива $_POST
пусто, мы проверяем, есть ли значение для черновика в базе данных, и, если оно существует, мы удаляем его.
2. Ресурсы
Поскольку мы уже заложили все основы для дезинфекции информации и увидели, как обновлять и удалять информацию в базе данных, делать то же самое для вкладки « Ресурсы » — это почти то же самое.
Единственное исключение состоит в том, что, поскольку мы имеем дело с динамическим набором информации, нам необходимо динамически связать сообщение с уникальным идентификатором на основе того, сколько ресурсов мы экономим.
В предыдущем посте наш код выглядел так:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
|
<?php
// If the ‘Resources’ inputs exist, iterate through them and sanitize them
if ( ! empty( $_POST[‘authors-commentary-resources’] ) ) {
$resources = $_POST[‘authors-commentary-resources’];
foreach ( $resources as $resource ) {
$resource = esc_url( strip_tags( $resource ) );
// More to come…
}
}
|
Когда дело доходит до динамической обработки информации, цикл foreach
работает отлично; однако при сохранении информации нам нужно ассоциировать уникальный ключ с каждым значением.
Одним из вариантов может быть установка цикла for, чтобы суффиксировать мета-ключ уникальным ключом (используя итератор для каждого значения в цикле), но это может вызвать проблемы при удалении информации. В частности, если пользователь вводит значение для первого, второго и третьего ввода, но затем удаляет второй ввод, оставляя только первое и третье при обновлении записи, нам нужно правильно удалить эти пустые значения и соответственно сместить все записи.
Это можно сделать несколькими различными способами, но на самом деле проще сохранить один сериализованный массив в уникальный индекс, а не пытаться делать что-либо необычное со строками базы данных, запросами и так далее.
Таким образом, мы обновляем код выше, чтобы выглядеть так:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
|
<?php
// If the ‘Resources’ inputs exist, iterate through them and sanitize them
if ( ! empty( $_POST[‘authors-commentary-resources’] ) ) {
$resources = $_POST[‘authors-commentary-resources’];
$sanitized_resources = array();
foreach ( $resources as $resource ) {
$resource = esc_url( strip_tags( $resource ) );
if ( ! empty( $resource ) ) {
$sanitized_resources[] = $resource;
}
}
update_post_meta( $post_id, ‘authors-commentary-resources’, $sanitized_resources );
}
|
Если вы загляните в базу данных и посмотрите на этот конкретный ключ, вы должны увидеть что-то вроде этого, сохраненное в качестве значения:
1
|
a:3:{i:0;s:22:»http://tommcfarlin.com»;i:1;s:19:»http://tutsplus.com»;i:2;s:17:»http://google.com»;}
|
Мы увидим, как это получится, когда мы получим информацию из базы данных позже в этой статье. Также обратите внимание, что нам нужно учитывать случай, когда пользователь удалил все экземпляры ресурсов.
Как и в первой части статьи, мы просто удаляем метаданные публикации, если значение существует. Это можно сделать с помощью очень похожего кода:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
<?php
// If the ‘Resources’ inputs exist, iterate through them and sanitize them
if ( ! empty( $_POST[‘authors-commentary-resources’] ) ) {
$resources = $_POST[‘authors-commentary-resources’];
$sanitized_resources = array();
foreach ( $resources as $resource ) {
$resource = esc_url( strip_tags( $resource ) );
$sanitized_resources[] = $resource;
}
update_post_meta( $post_id, ‘authors-commentary-resources’, $sanitized_resources );
} else {
if ( » !== get_post_meta( $post_id, ‘authors-commentary-resources’, true ) ) {
delete_post_meta( $post_id, ‘authors-commentary-resources’ );
}
}
|
Теперь нам нужно сохранить значения для последнего мета-блока.
3. Опубликовано
Последняя вкладка мета-блока, вкладка Опубликовать , станет для нас самой простой в обновлении, поскольку она объединяет все, что мы рассмотрели в этой статье.
В частности, мы перебираем коллекцию значений, записываем их в массив и затем сериализуем массив в базу данных. Пожалуй, самое важное, что следует отметить, это то, что мы используем ассоциативный массив и индексируем каждое значение по значению идентификатора комментария.
Как мы увидим позже в этой статье, это значительно упростит установку значений в пользовательском интерфейсе.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
|
<?php
// If there are any values saved in the ‘Resources’ input, save them
if ( ! empty( $_POST[‘authors-commentary-comments’] ) ) {
$comments = $_POST[‘authors-commentary-comments’];
$sanitized_comments = array();
foreach ( $comments as $comment_id => $comment_value ) {
$comment = strip_tags( stripslashes( $comment_value ) );
$sanitized_comments[ $comment_id ] = $comment;
}
update_post_meta( $post_id, ‘authors-commentary-comments’, $sanitized_comments );
}
|
Как и в предыдущем разделе, если в массиве $_POST
ничего не указано, мы проверяем наличие значений в базе данных и, если они существуют, мы удаляем их:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
<?php
// If there are any values saved in the ‘Resources’ input, save them
if ( ! empty( $_POST[‘authors-commentary-comments’] ) ) {
$comments = $_POST[‘authors-commentary-comments’];
$sanitized_comments = array();
foreach ( $comments as $comment_id => $comment_value ) {
$comment = strip_tags( stripslashes( $comment_value ) );
$sanitized_comments[ $comment_id ] = $comment;
}
update_post_meta( $post_id, ‘authors-commentary-comments’, $sanitized_comments );
} else {
if ( » !== get_post_meta( $post_id, ‘authors-commentary-comments’, true ) ) {
delete_post_meta( $post_id, ‘authors-commentary-comments’ );
}
}
|
Как уже упоминалось, этот последний пример объединяет все, что мы видели на последних двух вкладках, поэтому на этом этапе должен быть относительно понятный код.
Слово о базе данных
Прежде чем идти дальше, давайте уделим немного времени, чтобы понять, как мы можем в конечном итоге запрашивать информацию из базы данных.
Допустим, у вас есть пост с идентификатором 9000 (ваш будет зависеть от вашей настройки). Вы можете взять этот идентификатор и заглянуть в таблицу wp_postmeta
чтобы увидеть всю метаинформацию, связанную с публикацией.
Кроме того, вы можете указать ключ для извлечения только информации, связанной с идентификатором поста и ключом.
Если вы укажете только идентификатор сообщения, вы увидите всю мета-информацию, связанную с сообщением. Если вы укажете только ключ, вы увидите все идентификаторы постов, которые содержат контент для их черновиков. Если вы укажете и идентификатор сообщения, и ключ, вы извлечете только черновую информацию, указанную для одного сообщения.
Говоря о получении данных, давайте рассмотрим шаги, необходимые для отображения метаданных записей на панели инструментов нашего плагина.
Получение данных
Теперь, когда вся информация была сохранена в базе данных, мы можем ввести код, который будет ее извлекать и отображать на соответствующей вкладке каждого плагина. Приятно то, что он будет использовать функции и конструкторы (например, get_post_meta
и for
), которые мы уже использовали.
1. Проект
Найдите admin/views/partials/drafts.php
. Предполагая, что вы следили за всем до этого момента, код должен выглядеть следующим образом:
1
2
3
|
<div class=»inside»>
<textarea id=»authors-commentary-drafts» name=»authors-commentary-drafts»></textarea>
</div>
|
Чтобы заполнить эту textarea
, нам нужно вызвать get_post_meta
используя текущий идентификатор сообщения и ключ, который мы использовали для сохранения информации ранее в этой статье. Посмотрите на следующий код:
1
2
3
|
<div class=»inside»>
<textarea id=»authors-commentary-drafts» name=»authors-commentary-drafts»><?php echo get_post_meta( get_the_ID(), ‘authors-commentary-drafts’, true );
</div>
|
Обратите внимание, что мы передаем три параметра:
- Первый — это идентификатор сообщения, который получается с помощью функции
get_the_ID
. - Второй — это ключ, который мы указали при сохранении данных для однозначной идентификации.
- Третье — это логическое значение true, которое сообщает функции, чтобы она возвращала нам значение в виде строки, а не в виде массива.
Если значение не существует, то оно просто возвращает пустую строку, поэтому textarea
пустое.
2. Ресурсы
Для Ресурсов мы делаем аналогичный звонок; однако на этот раз мы хотим перебрать результаты, чтобы мы могли динамически создавать пользовательский интерфейс.
Из-за способа, которым WordPress сериализует массив, мы все еще хотим, чтобы информация возвращалась в строковом формате (хотя это будет десериализованный массив), который позволит нам использовать цикл foreach
для итерации по нему.
1
2
3
4
5
6
7
8
9
|
<div class=»inside hidden»>
<div id=»authors-commentary-resources»>
<?php $resources = get_post_meta( get_the_ID(), ‘authors-commentary-resources’, true );
<?php foreach ( $resources as $resource ) { ?>
<input type=»text» value=»<?php echo $resource; ?>» />
<?php } ?>
</div><!— #authors-commentary-resources —>
<p><input type=»submit» id=»authors-commentary-add-resource» value=»Add Resource» class=»button» />
</div>
|
Вкратце, мы извлекаем информацию из базы данных, перебираем ее, создаем элемент input
для каждого значения и затем отображаем ее на странице.
Это также позволяет нам удалять элементы, просто удаляя значение и затем обновляя сообщение. Оттуда дисплей будет перерисовываться так, чтобы не было пустых элементов ввода.
3. Опубликовано
Возможно, это самая легкая часть плагина. Поскольку в шаблоне уже содержится так много кода, единственное, что нам действительно нужно сделать, это определить, установлено ли значение для флажка в массиве метаданных.
Поскольку мы используем идентификатор комментария в качестве числового индекса массива, мы можем просто проверить, содержится ли идентификатор комментария в массиве мета-ключей, который возвращается из метаданных.
Вот как:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
|
<div class=»inside hidden»>
<?php $comments = $this->load_post_comments();
<ul id=»author-commentary-comments»>
<?php foreach ( $comments as $comment ) { ?>
<li>
<label for=»authors-commentary-comment-<?php echo $comment->comment_ID ?>»>
<?php $comments = get_post_meta( get_the_ID(), ‘authors-commentary-comments’, true );
<input type=»checkbox» name=»authors-commentary-comments[<?php echo $comment->comment_ID ?>]» id=»authors-commentary-comment-<?php echo $comment->comment_ID ?>» <?php echo array_key_exists( $comment->comment_ID, $comments ) ?
This comment has received a reply.
</label>
<p>
<em><?php echo $comment->comment_author;
<?php echo $comment->comment_content;
</p>
<hr />
</li>
<?php } ?>
</ul>
</div>
|
Обратите внимание, что мы получаем значение из базы данных, снова передавая true
в качестве третьего значения.
Затем мы берем текущий идентификатор комментария и проверяем, содержится ли это значение в ключах массива (с помощью array_key_exists
) метаданных записи, которые были возвращены. Если так, мы отмечаем флажок как проверенный; в противном случае мы ничего не делаем.
Следующий
На данный момент у нас есть полностью функционирующий плагин, который отвечает всем требованиям, которые мы собирались построить, начиная с первой статьи в серии.
Но поддерживается ли сам плагин? То есть выполняет ли он главную задачу этой серии?
В некоторых случаях да, но есть возможности для улучшения. Поскольку часть разработки должна работать с кодом, который мы наследуем, мы рассмотрим, как реорганизовать некоторый код, который мы написали, чтобы сделать его более понятным и более понятным.
Кроме того, мы рассмотрим причины, по которым мы выполняем часть рефакторинга, который мы делаем. В конце концов, было бы бессмысленно упрощать код или перемещать его без каких-либо обоснований.
Но прежде чем делать это, продолжайте работу над этой статьей, взгляните на код из соответствующего репозитория GitHub и оставьте любые комментарии, вопросы или общие отзывы ниже.