Esempio n. 1
0
/**
 * Similar to `media_sideload_image` except that it simply returns the attachment's ID on success
 *
 * @param (string) $file the url of the image to download and attach to the post
 * @param (integer) $post_id the post ID to attach the image to
 * @param (string) $desc an optional description for the image
 *
 * @since 0.1
 */
function pmp_media_sideload_image($file, $post_id, $desc = null)
{
    if (!empty($file)) {
        pmp_debug("      ** sideloading-image {$file} for post[{$post_id}]");
        include_once ABSPATH . 'wp-admin/includes/image.php';
        include_once ABSPATH . 'wp-admin/includes/file.php';
        include_once ABSPATH . 'wp-admin/includes/media.php';
        // Set variables for storage, fix file filename for query strings.
        preg_match('/[^\\?]+\\.(jpe?g|jpe|gif|png)\\b/i', $file, $matches);
        $file_array = array();
        if (empty($matches)) {
            $file_array['name'] = basename($file);
        } else {
            $file_array['name'] = basename($matches[0]);
        }
        // Download file to temp location.
        $file_array['tmp_name'] = download_url($file);
        // If error storing temporarily, return the error.
        if (is_wp_error($file_array['tmp_name'])) {
            return $file_array['tmp_name'];
        }
        // Do the validation and storage stuff.
        $id = media_handle_sideload($file_array, $post_id, $desc);
        // If error storing permanently, unlink.
        if (is_wp_error($id)) {
            @unlink($file_array['tmp_name']);
        }
        return $id;
    }
}
Esempio n. 2
0
/**
 * For each saved search query, query the PMP and perform the appropriate action (e.g., auto draft, auto publish or do nothing)
 *
 * @since 0.3
 */
function pmp_import_for_saved_queries()
{
    $search_queries = pmp_get_saved_search_queries();
    $sdk = new SDKWrapper();
    foreach ($search_queries as $id => $query_data) {
        if ($query_data->options->query_auto_create == 'off') {
            continue;
        }
        $default_opts = array('profile' => 'story', 'limit' => 25);
        $cron_name = 'pmp_last_saved_search_cron_' . sanitize_title($query_data->options->title);
        $last_saved_search_cron = get_option($cron_name, false);
        if (!empty($last_saved_search_cron)) {
            $default_opts['startcreated'] = $last_saved_search_cron;
        } else {
            // First time pulling, honor the initial pull limit
            if (!empty($query_data->options->initial_pull_limit)) {
                $default_opts['limit'] = $query_data->options->initial_pull_limit;
            }
        }
        $query_args = array_merge($default_opts, (array) $query_data->query);
        pmp_debug("========== saved-searching: {$query_data->options->title} ==========");
        pmp_debug($query_args);
        $result = $sdk->queryDocs($query_args);
        if (empty($result)) {
            pmp_debug('  -- NO RESULTS!');
            continue;
        } else {
            pmp_debug("  -- got {$result->items()->count()} of {$result->items()->totalItems()} total");
        }
        // process results, recording the biggest "created" date
        $last_created = null;
        foreach ($result->items() as $item) {
            $syncer = PmpPost::fromDoc($item);
            if ($syncer->post) {
                $syncer->pull();
            } else {
                if ($query_data->options->query_auto_create == 'draft') {
                    $syncer->pull(false, 'draft');
                } else {
                    $syncer->pull(false, 'publish');
                }
            }
            // make sure we got a post out of the deal
            $post_id = $syncer->post->ID;
            if (!$post_id) {
                continue;
            }
            if (is_null($last_created) || $item->attributes->created > $last_created) {
                $last_created = $item->attributes->created;
            }
            // set the category(s)
            if (isset($query_data->options->post_category)) {
                // Make sure "Uncategorized" category doesn't stick around if it
                // wasn't explicitly set as a category for the saved search import.
                $assigned_categories = wp_get_post_categories($post_id);
                $uncategorized = get_category(1);
                // Check for "Uncategorized" in the already-assigned categories
                $in_assigned_cats = array_search($uncategorized->term_id, $assigned_categories);
                // Check for "Uncategorized" in the saved-search categories
                $in_saved_search_cats = array_search($uncategorized->term_id, $query_data->options->post_category);
                // If "Uncategorized" is in assigned categories and NOT in saved-search categories, ditch it.
                if ($in_assigned_cats >= 0 && $in_saved_search_cats === false) {
                    unset($assigned_categories[array_search($uncategorized->term_id, $assigned_categories)]);
                }
                // Set the newly generated list of categories for the post
                wp_set_post_categories($post_id, array_values(array_unique(array_merge($assigned_categories, $query_data->options->post_category))));
            }
        }
        // only set the last-searched-cron if we got a date
        if ($last_created) {
            update_option($cron_name, $last_created);
        }
    }
}
/**
 * When the PMP notification hub sends an update, handle it
 *
 * @since 0.3
 */
