From 85aaab14787b475b38a2dbae8b9d5c60ecd5431c Mon Sep 17 00:00:00 2001 From: pfefferle Date: Fri, 28 Feb 2014 13:35:03 +0100 Subject: [PATCH] the plugin now sends webmentions asynchron --- webmention.php | 108 ++++++++++++++++++++++++++++++++++++------------- 1 file changed, 79 insertions(+), 29 deletions(-) diff --git a/webmention.php b/webmention.php index d2c61b64..338a95da 100755 --- a/webmention.php +++ b/webmention.php @@ -46,6 +46,9 @@ public static function init() { add_action('wp_head', array('WebMentionPlugin', 'html_header'), 99); add_action('send_headers', array('WebMentionPlugin', 'http_header')); + // run webmentions before the other pinging stuff + add_action('do_pings', array('WebMentionPlugin', 'do_webmentions'), 5, 1); + add_action('publish_post', array('WebMentionPlugin', 'publish_post_hook')); add_filter('webmention_title', array('WebMentionPlugin', 'default_title_filter'), 10, 4); @@ -194,7 +197,7 @@ public static function parse_query($wp) { $comment_ID = wp_new_comment($commentdata); } - echo "WebMention received... Thanks :)"; + echo apply_filters('webmention_success_message', 'WebMention received... Thanks :)'); do_action( 'webmention_post', $comment_ID ); exit; @@ -265,6 +268,18 @@ public static function default_title_filter( $title, $contents, $target, $source return $title; } + /** + * Marks the post as "no webmentions sent yet" + * + * @param int $post_ID + */ + public static function publish_post_hook( $post_ID ) { + // check if pingbacks are enabled + if ( get_option('default_pingback_flag') ) + add_post_meta( $post_ID, '_mentionme', '1', true ); + } + + /** * Send WebMentions * @@ -272,7 +287,7 @@ public static function default_title_filter( $title, $contents, $target, $source * @param string $target target url * @return array of results including HTTP headers */ - public static function send_webmention($source, $target) { + public static function send_webmention( $source, $target ) { // stop selfpings if ($source == $target) { return false; @@ -282,7 +297,8 @@ public static function send_webmention($source, $target) { $webmention_server_url = self::discover_endpoint( $target ); $args = array( - 'body' => 'source='.urlencode($source).'&target='.urlencode($target) + 'body' => 'source='.urlencode($source).'&target='.urlencode($target), + 'timeout' => 100 ); if ($webmention_server_url) { @@ -292,32 +308,20 @@ public static function send_webmention($source, $target) { return false; } - /** - * The WebMention autodicovery meta-tags - */ - public static function html_header() { - // backwards compatibility with v0.1 - echo ''."\n"; - echo ''."\n"; - } - - /** - * The WebMention autodicovery http-header - */ - public static function http_header() { - // backwards compatibility with v0.1 - header('Link: <'.site_url("?webmention=endpoint").'>; rel="http://webmention.org/"', false); - header('Link: <'.site_url("?webmention=endpoint").'>; rel="webmention"', false); - } - /** * Send WebMentions if new Post was saved * + * You can still hook this function directly into the `publish_post` action: + * + * + * add_action('publish_post', array('WebMentionPlugin', 'send_webmentions')); + * + * * @param array $links Links to ping * @param array $punk Pinged links * @param int $id The post_ID */ - public static function publish_post_hook( $post_ID ) { + public static function send_webmentions( $post_ID ) { // get source url $source = get_permalink($post_ID); @@ -327,21 +331,49 @@ public static function publish_post_hook( $post_ID ) { // initialize links array $links = array(); - // Find all external links in the source - if (preg_match_all("/]+href=.(https?:\/\/[^'\"]+)/i", $post->post_content, $matches)) { - $links = $matches[1]; - } + // Parsing the post, external links (if any) + $links = wp_extract_urls( $post->post_content ); // filter links $targets = apply_filters('webmention_links', $links, $post_ID); $targets = array_unique($targets); foreach ($targets as $target) { - // @todo check response - $data = self::send_webmention($source, $target); + // send webmention + $response = self::send_webmention($source, $target); + + // check response + if ( !is_wp_error( $response ) ) { + $pung = get_pung($post_ID); + + // if not already added to punged urls + if (!in_array($target, $pung)) { + // tell the pingback function not to ping these links again + add_ping( $post_ID, $target ); + } + } + + // if flood control is is active, rescedule the the cron + if (403 == wp_remote_retrieve_response_code( $response )) { + add_post_meta( $post_ID, '_mentionme', '1', true ); + wp_schedule_single_event( time()+60, 'do_pings' ); + } } } + /** + * Do webmentions + */ + public static function do_webmentions() { + global $wpdb; + // get all posts that should be "mentioned" + while ($mention = $wpdb->get_row("SELECT ID, meta_id FROM {$wpdb->posts}, {$wpdb->postmeta} WHERE {$wpdb->posts}.ID = {$wpdb->postmeta}.post_id AND {$wpdb->postmeta}.meta_key = '_mentionme' LIMIT 1")) { + delete_metadata_by_mid( 'post', $mention->meta_id ); + // send them webmentions + self::send_webmentions( $mention->ID ); + } + } + /** * Finds a WebMention server URI based on the given URL. * @@ -410,6 +442,24 @@ public static function discover_endpoint( $url ) { return false; } + /** + * The WebMention autodicovery meta-tags + */ + public static function html_header() { + // backwards compatibility with v0.1 + echo ''."\n"; + echo ''."\n"; + } + + /** + * The WebMention autodicovery http-header + */ + public static function http_header() { + // backwards compatibility with v0.1 + header('Link: <'.site_url("?webmention=endpoint").'>; rel="http://webmention.org/"', false); + header('Link: <'.site_url("?webmention=endpoint").'>; rel="webmention"', false); + } + /** * converts relative to absolute urls * @@ -446,4 +496,4 @@ public static function make_url_absolute( $base, $rel ) { } // end check if class already exists -endif; \ No newline at end of file +endif;