Создайте и отправьте файл ICS через WordPress

Вопрос или проблема

Я пишу собственный плагин для бронирований. Мне нужно сгенерировать файл .ics, который нужно отправить на предопределённый адрес электронной почты.

Я пробовал использовать библиотеки, такие как ZContent iCalendar, и нашёл PHP-скрипт на GitHub, который я включил в код моего плагина. Скрипт работает хорошо, и я могу получить корректный выходной файл. Проблема в том, что я не могу понять, как сгенерировать файл ics и прикрепить его к письму с помощью функции wp_mail.

Вот мой код:

<?php
/**
 * ICS.php
 * =======
 * Используйте этот класc для создания файла .ics.
 *
 * Использование
 * -----
 * Основное использование - генерировать содержимое файла ics (см. ниже доступные свойства):
 *   $ics = new ICS($props);
 *   $ics_file_contents = $ics->to_string();
 *
 * Установка свойств после создания экземпляра
 *   $ics = new ICS();
 *   $ics->set('summary', 'Моё замечательное событие');
 *
 * Вы также можете установить несколько свойств одновременно, используя массив:
 *   $ics->set(array(
 *     'dtstart' => 'now + 30 minutes',
 *     'dtend' => 'now + 1 hour'
 *   ));
 *
 * Доступные свойства
 * --------------------
 * description
 *   Строка описания события.
 * dtend
 *   М метка даты/времени, задающая окончание события. Вы можете использовать либо
 *   объект DateTime, либо строку формата даты/времени PHP (например, "now + 1 hour").
 * dtstart
 *   М метка даты/времени, задающая начало события. Вы можете использовать либо
 *   объект DateTime, либо строку формата даты/времени PHP (например, "now + 1 hour").
 * location
 *   Строка адреса или описание места проведения события.
 * summary
 *   Строка краткого описания события - обычно используется в качестве заголовка.
 * url
 *   URL, который нужно прикрепить к событию. Убедитесь, что вы добавили протокол (http://
 *   или https://).
 */
class WP_ICS{
  const DT_FORMAT = 'Ymd\THis\Z';
  protected $properties = array();
  private $available_properties = array(
    'description',
    'dtend',
    'dtstart',
    'location',
    'summary',
    'url'
  );
  public function __construct($props) {
    $this->set($props);
  }
  public function set($key, $val = false) {
    if (is_array($key)) {
      foreach ($key as $k => $v) {
        $this->set($k, $v);
      }
    } else {
      if (in_array($key, $this->available_properties)) {
        $this->properties[$key] = $this->sanitize_val($val, $key);
      }
    }
  }
  public function to_string() {
    $rows = $this->build_props();
    return implode("\r\n", $rows);
  }
  private function build_props() {
    // Создать свойства ICS - добавить заголовок
    $ics_props = array(
      'BEGIN:VCALENDAR',
      'VERSION:2.0',
      'PRODID:-//hacksw/handcal//NONSGML v1.0//EN',
      'CALSCALE:GREGORIAN',
      'BEGIN:VEVENT'
    );
    // Создать свойства ICS - добавить заголовок
    $props = array();
    foreach($this->properties as $k => $v) {
      $props[strtoupper($k . ($k === 'url' ? ';VALUE=URI' : ''))] = $v;
    }
    // Установить некоторые значения по умолчанию
    $props['DTSTAMP'] = $this->format_timestamp('now');
    $props['UID'] = uniqid();
    // Добавить свойства
    foreach ($props as $k => $v) {
      $ics_props[] = "$k:$v";
    }
    // Создать свойства ICS - добавить нижний колонтитул
    $ics_props[] = 'END:VEVENT';
    $ics_props[] = 'END:VCALENDAR';
    return $ics_props;
  }
  private function sanitize_val($val, $key = false) {
    switch($key) {
      case 'dtend':
      case 'dtstamp':
      case 'dtstart':
        $val = $this->format_timestamp($val);
        break;
      default:
        $val = $this->escape_string($val);
    }
    return $val;
  }
  private function format_timestamp($timestamp) {
    $dt = new DateTime($timestamp);
    return $dt->format(self::DT_FORMAT);
  }
  private function escape_string($str) {
    return preg_replace('/([\,;])/','\\\$1', $str);
  }
}

