Action load post php

WordPress. Обработка POST-запросов. Часть 1

В процессе загрузки WordPress происходит множество событий. К каждому из этих событий можно привязать функцию, которая выполнит какое-то действие ( action ) или изменит данные ( filter ). Отправка формы не является исключением — мы можем «прицепить» свою функцию к подходящему хуку и обработать POST-данные.

Кодекс WordPress говорит, что данные формы нужно отправлять на admin-post.php в директории wp-admin . А сама форма должна содержать поле action . Посмотрим на исходный код этого скрипта:

if (!defined('WP_ADMIN'))  define('WP_ADMIN', true); > if (defined('ABSPATH'))  require_once(ABSPATH . 'wp-load.php'); > else  require_once(dirname(dirname(__FILE__)) . '/wp-load.php'); > send_origin_headers(); require_once(ABSPATH . 'wp-admin/includes/admin.php'); nocache_headers(); do_action('admin_init'); $action = empty($_REQUEST['action']) ? '' : $_REQUEST['action']; if (!wp_validate_auth_cookie())  // если пользователь не авторизован if (empty($action))  do_action('admin_post_nopriv'); > else  do_action('admin_post_nopriv_'.$action); > > else  // если пользователь авторизован if (empty($action))  do_action('admin_post'); > else  do_action('admin_post_'.$action); > >
  • когда пользователь не авторизован
    • если action не установлен, происходит событие admin_post_nopriv
    • если action установлен, происходит событие admin_post_nopriv_
    • если action не установлен, происходит событие admin_post
    • если action установлен, происходит событие admin_post_

    Все вышеописанные хуки можно применить и для GET запроса, если адрес примерно такой:

    http://www.server.com/wp-admin/admin-post.php?action=some_action&data=some_data

    Плагин «Форма обратной связи»

    Давайте применим полученные знания на практике и создадим плагин, который позволит добавить на сайт форму обратной связи. Создаем директорию tokmakov-feedback и внутри нее — файл tokmakov-feedback.php .

     /* Plugin Name: Форма обратной связи Plugin URI: https://tokmakov.msk.ru Description: Регистрирует шорткод [tokmakov-feedback] для формы обратной связи, отправляет сообщения на почту. Version: 1.0 Author: Евгений Токмаков Author URI: https://tokmakov.msk.ru */ register_activation_hook(__FILE__, function()  // проверяем права пользователя на активацию плагинов if (!current_user_can('activate_plugins'))  return; > >); register_deactivation_hook(__FILE__, function()  // проверяем права пользователя на деактивацию плагинов if (!current_user_can('deactivate_plugins'))  return; > >);

    Для начала зарегистрируем шорткод [tokmakov-feedback] :

    /* * Регистрируем шорткод [tokmakov-feedback], который позволит * вставить форму обратной связи на страницу или запись блога */ add_shortcode('tokmakov-feedback', function ()  ob_start(); ?> class="tokmakov-feedback"> class="response">  action=" admin_url('admin-post.php'); ?>" method="post"> type="hidden" name="action" value="tokmakov_feedback" /> type="hidden" name="redirect" value=" get_permalink(); ?>" /> for="name"> Имя type="text" name="name" value="" required />  for="email"> Email type="text" name="email" value="" required />  for="phone"> Телефон type="text" name="phone" value="" />  for="message"> Сообщение name="message" required>   type="submit" value="Отправить" />    return ob_get_clean(); >);

    У нас есть скрытое поле формы action со значением tokmakov_feedback — значит, нам доступны два хука:

    Форму мы должны обработать независимо от того, залогинился пользователь или нет:

    /* * Обрабатываем отправленные данные формы обратной связи */ add_action('admin_post_nopriv_tokmakov_feedback', 'tokmakov_process_feedback_form'); add_action('admin_post_tokmakov_feedback', 'tokmakov_process_feedback_form'); function tokmakov_process_feedback_form()  /* * Здесь уже можно обрабатывать массивы $_POST или $_GET */ >

    Что ж, давайте напишем функцию, которая будет обрабатывать данные формы и отправлять письмо администратору:

    function tokmakov_process_feedback_form()  /* * Обрабатываем данные, полученные из формы */ $data['name'] = trim(iconv_substr(strip_tags($_POST['name']), 0, 50)); $data['email'] = trim(iconv_substr(strip_tags($_POST['email']), 0, 50)); $data['phone'] = trim(iconv_substr(strip_tags($_POST['phone']), 0, 50)); $data['message'] = trim(iconv_substr(strip_tags($_POST['message']), 0, 1000)); // были допущены ошибки при заполнении формы? if (empty($data['name']))  $errors[] = 'Не заполнено обязательное поле «Имя»'; > if (empty($data['email']))  $errors[] = 'Не заполнено обязательное поле «E-mail»'; > if (empty($data['message']))  $errors[] = 'Не заполнено обязательное поле «Сообщение»'; > if (!empty($errors))  /* * были допущены ошибки при заполнении формы, сохраняем введенные * пользователем данные, чтобы после редиректа снова показать форму, * заполненную введенными ранее даннными и сообщением об ошибке */ $_SESSION['tokmakov_feedback']['success'] = false; $message = 'При заполнении формы были допущены ошибки'; $_SESSION['tokmakov_feedback']['message'] = $message; $_SESSION['tokmakov_feedback']['errors'] = $errors; $_SESSION['tokmakov_feedback']['data'] = $data; > else  // отправляем письмо администратору if (tokmakov_sendmail($data))  $_SESSION['tokmakov_feedback']['success'] = true; $message = 'Ваше сообщение успешно отправлено'; $_SESSION['tokmakov_feedback']['message'] = $message; > else  $_SESSION['tokmakov_feedback']['success'] = false; $message = 'Произошла ошибка при отправке письма'; $_SESSION['tokmakov_feedback']['message'] = $message; $_SESSION['tokmakov_feedback']['data'] = $data; > > // после отправки формы делаем редирект, чтобы предотвратить // повторную отправку, если пользователь обновит страницу $redirect = home_url(); if (isset($_POST['redirect']))  $redirect = $_POST['redirect']; $redirect = wp_validate_redirect($redirect, home_url()); > wp_redirect($redirect); die(); >
    function tokmakov_sendmail($data)  $message = 'Имя: ' . $data['name'] . PHP_EOL; $message .= 'E-mail: ' . $data['email'] . PHP_EOL; if (!empty($data['phone']))  $message .= 'Телефон: ' . $data['phone'] . PHP_EOL; > $message .= PHP_EOL . 'Сообщение: ' . PHP_EOL . $data['message'] . PHP_EOL; $result = wp_mail( get_bloginfo('admin_email'), 'Заполнена форма обратной связи', $message ); return $result; >

    Как видите, функция проверяет корректность данных и записывает результат проверки в сессию. Чтобы после редиректа показать результаты проверки пользователю. Если форма содержит ошибки, в сессию будут также записаны введенные пользователем данные. Будет некрасиво, если пользователь потратил время, чтобы написать сообщение, а мы это сообщение потеряем при проверке.

    А теперь доработаем функцию, которая регистрирует шорткод. Кроме самой формы, она будет показывать сообщения об ошибках или сообщение об успешной отправке:

    /* * Регистрируем шорткод [tokmakov-feedback], который позволит * вставить форму обратной связи на страницу или запись блога */ add_shortcode('tokmakov-feedback', function ()  $name = ''; $email = ''; $phone = ''; $message = ''; if (isset($_SESSION['tokmakov_feedback']['data']))  $name = htmlspecialchars($_SESSION['tokmakov_feedback']['data']['name']); $email = htmlspecialchars($_SESSION['tokmakov_feedback']['data']['email']); $phone = htmlspecialchars($_SESSION['tokmakov_feedback']['data']['phone']); $message = htmlspecialchars($_SESSION['tokmakov_feedback']['data']['message']); > ob_start(); ?> class="tokmakov-feedback"> class="response">  if (isset($_SESSION['tokmakov_feedback'])): ?>  $_SESSION['tokmakov_feedback']['message']; ?>   if (isset($_SESSION['tokmakov_feedback']['errors'])): ?>  foreach ($_SESSION['tokmakov_feedback']['errors'] as $error): ?>  $error; ?>   endforeach; ?>   endif; ?>  unset($_SESSION['tokmakov_feedback']); ?>  endif; ?>  action=" admin_url('admin-post.php'); ?>" method="post"> type="hidden" name="action" value="tokmakov_feedback" /> type="hidden" name="redirect" value=" get_permalink(); ?>" />  Имя type="text" name="name" value=" $name; ?>" required />   E-mail type="text" name="email" value=" $email; ?>" required />   Телефон type="text" name="phone" value=" $phone; ?>" />   Сообщение name="message" required> $message; ?>   type="submit" value="Отправить" />    return ob_get_clean(); >);

    Поскольку мы используем суперглобальный массив $_SESSION , давайте стартанем сессию при наступлении события init :

    /* * Запускаем сессию, чтобы передавать сообщение о результате * обработки формы обратной связи после перезагрузки страницы */ add_action('init', function ()  if (session_id() == '')  session_start(); > >);

    Если при проверке данных формы были обнаружены ошибки, элемент массива $_SESSION с ключом tokmakov_feedback будет содержать вот что:

    Array ( [success] => false [message] => При заполнении формы были допущены ошибки [errors] => Array ( [0] => Не заполнено обязательное поле «E-mail» ) [data] => Array ( [name] => Евгений [email] => [phone] => [message] => Какое-то сообщение ) )

    Если данные формы были успешно отправлены, этот элемент массива будет таким:

    Array ( [success] => true [message] => Ваше сообщение успешно отправлено )

    Скачать плагин «Форма обратной связи» можно здесь.

    Источник

    Action load post php

    I think the way an array of attachments works is kind of cumbersome. Usually the PHP guys are right on the money, but this is just counter-intuitive. It should have been more like:

    Array
    (
    [0] => Array
    (
    [name] => facepalm.jpg
    [type] => image/jpeg
    [tmp_name] => /tmp/phpn3FmFr
    [error] => 0
    [size] => 15476
    )

    Anyways, here is a fuller example than the sparce one in the documentation above:

    foreach ( $_FILES [ «attachment» ][ «error» ] as $key => $error )
    $tmp_name = $_FILES [ «attachment» ][ «tmp_name» ][ $key ];
    if (! $tmp_name ) continue;

    $name = basename ( $_FILES [ «attachment» ][ «name» ][ $key ]);

    if ( $error == UPLOAD_ERR_OK )
    if ( move_uploaded_file ( $tmp_name , «/tmp/» . $name ) )
    $uploaded_array [] .= «Uploaded file ‘» . $name . «‘.
    \n» ;
    else
    $errormsg .= «Could not move uploaded file ‘» . $tmp_name . «‘ to ‘» . $name . «‘
    \n» ;
    >
    else $errormsg .= «Upload error. [» . $error . «] on file ‘» . $name . «‘
    \n» ;
    >
    ?>

    Do not use Coreywelch or Daevid’s way, because their methods can handle only within two-dimensional structure. $_FILES can consist of any hierarchy, such as 3d or 4d structure.

    The following example form breaks their codes:

    As the solution, you should use PSR-7 based zendframework/zend-diactoros.

    use Psr \ Http \ Message \ UploadedFileInterface ;
    use Zend \ Diactoros \ ServerRequestFactory ;

    $request = ServerRequestFactory :: fromGlobals ();

    if ( $request -> getMethod () !== ‘POST’ ) http_response_code ( 405 );
    exit( ‘Use POST method.’ );
    >

    $uploaded_files = $request -> getUploadedFiles ();

    if (
    !isset( $uploaded_files [ ‘files’ ][ ‘x’ ][ ‘y’ ][ ‘z’ ]) ||
    ! $uploaded_files [ ‘files’ ][ ‘x’ ][ ‘y’ ][ ‘z’ ] instanceof UploadedFileInterface
    ) http_response_code ( 400 );
    exit( ‘Invalid request body.’ );
    >

    $file = $uploaded_files [ ‘files’ ][ ‘x’ ][ ‘y’ ][ ‘z’ ];

    if ( $file -> getError () !== UPLOAD_ERR_OK ) http_response_code ( 400 );
    exit( ‘File uploading failed.’ );
    >

    $file -> moveTo ( ‘/path/to/new/file’ );

    The documentation doesn’t have any details about how the HTML array feature formats the $_FILES array.

    Array
    (
    [document] => Array
    (
    [name] => sample-file.doc
    [type] => application/msword
    [tmp_name] => /tmp/path/phpVGCDAJ
    [error] => 0
    [size] => 0
    )
    )

    Multi-files with HTML array feature —

    Array
    (
    [documents] => Array
    (
    [name] => Array
    (
    [0] => sample-file.doc
    [1] => sample-file.doc
    )

    [type] => Array
    (
    [0] => application/msword
    [1] => application/msword
    ) [tmp_name] => Array
    (
    [0] => /tmp/path/phpVGCDAJ
    [1] => /tmp/path/phpVGCDAJ
    )

    The problem occurs when you have a form that uses both single file and HTML array feature. The array isn’t normalized and tends to make coding for it really sloppy. I have included a nice method to normalize the $_FILES array.

    function normalize_files_array ( $files = [])

    foreach( $files as $index => $file )

    if (! is_array ( $file [ ‘name’ ])) $normalized_array [ $index ][] = $file ;
    continue;
    >

    foreach( $file [ ‘name’ ] as $idx => $name ) $normalized_array [ $index ][ $idx ] = [
    ‘name’ => $name ,
    ‘type’ => $file [ ‘type’ ][ $idx ],
    ‘tmp_name’ => $file [ ‘tmp_name’ ][ $idx ],
    ‘error’ => $file [ ‘error’ ][ $idx ],
    ‘size’ => $file [ ‘size’ ][ $idx ]
    ];
    >

    ?>

    The following is the output from the above method.

    Array
    (
    [document] => Array
    (
    [0] => Array
    (
    [name] => sample-file.doc
    [type] => application/msword
    [tmp_name] => /tmp/path/phpVGCDAJ
    [error] => 0
    [size] => 0
    )

    [documents] => Array
    (
    [0] => Array
    (
    [name] => sample-file.doc
    [type] => application/msword
    [tmp_name] => /tmp/path/phpVGCDAJ
    [error] => 0
    [size] => 0
    ) [1] => Array
    (
    [name] => sample-file.doc
    [type] => application/msword
    [tmp_name] => /tmp/path/phpVGCDAJ
    [error] => 0
    [size] => 0
    )

    Источник

    Читайте также:  Javascript from file example
Оцените статью