Uprość sobie życie. Przykład automatyzacji działań w WordPress


Uwaga! Wszystkie informacje i solucje zawarte w postach typu DYI mogą z czasem przestać być aktualne. Niektóre publikowane kody źródłowe, będąc zależnymi od używanych konfiguracji platform i sprzętu, mogą nie działać, lub działać nieprawidłowo u niektórych użytkowników. Stosując opisane rozwiązania przyjmujesz do wiadomości i zgadzasz się, że nie ponoszę odpowiedzialności za ich finalne efekty.


Zasadniczo, istnieją dwie możliwości kiedy zbudujesz stronę internetową, zaczynasz nią zarządzać i okazuje się, że na wszystkich stronach wpisów trzeba dokonać podobnej poprawki: albo ręcznie zmodyfikujesz kod, albo zautomatyzujesz swoją pracę. W pierwszym przypadku będziesz to robił do śmierci, która jak sądzę nastąpi dość szybko, bo prędzej czy później się potniesz. W drugim – poświęcisz naprawdę niewiele czasu. Jak mówią – czas jest bezcenny. Naucz się tego. Wtedy będziesz leciał przez życie jak stary poczciwy Ursus po żuławskich polach.

Aktualnie buduję stronę prezentującą treści teatralne. Każdy post jest odrębną opowieścią, z inną szatą graficzną, choć wykorzystaną według tego samego wzoru, bo jak wiadomo UX jest święte. Problematyczne było umieszczanie na każdej podstronie tego samego kodu js, różniącego się wyłącznie numerem wydarzenia (eventID). Uznałem, że ewentualna modyfikacja tej treści może być za trudna dla osoby obsługującej stronę po produkcji. Wymyśliłem więc, że w treści każdego z wpisów umieszczę znacznik {eventid} i stworzę wtyczkę, która:

1. W panelu bocznym edytora wpisów będzie udostępniała box – Event ID.
2. Zamieni istniejący znacznik {eventid} na ekwiwalent w postaci wygenerowanego przez platformę sprzedażową iframe’a.

To dość skomplikowane, bo nie dość, że plugin musi m.in. za pomocą sanitize_text_field() sprawdzać wprowadzane dane (czy nie zawierają potencjalnie szkodliwych treści – to jest zapobieganie atakom XSS), sprawdzać czy żądanie pochodzi z zaufanego źródła (czyli chronić przed atakami CSRF), stwierdzać, gdzie ma wykonywać zmiany, to jeszcze ma być być idioto-odporny i wyświetlać komunikat o braku sprzedaży biletów, jeśli użytkownikowi nie będzie się chciało podać eventid.

Kod można rozbudować o inne funkcjonalności, np. żeby sprawdzał, czy w meta box wprowadzono wyłącznie numer, a także reagował, kiedy wprowadzony numer jest błędny i generuje błąd 404. W tym przypadku nie było jednak takiej potrzeby.

<?php
/*
Plugin Name: Biletyna Event ID
Description: Zamienia {eventid} w treści wpisu na iframe z Biletyny lub wyświetla wiadomość, jeśli ID wydarzenia nie został podany.
Version: 1.2
Author: Dariusz Staropiętka
*/

function biletyna_event_id_meta_box() {
    add_meta_box(
        'biletyna_event_id',
        __('Biletyna Event ID', 'biletyna'),
        'biletyna_event_id_callback',
        ['post'], // Tutaj określamy do jakich typów treści zostanie dodany metabox; typ może być 'post', 'page', 'custom post types' lub wielokrotny: ['post', 'page']
        'side', // Umieszczenie metaboxa w panelu bocznym...
        'high' //...jako pierwszy element
    );
}
add_action('add_meta_boxes', 'biletyna_event_id_meta_box');

function biletyna_event_id_callback($post) {
    wp_nonce_field('biletyna_event_id_nonce_action', 'biletyna_event_id_nonce');
    $value = get_post_meta($post->ID, '_biletyna_event_id', true);
    echo '<label for="biletyna_event_id">' . __('Wprowadź ID wydarzenia', 'biletyna') . '</label>';
    echo '<input type="text" id="biletyna_event_id" name="biletyna_event_id" value="' . esc_attr($value) . '" style="width:100%;">';
}

function save_biletyna_event_id_meta_box($post_id) {
    if (!isset($_POST['biletyna_event_id_nonce']) || !wp_verify_nonce($_POST['biletyna_event_id_nonce'], 'biletyna_event_id_nonce_action')) {
        return;
    }
    if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) {
        return;
    }
    if (isset($_POST['biletyna_event_id'])) {
        update_post_meta($post_id, '_biletyna_event_id', sanitize_text_field($_POST['biletyna_event_id']));
    } else {
        delete_post_meta($post_id, '_biletyna_event_id');
    }
}
add_action('save_post', 'save_biletyna_event_id_meta_box');

function biletyna_replace_eventid($content) {
    if (is_single()) {
        global $post;
        $event_id = get_post_meta($post->ID, '_biletyna_event_id', true);

        if (!empty($event_id)) {
            // Tutaj - jeśli wpisano eventid, zamienimy frazę {eventid} umieszczoną w treści wpisu na jej ekwiwalent w postaci iframe
            $iframe = '<div id="biletyna_iframe"></div>
            <script type="text/javascript" src="https://biletyna.pl/javascript?ifid=999&action_url=event/view/id/' . esc_attr($event_id) . '" async></script>';
            $content = str_replace('{eventid}', $iframe, $content);
        } else {
            // Tutaj zmienimy {eventid} na komunikat, jeśli ID nie zostało wpisane przez użytkownika
            $content = str_replace('{eventid}', '<strong>Sprzedaż biletów na to wydarzenie nie jest obecnie prowadzona.</strong>', $content);
        }
    }
    return $content;
}
add_filter('the_content', 'biletyna_replace_eventid');