class iCalBooking{

  public function init(){
    add_action('admin_post_forward_booking_request', array($this, 'send_booking_request'));
    add_action('admin_post_nopriv_forward_booking_request', array($this, 'send_booking_request'));
    #add_action();
    add_shortcode('booking', array($this, 'display_booking_form'));
  }

  public function display_booking_form(){
    include_once 'booking-form.php';
  }

  private function has_valid_nonce() {
      if(!isset( $_POST['booking_nonce'] )){
        return false;
      }
      $field  = wp_unslash( $_POST['booking_nonce'] );
      $action = 'validate_booking_request';
      return wp_verify_nonce( $field, $action );
  }

  public function send_booking_request(){
    if(! ( $this->has_valid_nonce() ) ){
      return;
    }
    $fname = $_POST['client_fname'];
    $lname = $_POST['client_lname'];
    $phone = $_POS['client_phone'];
    $email = $_POST['client_email'];

    $title="Бронирование";

    $description = $fname . $lname . $phone . $email;

    $ics = new WP_ICS(array(
      'location' => '',
      'description' => $description,
      'dtstart' => $_POST['client_checkin'],
      'dtend' => $_POST['client_checkout'],
      'summary' => '',
      'url' => ''
    ));

    file_put_contents('reservation.ics', $ics->to_string() );

    #header('Content-Type: text/calendar; charset=utf-8');
    #header('Content-Disposition: attachment; filename=reservation.ics');

  }

}

$booking = new iCalBooking;
$booking->init();
?> 

Это неопытно, но это тот подход, который вам нужно использовать. Я просто работаю с последним методом в вашем классе.

Вот как я бы подошёл к этому:

  1. Вам нужно указать путь к файлу, когда вы сохраняете файл, чтобы вы могли использовать его позже для прикрепления.
  2. Настройте значения для вашего электронного письма (адрес “кому”, тема, сообщение, заголовки и путь к вложению).
  3. Используйте переменные из #2 для wp_mail(), чтобы отправить ваше сообщение.

Вот функция из вашего класса с моими дополнениями:

public function send_booking_request(){
    if(! ( $this->has_valid_nonce() ) ){
      return;
    }
    $fname = $_POST['client_fname'];
    $lname = $_POST['client_lname'];
    $phone = $_POS['client_phone'];
    $email = $_POST['client_email'];

    $title="Бронирование";

    $description = $fname . $lname . $phone . $email;

    $ics = new WP_ICS(array(
      'location' => '',
      'description' => $description,
      'dtstart' => $_POST['client_checkin'],
      'dtend' => $_POST['client_checkout'],
      'summary' => '',
      'url' => ''
    ));

    // Вам нужно указать путь здесь, чтобы вы могли использовать его позже для получения вложения
    $uploads = wp_upload_dir();
    $path = $uploads['path'];

    file_put_contents( $path . '/reservation.ics', $ics->to_string() );

    // Настройте электронное письмо
    $to = '[email protected]';
    $subject = "файл бронирования";
    $message = "Пожалуйста, смотрите приложенное бронирование.";
    $headers="From: Моё Имя <[email protected]>" . "\r\n";
    $attachments = array( $path . '/reservation.ics' );

    // Отправьте письмо.
    wp_mail( $to, $subject, $message, $headers, $attachments );

    #header('Content-Type: text/calendar; charset=utf-8');
    #header('Content-Disposition: attachment; filename=reservation.ics');

}

Предполагая, что остальная часть вашего кода в порядке и файл создан, это должно работать и прикрепить его к письму.

Ответ или решение

Генерация и отправка ICS файла через WordPress: Полное руководство

Создание и отправка ICS файлов через WordPress может показаться сложной задачей, особенно для разработчиков, которые только начинают разрабатывать плагины или расширения. В данном руководстве мы подробно рассмотрим, как сгенерировать ICS файл и успешно прикрепить его к email-сообщению с использованием функции wp_mail в WordPress.

