it-swarm.com.de

Beiträge eines benutzerdefinierten Beitragstyps (Ereignis) durchlaufen und eine .ics (iCal) -Datei erstellen?

Ich brauche wirklich Ihre Hilfe bei einer Funktion, mit der ich bisher noch nie gearbeitet habe.

Ich habe einen benutzerdefinierten Post-Typ namens wr_event. Und ich habe diesen benutzerdefinierten WP_Query erstellt, um alle Beiträge für diesen Beitragstyp abzurufen, die "jünger" als gestern sind. Ziemlich einfach und das funktioniert wie ein Zauber.

function event_list_iCal() {

    $yesterday = time() - 24*60*60;
    $args = array(
        'post_type' => 'wr_event',
        'posts_per_page' => -1, // show all posts
        'meta_key' => 'event_date',
        'orderby' => 'meta_value_num',
        'order' => 'ASC',
        'meta_value' => $yesterday,
        'meta_compare' => '>',
    );

    $loop = new WP_Query( $args );
    $ical = "BEGIN:VCALENDAR
    VERSION:2.0
    PRODID:-//hacksw/handcal//NONSGML v1.0//EN";

    $posts = get_posts( $args );
    foreach( $posts as $post ) : setup_postdata($post);
        $ical .= "BEGIN:VEVENT
        UID:" . md5(uniqid(mt_Rand(), true)) . "mysite.com
        DTSTAMP:" . gmdate('Ymd').'T'. gmdate('His') . "Z
        DTSTART:".unixToiCal(get_event_date($post), get_event_time($post))."00Z
        DTEND:".unixToiCal(get_event_end_date($post), get_event_end_time($post))."00Z
        SUMMARY:".get_the_title($post->ID)."
        DESCRIPTION:".get_the_content($post->ID)."
        END:VEVENT";
    endforeach;

    $ical .= "END:VCALENDAR";

    header('Content-type: text/calendar; charset=utf-8');
    header('Content-Disposition: inline; filename=calendar.ics');
    echo $ical;
    exit;
}

function unixToiCal($uStamp = 0, $tzone = 0.0) {
    $uStampUTC = $uStamp + ($tzone * 3600);       
    $stamp  = date("Ymd\THis\Z", $uStampUTC);
    return $stamp;       
} 

Ich benutze diesen Funktionsaufruf in meinem index.php, um alle "bevorstehenden" Ereignisse aufzulisten.

Erstellen einer .ics-Datei.

Es gibt noch eine weitere Funktion, die ich gerne hätte. Ich möchte eine .ics (iCal) -Datei mit allen "bevorstehenden" Ereignissen erstellen. Ich denke, das sollte nicht zu schwierig sein, da ich die Frage bereits habe.

Irgendwelche Ideen dazu? Ich würde mich sehr über Hilfe freuen.

Update:

Ich habe noch zwei Probleme mit der .ics-Kalenderdatei.

Ich habe eine Funktion get_event_date($timestamp), die einen Zeitstempel des Ereignisdatums zurückgibt. Es gibt jedoch einen (für mich) ziemlich komplizierten Teil.

Es gibt zwei Variablen $date[0] und $time[0], die unterschiedliche Formate haben. Der $date[0] enthält einen Zeitstempel 1347667200 und der $time[0] enthält eine Zeichenfolge, z.B. 14:00. Ich muss jetzt den endgültigen Zeitstempel des "Datums" plus "Uhrzeit" berechnen, um ihn an die Funktion unixToical() weiterzuleiten.

if ( $timestamp ) { 
            if ( !empty( $time[0]) ) {
                $time = explode(':', $time[0]);
                $hours = $time[0];
                $minutes = $time[1];
            } else { 
                //$hours = "00";
                //$minutes = "00";
            }
            $seconds = "00";
            return $date[0] + ($hours * 60)  + $minutes;
            exit;
        }

Der Teil, in dem ich $hours auf "00" setze, ist für den Fall, dass keine Zeit eingestellt ist. In diesem Fall möchte ich im Finale .ics auf "00:00" (Mitternacht) setzen.

Irgendeine Idee, was ich hier falsch mache. Ich vermute, dies könnte das Problem sein, warum beim Importieren der Kalenderdatei in iCal nur das erste Ereignis importiert wird. (Beim Öffnen der Datei mit einem Texteditor sind alle Ereignisse dort)

1
mathiregister

Dies basiert vollständig auf Event Organizer (einem Plug-In, das ich entwickelt habe). Der Code wird fast direkt von der Quelle abgerufen, jedoch mit Änderungen. Als solches habe ich den Code nicht wie angegeben getestet.

Schritt 1: Erstellen Sie einen Feed

Das ist ganz einfach:

add_action('init','wpse63611_add_events_feed');
function wpse63611_add_events_feed(){
     add_feed('my-events','wpse63611_events_feed_output');
}

Dies fügt Ihrer Site einen Feed hinzu: www.site.com?feed=my-events oder www.site.com/feed/my-events, wenn Sie hübsche Permalinks haben. Der Rückruf wpse63611_events_feed_output() gibt den Inhalt der ICAL-Datei aus. Aber zuerst...

Schritt 2: Ändern Sie die Abfrage

WordPress weiß nicht, was dieser Feed enthalten soll. Hier verwenden wir den pre_get_posts, um WordPress mitzuteilen, dass wir für diesen Feed Posts des Post-Typs 'wr_event' wünschen. Wir könnten Events von einer bestimmten Kategorie, einem Veranstaltungsort oder auch zwischen bestimmten Daten erhalten.

