Ab und an muss man unverständliche Dinge neu lernen. Der Versuch direkte Kalendereinladungen per WordPress zu versenden, endet im Disaster. Aber warum?

mail() ist eine PHP Funktion die Mails verschickt. wp_mail() ist die WordPress Funktion. wp_mail kann es aber nicht, da es den Code nicht korrekt formatiert und daher die Mails entweder mit einer ICS Datei ankommen, oder der Mailserver diese nicht lesen kann. Mit mail() umzusetzen ist möglich, aber ist aufwändig und nutzt nicht die WordPress Möglichkeiten.

Daher habe ich ein Zwitter gemacht. Ich nutze eine eigene Funktion, greife aber auf das Mailversandgerüst von WordPress zurück.

<?php
function sendOutlookInvitation($participants, $subject, $desc, $start_time, $end_time, $location='') {
	global $phpmailer;
	if ( ! ( $phpmailer instanceof PHPMailer\PHPMailer\PHPMailer ) ) {
		require_once ABSPATH . WPINC . '/PHPMailer/PHPMailer.php';
		require_once ABSPATH . WPINC . '/PHPMailer/SMTP.php';
		require_once ABSPATH . WPINC . '/PHPMailer/Exception.php';
		$phpmailer = new PHPMailer\PHPMailer\PHPMailer( true );

		$phpmailer::$validator = static function ( $email ) {
			return (bool) is_email( $email );
		};
	}

	$phpmailer->addAddress($participants[0]);
	foreach ($participants as $i => $attendee) {
		if ($i >= 1) $phpmailer->addCC($attendee);
	}

	$phpmailer->WordWrap = 50;
	$phpmailer->isHTML(true);

	$urlparts = parse_url(site_url());
	$organizer = $urlparts['host'];

	$text = "BEGIN:VCALENDAR\r\n".
		"VERSION:2.0\r\n".
		"PRODID:-//wukch-calender//mailer/NONSGML v1.0//EN\r\n".
		"METHOD:REQUEST\r\n".
		"BEGIN:VEVENT\r\n".
		"UID:" . md5(uniqid(mt_rand(), true)) . "wuk.ch\r\n".
		"DTSTAMP:" . gmdate('Ymd').'T'. gmdate('His') . "Z\r\n".
		"DTSTART:" . date('Ymd\THis', $start_time) . "Z\r\n".
		"DTEND:" . date('Ymd\THis', $end_time) . "Z\r\n".
		"SUMMARY:".$subject."\r\n".
		"ORGANIZER;CN=".$participants[0].":mailto:website@".$participants[0]."\r\n".
		"LOCATION:".$location."\r\n".
		"DESCRIPTION:".$desc."\r\n";

		foreach ($participants as $i => $attendee) {
			$text .= "ATTENDEE;CUTYPE=INDIVIDUAL;ROLE=REQ-PARTICIPANT;PARTSTAT=NEEDS-ACTION;RSVP=TRUE;CN".$attendee.";X-NUM-GUESTS=0:MAILTO:".$attendee."\r\n";
		}
	$text .= "END:VEVENT\r\n".
		"END:VCALENDAR\r\n";

	$headers = "From: ".$participants[0]."\n";
	$headers = "Reply-To: ".$participants[0]."\n";
	$headers .= 'Content-Type:text/calendar; Content-Disposition: inline; charset=utf-8;\r\n';
	$headers .= "Content-Type: text/plain;charset=\"utf-8\"\r\n";

	$phpmailer->Subject = $subject;
	$phpmailer->Body = $desc;
	$phpmailer->AltBody = $text;
	$phpmailer->Ical = $text;

	if(!$phpmailer->send()) { return false; }
	return true;
}

Ich habe die Funktion gebaut, dass mir Kunden eine Einladung zusenden können an freien Terminen. Sich selbst muss man natürlich auch einladen. Die erste Mailadresse die angegeben wird, wird automatisch als Organisator verwendet:

<?php
$participants = array('test@test.ch','kunde@domain.de');
$subject = 'Betreff der Mail';
$desc = "Beschreibung der Mail";
$start_time = gmttime(); // GMT Zeit des Start
$end_time = gmttime() // GMT Zeit Ende
$location = 'Zoom oder vor Ort'
sendOutlookInvitation($participants, $subject, $desc, $start_time, $end_time, $location='');

