Современный сайт на WordPress сложно представить без плагина Advanced Custom Fields, данный плагин позволяет организовать работу с Custom Fields максимально удобно для пользователя. Этот плагин довольно прост в настройке, но иногда приходится сталкиваться с нестандартными задачами. Одна из таких задач — вставка в запись данных из полей Custom Fields.
Как извлечь данные из формы WordPress до их записи в БД?
Для начала, можно просмотреть все данные, что отправляются из формы после публикации записи, т.е. после нажатия кнопки Опубликовать/Publish. Для этого в файле functions.php создадим фильтр wp_insert_post_data, который будет вызван перед вставкой или обновлением данных в БД. Суть функции — var_dump($_POST) с выводом данных в файл, который будет находится в стандартной uploads директории WordPress. Для вывода var_dump() придётся включить буферизацию.
| 
					 1 2 3 4 5 6 7 8 9  | 
						add_filter( 'wp_insert_post_data' , 'filter_post_data' , '99', 2 ); function filter_post_data( $data , $postarr ) { ob_start(); var_dump($_POST); $output = ob_get_clean(); $new_file_name = 'uploaded3.txt'; $upload = wp_upload_bits( $new_file_name, null, $output );  }  | 
					
Я не буду публиковать всё содержимое файла, только некоторые фрагменты, т.к. данных в $_POST предостаточно.
| 
					 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59  | 
						array(68) {   ["_wpnonce"]=>   string(10) "de38789e94"   ["_wp_http_referer"]=>   string(22) "/wp-admin/post-new.php"   ["user_ID"]=>   int(1)   ["action"]=>   string(8) "editpost"   ["originalaction"]=>   string(8) "editpost"   ["post_author"]=>   int(1)   ["post_type"]=>   string(4) "post" . . .  ["_thumbnail_id"]=>   string(2) "-1"   ["fields"]=>   array(6) {     ["field_5aae6a08e2740"]=>     string(1) "1"     ["field_5aae6a65e2741"]=>     string(62) "http://www.mywebtoday.ru/wp-admin/post-new.php"     ["field_5aae6a8ce2742"]=>     string(52) "http://google.com/"     ["field_5aae6b00e2743"]=>     string(16) "test123"     ["field_5aae6b4fe2744"]=>     string(119) "test555"     ["field_5aaf8570e38da"]=>     string(21) "yandex.ru"   }   ["acf_nonce"]=>   string(10) "60f29da599"   ["excerpt"]=>   string(0) ""   ["trackback_url"]=>   string(0) "" . . .   ["post_mime_type"]=>   string(0) ""   ["ID"]=>   int(1218)   ["post_content"]=>   string(23) "fdgdfg  fgd fg dfg dfg "   ["post_excerpt"]=>   string(0) ""   ["to_ping"]=>   string(0) ""   ["comment_status"]=>   string(6) "closed"   ["ping_status"]=>   string(6) "closed" }  | 
					
Данная операция позволяет убедиться, что данные действительно передаются на сервер. Интересны названия переменных полей Custom Fields — они уникальны, например, $_POST[«fields»][«field_5aae6a65e2741»] и в них нет даже упоминания о названиях-псевдонимах. Стоит отметить, что при просмотре содержимого директории uploads можно будет увидеть не один, а два или три файла, .т.к. WordPress делает автосохранение записи и фильтр может «успеть» сработать несколько раз. На первый взгляд, можно поработать с $_POST, извлечь все необходимые данные и сохранить их в «теле» записи, но это обманчивый путь.
Для работы с введёнными в форму данными у ACF существует подходящий для этих целей action — acf/save_post . В документации написано, что он вызывается во время сохранения $_POST данных. То, что нужно. Есть 2 варианта вызова этого action: с высоким и низким приоритетом:
| 
					 1 2 3 4  | 
						add_action('acf/save_post', 'my_acf_save_post', 1); add_action('acf/save_post', 'my_acf_save_post', 20);  | 
					
В первом случае мы сможем работать с данными ассоциативного массива $_POST, а во втором — со стандартными функциями ACF.
Для первого варианта документация по ACF предлагает воспользоваться следующей функцией:
| 
					 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16  | 
						<?php function my_acf_save_post( $post_id ) {     // return если переменная не содержит данных     if( empty($_POST['acf']) ) {         return;       }     // массив с данными ACF     $fields = $_POST['acf'];     // данные определённого поля     $field = $_POST['acf']['field_abc123']; } add_action('acf/save_post', 'my_acf_save_post', 1); ?>  | 
					
Во втором случае данные уже сохранены и их можно обрабатывать с помощью стандартных ACF функций:
| 
					 1 2 3 4 5 6 7 8 9 10 11  | 
						<?php function my_acf_save_post( $post_id ) {     // получить значение поля     $value = get_field('my_field');     // что-то делаем.... } add_action('acf/save_post', 'my_acf_save_post', 20); ?>  | 
					
Это два стандартных примера, которые можно найти в документации.
Как вставить в тело записи данные из Custom Fields?
Пример.
Я предлагаю не обрабатывать данные до их записи в БД, а поработать с ними уже после их внесения в БД. Результат от этого не измениться, но делать обработку проще. Используем тот же action — acf/save_post
| 
					 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32  | 
						add_action('acf/save_post', 'save_post', 20); function save_post($post_id){     if (get_post_type($post_id) != 'post') {       return;     }     // получаем данные из определённых полей     $movie_url = get_field('movie_url', $post_id);     $short_description = get_field('short_description', $post_id); 	// получаем post_content записи 	$post = get_post($post_id); 	$content = $post->post_content;     // Устанавливаем данные для добавления к записи     $new_post = array(         'ID'           => $post_id,         'post_title'   => $short_description, 		'post_content' => $movie_url.$content,     );     // Удаляем action, чтобы избежать зацикливания при wp_update_post     remove_action('acf/save_post', 'save_post', 20);     // Обновляем запись     wp_update_post( $new_post );     // Добавляем action      add_action('acf/save_post', 'save_post', 20); }  | 
					

Свежие комментарии