function pmp_do_notification_callback()
{
    global $wpdb;
    pmp_debug('========== pmp_do_notification_callback ==========');
    $body = file_get_contents('php://input');
    $hash = hash_hmac('sha1', $body, PMP_NOTIFICATIONS_SECRET);
    // get a COMPLETE mapping of known-PMP-guids to top-level WP-posts
    $pmp_post_data = $wpdb->get_results("select post_id, meta_value, post_parent " . "from {$wpdb->posts} join {$wpdb->postmeta} on (ID = post_id) " . "where meta_key = 'pmp_guid'", ARRAY_A);
    // map to the TOP LEVEL post (attachments map to their parent)
    $pmp_guids = array();
    foreach ($pmp_post_data as $row) {
        if ($row['post_parent'] > 0) {
            $pmp_guids[$row['meta_value']] = $row['post_parent'];
        } else {
            $pmp_guids[$row['meta_value']] = $row['post_id'];
        }
    }
    // check hub signature
    if ($_SERVER['HTTP_X_HUB_SIGNATURE'] !== "sha1={$hash}") {
        var_log('INVALID PMP notifications HTTP_X_HUB_SIGNATURE');
        var_log("  Expected: sha1={$hash}");
        var_log("  Got:      " . $_SERVER['HTTP_X_HUB_SIGNATURE']);
        return;
    }
    // parse xml pubsubhubbub body
    $xml = simplexml_load_string($body);
    foreach ($xml->channel->item as $item) {
        $item_json = json_decode(json_encode($item));
        $item_guid = $item_json->guid;
        // look for Posts tied to that guid
        if (isset($pmp_guids[$item_guid])) {
            $post = get_post($pmp_guids[$item_guid]);
            if ($post) {
                $syncer = PmpPost::fromPost($post);
                $syncer->pull();
            }
        }
    }
}
 /**
  * Debug helper to attach post/doc information
  */
 protected function pmp_debug($msg)
 {
     if ($this->post) {
         $msg = "{$msg} wp[{$this->post->ID}]";
     }
     if ($this->doc) {
         $msg = "{$msg} pmp[{$this->doc->attributes->guid}]";
     }
     pmp_debug($msg);
 }
 /**
  * Get the first valid audio-enclosure-url from an audio doc
  *
  * @since 0.2
  */
 public static function getPlayableUrl($audio_doc)
 {
     $guid = $audio_doc->attributes->guid;
     $enclosure = $audio_doc->links('enclosure')->first();
     if (!$enclosure) {
         pmp_debug("      ** NO ENCLOSURES for audio[{$guid}]");
         return null;
     }
     // supplementary data
     $href = $enclosure->href;
     $type = isset($enclosure->type) ? $enclosure->type : null;
     $uri_parts = parse_url($href);
     $extension = pathinfo($uri_parts['path'], PATHINFO_EXTENSION);
     if (!in_array($uri_parts['scheme'], array('http', 'https'))) {
         pmp_debug("      ** INVALID ENCLOSURE HREF ({$href}) for audio[{$guid}]");
         return null;
     }
     // dereference playlists (m3u)
     if ($type == 'audio/m3u' || $extension == 'm3u') {
         pmp_debug("      ** dereferencing playlist for audio[{$guid}]");
         $response = wp_remote_get($href);
         $lines = explode("\n", $response['body']);
         $href = $lines[0];
         $uri_parts = parse_url($href);
         $extension = pathinfo($uri_parts['path'], PATHINFO_EXTENSION);
         $type = null;
         // we don't know this anymore
     }
     // check for "known" types that start with audio/*
     if ($type && in_array($type, array_values(get_allowed_mime_types()))) {
         if (preg_match('/^audio/', $type)) {
             pmp_debug("      ** known mime type '{$type}' for audio[{$guid}]");
             return $href;
         }
     }
     if (in_array($extension, wp_get_audio_extensions())) {
         pmp_debug("      ** known extension '{$extension}' for audio[{$guid}]");
         return $href;
     }
     // not sure what this is
     pmp_debug("      ** UNABLE TO PLAY enclosure ({$href}) for audio[{$guid}]");
     return null;
 }