Viel Spass damit.

Mit dem folgenden Code, werden alle Bilder auf Lazy Load bei WordPress umgestellt.

add_filter( 'wp_get_attachment_image_attributes', 'alter_att_attributes_wpse_102079', 20);
function alter_att_attributes_wpse_102079($attr) {
	if (strpos($attr['class'], 'skip-lazy') === false) {
		$attr['data-original'] = $attr['src'];
		unset($attr['src']);
		if (isset($attr['srcset'])) {
			$attr['data-original-set'] = $attr['srcset'];
			unset($attr['srcset']);
		}
		$attr['class'] .= ' lazy';
	}
	return $attr;
}
function debug_hook2() { echo "<p>--- Hook ---</p>";}
function debug_hook($hook) {
	global $wp_filter, $debughook;
	$debughook = $hook;
	$arr = array();
	foreach ($wp_filter[$hook]->callbacks as $nr => $ho) {
		$arr[$nr] = key($ho);
	}
	add_action($hook, 'debug_hook2',1);
	foreach ($arr as $nr => $ho) {
		add_action($hook, 'debug_hook2',$nr+1);
	}

	$out = "<pre>".print_r($arr,true)."</pre>";
	return $out;
}
echo debug_hook('woocommerce_email_order_details');
add_filter( 'wp_mail_from', function() { return 'example@example.com'; } );
add_filter( 'wp_mail_from_name', function() { return 'Example'; } );	

Schriften werden anschliessend nicht mehr von gfonts geladen.

add_filter( 'elementor/frontend/print_google_fonts', '__return_false' );
add_action('wp_enqueue_scripts', 'google_fonts_local');
function google_fonts_local() {
	wp_register_style('google_fonts_local', plugins_url('fonts/stylesheet.css',__FILE__ ));
	wp_enqueue_style('google_fonts_local');
}

Schriften müssen danach weiterhin lokal über das CSS geladen werden und muss manuell eingebaut werden!

add_filter( 'site_status_tests', 'sitehealthcheck' );
function sitehealthcheck( $tests ) {
	unset($test);
	return $tests;
}
if (!wp_next_scheduled('rev_cleanup')) {
	wp_schedule_event( time(), 'daily', 'rev_cleanup' );
}
add_action( 'rev_cleanup', 'do_rev_cleanup', 10);
function do_rev_cleanup() {
    global $wpdb;
	$abfrage = "DELETE a,b,c FROM wp_posts a LEFT JOIN wp_term_relationships b ON (a.ID = b.object_id) LEFT JOIN wp_postmeta c ON (a.ID = c.post_id)  WHERE a.post_type = 'revision' AND a.post_date < '".date("Y-m-d",strtotime('-2 weeks'))."';";
	$wpdb->get_results($abfrage);
}
add_filter('admin_email_check_interval', '__return_false');
remove_action( 'add_option_new_admin_email', 'update_option_new_admin_email' );
remove_action( 'update_option_new_admin_email', 'update_option_new_admin_email' );
function wuk_update_option_new_admin_email( $old_value, $value ) { update_option( 'admin_email', $value ); }
add_action( 'add_option_new_admin_email', 'wuk_update_option_new_admin_email', 10, 2 );
add_action( 'update_option_new_admin_email', 'wuk_update_option_new_admin_email', 10, 2 );

Code muss in wp-config.php eingefügt werden:

define('WP_DISABLE_FATAL_ERROR_HANDLER', true);
add_action( 'wp_enqueue_scripts', 'add_theme_scripts',80);
function add_theme_scripts() {
	wp_register_script('demo-js','https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js');
	wp_enqueue_script('demo-js');

}
add_filter( 'script_loader_tag', 'add_demo_to_script', 90, 3 );
function add_demo_to_script( $tag, $handle, $source ) {
    if ( 'demo-js' === $handle ) {
        $tag = '<script data-ad-client="ca-pub-9175988955138834" async src="' . $source . '"></script>';
    }
    return $tag;
}