Data wygaśnięcia wpisu w WordPressie – tworzymy wtyczkę

Temat, który powraca od kiedy istnieje WordPress. Data wygaśnięcia wpisu w WordPressie nie istnieje. Dla mnie to niestety minus tego systemu. Zapewne w repozytorium WordPress już jest podobna wtyczka, jednak oprócz gotowców chciałbym wam pokazać, jak łatwo sami możemy rozbudować nasz kokpit.

Zatem do dzieła.

W pierwszej kolejności do meta boksu „Opublikuj” musimy dodać wiersz z polem daty wygaśnięcia. Nie będzie to trudne, gdyż istnieje specjalny zaczep do którego możemy podpiąć naszą funkcję, tak aby data wygaśnięcia wyświetlała się pod datą publikacji. W przeciwieństwie do daty publikacji zastosujemy mechanizm z biblioteką jQuery Calendar.

W pierwszej kolejności musimy stworzyć funkcję, która do kokpitu wstawi nam skrypt jQuery Calendar oraz Javascript wtyczki.

    public function enqueue_scripts( $hook ) {
        if( 'post.php' != $hook ) return;
        wp_enqueue_script( 'jquery-ui-datepicker' );
        wp_enqueue_script( 'post-expiring', plugins_url('admin.js', __FILE__), array('jquery'), null, true );
    }

Nasza funkcja dołączy nam niezbędne biblioteki jedynie dla wpisów. Dla innych typów wpisów nie przewidziałem wygaszania treści. Następnie stworzymy funkcję, która pokaże nam pole z datą zakończenia publikacji. Żeby osiągnąć podobny efekt jak w przypadku daty publikacji dołączony wcześniej skrypt JS umożliwi pokazywanie i ukrywanie części o id expiringdatediv.

    public function add_expiring_field() {
        global $post;
        $screen = get_current_screen();
        if( $screen->base != 'post' ) return;
        ?>
        <?php $postexpired = get_post_meta( $post->ID, 'postexpired', true ); // pobieram meta dane ?>
        <div class="misc-pub-section curtime misc-pub-curtime">
            <span id="timestamp"><?php _e('Expiring:', 'postexpiring'); ?></span> <span class="setexpiringdate"><?php echo !empty($postexpired) ? $postexpired : __('Never'); ?></span>
            <a href="#edit_expiringdate" class="edit-expiringdate hide-if-no-js"><span aria-hidden="true"><?php _e( 'Edit' ); ?></span> <span class="screen-reader-text"><?php _e('Edit expiring date', 'postexpiring'); ?></span></a>
            <div id="expiringdatediv" class="hide-if-js">
                <div class="wrap"><input type="text" class="expiring-datepicker" data-exdate="<?php echo esc_attr($postexpired); ?>" value="<?php echo esc_attr($postexpired); ?>" style="font-size: 12px;" name="post_expiring" /><a class="set-expiringdate hide-if-no-js button" href="#edit_expiringdate"><?php _e('OK'); ?></a></div>
                <div><a class="cancel-expiringdate hide-if-no-js button-cancel" href="#edit_expiringdate"><?php _e('Cancel'); ?></a></div>                
            </div>
        </div>
        <?php
    }

Żeby nasze metadane zostały zapisane musimy stworzyć dla zaczepu save_post funkcję, która zapisze datę wygaśnięcia.

    public function save_post_meta( $post_id, $post ) {
        if ( $post_id === null || ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) ) return;
        if ( !current_user_can( 'edit_post', $post_id ) || 'post' != $post->post_type ) return;
        if( isset($_POST['post_expiring']) ) {
            $date_arr  = explode('-', $_POST['post_expiring']);
            if( !isset($date_arr[0]) || !isset($date_arr[1]) || !isset($date_arr[2]) ) {
                delete_post_meta( $post_id, 'postexpired' );
            }
            if ( !empty($_POST['post_expiring']) AND checkdate($date_arr[1], $date_arr[0], $date_arr[2]) ) {
                add_post_meta( $post_id, 'postexpired', esc_sql( $_POST['post_expiring'] ), true ) || update_post_meta( $post_id, 'postexpired', esc_sql( $_POST['post_expiring'] ) );
            }
        }
    }

Powyższa funkcja sprawdza czy użytkownik ma uprawnienia do edycji i czy metadane są zapisywane jedynie dla typu „post”. Zapisanie danych zostanie poprzedzone walidacją daty. Odpowiedzialna jest za to funkcja checkdate. W przypadku, gdy usuniemy datę wygaśnięcia metadane zostaną usunięte.

Ostatnią rzeczą jaka nam pozostała to dodanie do WP_QUERY zaczepu, który pozwoli nam na zmodyfikowanie zapytania SQL. Poprzez metodę set zdefiniujemy wartość meta_query, dzięki której sprawdzimy czy dany wpis posiada klucz postexpired i czy jest większy lub równy obecnej dacie.

    function post_expired( $query ) {
        if ( is_admin() AND !$query->is_main_query() || !is_feed() ) return;
        $query->set( 'meta_query', array(
            'relation' => 'OR',
            array( 'key' => 'postexpired', 'value' => date('Y-m-d', strtotime('NOW')), 'compare' => '>='),
            array('key' => 'postexpired', 'compare' => 'NOT EXISTS'),
        ));
    }

Od teraz nasze wpisy nie będą się pokazywały po dacie wygaśnięcia. Załączona wtyczka jest do pobrania poniżej, możecie ją sobie podejrzeć. Dodatkowo w adminie dla wpisów zostanie dodana kolumna, za datą publikacji, która będzie pokazywała kiedy wygasa wpis. Jeżeli zauważycie błędy proszę zgłaszać je w komentarzach.

Post expiring – wtyczka do wygaszania wpisów po zdefiniowanej dacie

//Edit 08.12.2014

Jak się okazuje nie znalazłem wtyczki, która byłaby na tyle podobna i łatwa. Postanowiłem dodać ją do repozytorium wtyczek WordPressa. Jedna zasadnicza zamiana jak zaszła w kodzie to funkcja post_expired, która była dołączona do akcji pre_get_posts została usunięta. Problem wynikał z tego, że w przypadku dwóch zastosowań pre_get_posts na meta_query WordPress, źle tworzył zapytanie. Zatem pozostało nic innego jak doklejenie do wp_query kodu SQL za pomocą filtra posts_clauses.

You may also like...