Шаг 1: Настройка класса для создания ICS файла

Сначала мы позаботимся о классе, который отвечает за создание ICS файла. Ваш исходный код уже содержит класс WP_ICS, который генерирует содержимое ICS файла. Вам необходимо убедиться, что все поля, которые вы хотите использовать, определены и корректно обрабатываются.

class WP_ICS {
    // Определения и функции класса остались без изменений
}

Шаг 2: Генерация ICS файла

В вашем методе send_booking_request вызывается класс WP_ICS для создания ICS файла. Мы добавим путь для сохранения файла в директорию загрузок WordPress, а затем запишем содержимое ICS файла в этот файл.

public function send_booking_request(){
    if (!($this->has_valid_nonce())) {
        return;
    }

    $fname = $_POST['client_fname'];
    $lname = $_POST['client_lname'];
    $phone = $_POST['client_phone'];
    $email = $_POST['client_email'];

    $description = $fname . ' ' . $lname . ', ' . $phone . ', ' . $email;

    $ics = new WP_ICS(array(
        'location' => '',
        'description' => $description,
        'dtstart' => $_POST['client_checkin'],
        'dtend' => $_POST['client_checkout'],
        'summary' => '',
        'url' => ''
    ));

    // Определяем путь для сохранения файла
    $uploads = wp_upload_dir();
    $file_path = $uploads['path'] . '/reservation.ics';

    // Записываем содержимое в файл
    file_put_contents($file_path, $ics->to_string());

Шаг 3: Подготовка и отправка Email

Прежде чем отправить email, вам нужно определить получателя, тему и содержимое сообщения. Также укажите путь к только что созданному ICS файлу как вложение.

    // Настройка параметров для отправки email
    $to = $email; // адрес получателя из формы
    $subject = "Подтверждение резервирования";
    $message = "Пожалуйста, посмотрите прикрепленный файл с подтверждением резервирования.";
    $headers = "С уважением, <ваше имя> <ваш email>" . "\r\n"; // Ваше имя и email

    // У attachment добавляем путь к файлу
    $attachments = array($file_path);

    // Отправка email
    wp_mail($to, $subject, $message, $headers, $attachments);
}

Шаг 4: Удаление временного файла (по желанию)

После успешной отправки email, вы можете удалить созданный ICS файл, если он больше не нужен. Для этого используйте следующую строку кода:

    unlink($file_path); // Удаляем файл после отправки

Общий код метода send_booking_request

public function send_booking_request(){
    if (!($this->has_valid_nonce())) {
        return;
    }

    $fname = $_POST['client_fname'];
    $lname = $_POST['client_lname'];
    $phone = $_POST['client_phone'];
    $email = $_POST['client_email'];

    $description = $fname . ' ' . $lname . ', ' . $phone . ', ' . $email;

    $ics = new WP_ICS(array(
        'location' => '',
        'description' => $description,
        'dtstart' => $_POST['client_checkin'],
        'dtend' => $_POST['client_checkout'],
        'summary' => '',
        'url' => ''
    ));

    $uploads = wp_upload_dir();
    $file_path = $uploads['path'] . '/reservation.ics';

    file_put_contents($file_path, $ics->to_string());

    $to = $email;
    $subject = "Подтверждение резервирования";
    $message = "Пожалуйста, посмотрите прикрепленный файл с подтверждением резервирования.";
    $headers = "С уважением, <ваше имя> <ваш email>" . "\r\n";
    $attachments = array($file_path);

    wp_mail($to, $subject, $message, $headers, $attachments);

    unlink($file_path); // Удаление временного файла
}

Заключение

Следуя этому руководству, вы успешно сможете создать ICS файл и отправить его как вложение в email-сообщении через WordPress. Метод wp_mail предоставит вам гибкость настройки параметров отправляемого сообщения, а также возможность прикрепления файлов. Не забывайте следить за настройками конфиденциальности и защищенностью email данных ваших клиентов.

Оцените материал
Добавить комментарий

Капча загружается...