Wenn Sie die Abfrage von der Ausgabe trennen, können Sie mehrere Feeds erstellen, die dieselbe Ausgabefunktion verwenden, jedoch unterschiedliche Ereignisse abfragen (basierend auf Zeit, Ort, Kategorie usw.).

add_action( 'pre_get_posts', 'wpse63611_event_feed_query' );
function wpse63611_event_feed_query( $query ) {

     $yesterday = current_time('timestamp') - 24*60*60;
     $compare = $latest ? '>' : '<';

     if( $query->is_feed('eo-events') ){
         $query->set('post_type', 'wr_event');
         $query->set('posts_per_page', -1);
         $query->set('meta_key', 'event_date');
         $query->set('orderby', 'meta_value_num');
         $query->set('order', 'ASC');
         $query->set('meta_compare', $compare);
         $query->set('meta_value', $value);
     }
}

Schritt 3: Der Inhalt der Datei ICS

Wie bereits erwähnt, ist wpse63611_events_feed_output() für das Drucken der Ausgabe unseres Feeds verantwortlich.

 function wpse63611_events_feed_output(){
      //Let's give it a name;
      $filename = urlencode( 'my_events' . date('Y-m-d') . '.ics' );

      //Collect output 
      ob_start();

      // File header
      header( 'Content-Description: File Transfer' );
      header( 'Content-Disposition: attachment; filename=' . $filename );
      header('Content-type: text/calendar');
      header("Pragma: 0");
      header("Expires: 0");
?>
BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//<?php  get_bloginfo('name'); ?>//NONSGML Events //EN
CALSCALE:GREGORIAN
X-WR-CALNAME:<?php echo get_bloginfo('name');?> - Events

<?php

    // Loop through events
    if ( have_posts() ):

         $now = new DateTime();
         $datestamp =$now->format('Ymd\THis\Z');

         while( have_posts() ): the_post();
              global $post;

              $uid = md5(uniqid(mt_Rand(), true))."@mysite.com";

              $start = unixToiCal(get_event_date($post), get_event_time($post));
              $end = unixToiCal(get_event_end_date($post), get_event_end_time($post));

              $summary = wpse63611_escape_icalText(get_the_title())
              $description = apply_filters('the_excerpt_rss',  get_the_content());
              $description = wpse63611_escape_icalText($description);

BEGIN:VEVENT
UID:<?php echo $uid;?>

DTSTAMP:<?php echo $datestamp;?>

DTSTART:<?php echo $start; ?>

DTEND:<?php echo $end; ?>

SUMMARY:<?php echo wpse63611_esc_ical_text($summary);?>

DESCRIPTION:<?php echo wpse63611_esc_ical_text($description);?>

END:VEVENT

         endwhile;

    endif;
?>
END:VCALENDAR
<?php

    //Collect output and echo 
    $eventsical = ob_get_contents();
    ob_end_clean();
    echo $eventsical;
    exit();
}   

Ich habe die Funktion unixToiCal verwendet, die Sie in Ihrer Frage definiert haben. Ich habe auch Folgendes verwendet, um alles zu entfernen, was einen ICAL-Parser stören könnte:

 function wpse63611_esc_ical_text( $text='' ){

    $text = str_replace("\\", "\\\\", $text);
    $text = str_replace(",", "\,", $text);
    $text = str_replace(";", "\;", $text);
    $text = str_replace("\n", "\n ", $text);

    return $text;
 }
4
Stephen Harris

Versuche dies:

Fügen Sie diese Funktionen zuerst der functions.php Ihres Themas hinzu

//this will call the download function if needed
function Ical_download() {
    global $wp;
    global $wp_query;
    if (isset($wp->query_vars["ical_download"])){
        event_list_iCal();
        exit();
    }
}

add_action('template_redirect', 'Ical_download');


//this will add ical_download to the list of query vars
function ical_download_query_val() {
    global $wp;
    $wp->add_query_var('ical_download');
}

add_filter('init', 'ical_download_query_val');
function event_list_iCal( $latest = true ) {

    $yesterday = time() - 24*60*60;
    $compare = $latest ? '>' : '<';

    $args = array(
        'post_type' => 'wr_event',
        'posts_per_page' => -1, // show all posts
        'meta_key' => 'event_date',
        'orderby' => 'meta_value_num',
        'order' => 'ASC',
        'meta_value' => $yesterday,
        'meta_compare' => $compare,
    );

    $loop = new WP_Query( $args );
    $ical = "BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//hacksw/handcal//NONSGML v1.0//EN
";
    while ( $loop->have_posts() ) : $loop->the_post();

    $ical .= "BEGIN:VEVENT
UID:" . md5(uniqid(mt_Rand(), true)) . "example.com
DTSTAMP:" . gmdate('Ymd').'T'. gmdate('His') . "Z
DTSTART:".get_event_date($post)."00Z
DTEND:".get_event_end_date($post);."00Z
SUMMARY:".$post->title."
DESCRIPTION:".$post->content."
END:VEVENT
";

    endwhile;

    $ical .= "END:VCALENDAR";

    //set correct content-type-header
    header('Content-type: text/calendar; charset=utf-8');
    header('Content-Disposition: inline; filename=calendar.ics');
    echo $ical;
    exit;

}

Aktualisieren Sie also einfach die Sommer- und Beschreibungsfelder sowie die Start- und Endzeiten auf das richtige Format, und Ihr Download-Link sollte ungefähr so ​​aussehen:

<a href="<?php echo get_bloginfo('url').'?ical_download';?>">Download iCal</a>
2
Bainternet