Пример #1
0
 function setUp()
 {
     parent::setUp();
     $settings = get_option('pmp_settings');
     if (empty($settings['pmp_api_url']) || empty($settings['pmp_client_id']) || empty($settings['pmp_client_secret'])) {
         $this->skip = true;
     } else {
         $this->skip = false;
         $this->sdk_wrapper = new SDKWrapper();
         // A test query that's all but guaranteed to return at least one result.
         $this->query = array('text' => 'Obama', 'limit' => 10, 'profile' => 'story');
         $this->editor = $this->factory->user->create();
         $user = get_user_by('id', $this->editor);
         $user->set_role('editor');
         wp_set_current_user($user->ID);
         $result = $this->sdk_wrapper->queryDocs($this->query);
         $this->pmp_story = $result->items()->first();
         $syncer = PmpPost::fromDoc($this->pmp_story);
         $syncer->pull();
     }
 }
Пример #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);
        }
    }
}
Пример #3
0
/**
 * 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();
            }
        }
    }
}
 /**
  * check push-ability
  */
 function test_is_writeable()
 {
     $syncer = new PmpPost($this->pmp_story, $this->wp_post);
     $this->assertFalse($syncer->is_writeable());
     // i can always push new stories (even with a guid)
     $syncer = new PmpPost(null, $this->wp_post);
     $this->assertTrue($syncer->is_writeable());
     // or an actual writeable doc
     $this->pmp_story->scope = 'write';
     $syncer = new PmpPost($this->pmp_story, $this->wp_post);
     $this->assertTrue($syncer->is_writeable());
 }
Пример #5
0
/**
 * Handle pushing post content to PMP. Works with posts and attachments (images).
 *
 * @since 0.2
 */
function pmp_handle_push($post_id)
{
    $post = get_post($post_id);
    $syncer = PmpPost::fromPost($post);
    if ($syncer->push()) {
        return $syncer->doc->attributes->guid;
    } else {
        return null;
    }
}
Пример #6
0
function _pmp_ajax_create_post($is_draft = false)
{
    $sdk = new SDKWrapper();
    // make sure we don't search for a blank string
    $guid = empty($_POST['pmp_guid']) ? 'nothing' : $_POST['pmp_guid'];
    $doc = $sdk->fetchDoc($guid);
    if (empty($doc)) {
        return array('success' => false, 'message' => "Cannot find PMP document {$guid}");
    } else {
        $syncer = PmpPost::fromDoc($doc);
        // pull from PMP
        if ($syncer->pull()) {
            return array('success' => true, 'data' => array('edit_url' => html_entity_decode(get_edit_post_link($syncer->post->ID)), 'post_id' => $syncer->post->ID));
        } else {
            return array('success' => false, 'message' => "Error: unable to pull PMP document {$guid}");
        }
    }
}
 /**
  * push a post
  */
 function test_push_post()
 {
     $syncer = new PmpPost(null, $this->local_post);
     $this->assertTrue($syncer->push());
     // re-fetch the doc, to make sure indexing has caught up
     sleep(1);
     $syncer->doc->load();
     // the parent post
     $story = $syncer->doc;
     $this->assertEquals('my post title', $story->attributes->title);
     $this->assertEquals('my post excerpt', $story->attributes->teaser);
     $this->assertEquals('here it is with content and some more content', $story->attributes->description);
     $this->assertStringStartsWith('<p>here it is with content</p><a', $story->attributes->contentencoded);
     $this->assertStringEndsWith('</a><p>and some more content</p><p>&nbsp;</p>', $story->attributes->contentencoded);
     $this->assertContains('pmp-wordpress', $story->attributes->itags);
     $this->assertContains('pmp-wordpress-test-content', $story->attributes->itags);
     $this->assertContains("post-id-{$syncer->post->ID}", $story->attributes->itags);
     $this->assertEquals('1999-12-31T12:12:12+00:00', $story->attributes->published);
     $this->assertEquals('admin', $story->attributes->byline);
     $this->assertObjectHasAttribute('tags', $story->attributes);
     $this->assertContains('foo', $story->attributes->tags);
     $this->assertContains('bar', $story->attributes->tags);
     $this->assertContains('and another one', $story->attributes->tags);
     $this->assertCount(1, $story->links->profile);
     $this->assertRegexp('/profiles\\/story$/', $story->links->profile[0]->href);
     $this->assertCount(1, $story->links->alternate);
     $this->assertRegexp("/^http.*\\?p={$syncer->post->ID}\$/", $story->links->alternate[0]->href);
     $this->assertObjectNotHasAttribute('collection', $story->links);
     // attachments
     $this->assertCount(3, $story->links->item);
     $this->assertContains('urn:collectiondoc:image', $story->links->item[0]->rels);
     $this->assertContains('urn:collectiondoc:image:featured', $story->links->item[0]->rels);
     $this->assertContains('urn:collectiondoc:image', $story->links->item[1]->rels);
     $this->assertContains('urn:collectiondoc:audio', $story->links->item[2]->rels);
     $this->assertCount(3, $story->items);
     $this->assertNotNull($story->items[0]);
     $this->assertNotNull($story->items[1]);
     $this->assertNotNull($story->items[2]);
     // check everything on the first image
     $image = $story->items[0];
     $this->assertEquals('real-alt-text', $image->attributes->title);
     $this->assertObjectNotHasAttribute('description', $image->attributes);
     $this->assertObjectNotHasAttribute('byline', $image->attributes);
     $this->assertRegexp('/profiles\\/image$/', $image->links->profile[0]->href);
     $this->assertCount(1, $image->links->alternate);
     $this->assertRegexp("/^http.*\\?attachment_id={$syncer->attachment_syncers[0]->post->ID}\$/", $image->links->alternate[0]->href);
     $this->assertCount(3, $image->links->enclosure);
     foreach ($image->links->enclosure as $encl) {
         $this->assertEquals('image/jpeg', $encl->type);
         $this->assertInternalType('integer', $encl->meta->height);
         $this->assertInternalType('integer', $encl->meta->width);
         $this->assertTrue(in_array($encl->meta->crop, array('square', 'small', 'medium', 'large', 'primary')));
     }
     // second image should have different attributes
     $image = $story->items[1];
     $this->assertEquals('imagetest', $image->attributes->title);
     $this->assertEquals('my-excerpt', $image->attributes->description);
     $this->assertEquals('my-byline', $image->attributes->byline);
     $this->assertRegexp('/profiles\\/image$/', $image->links->profile[0]->href);
     // and how about that audio attachment?
     $audio = $story->items[2];
     $this->assertEquals('mpthreetest', $audio->attributes->title);
     $this->assertObjectNotHasAttribute('description', $audio->attributes);
     $this->assertObjectNotHasAttribute('byline', $audio->attributes);
     $this->assertRegexp('/profiles\\/audio$/', $audio->links->profile[0]->href);
     $this->assertCount(1, $audio->links->alternate);
     $this->assertRegexp("/^http.*\\?attachment_id={$syncer->attachment_syncers[2]->post->ID}\$/", $audio->links->alternate[0]->href);
     $this->assertCount(1, $audio->links->enclosure);
     $this->assertRegexp('/mpthreetest\\.mp3$/', $audio->links->enclosure[0]->href);
     $this->assertEquals('audio/mpeg', $audio->links->enclosure[0]->type);
     $this->assertEquals(12, $audio->links->enclosure[0]->meta->duration);
     // check that audio tag gets stripped from description/contentencoded
     $this->assertNotContains('audio', $story->attributes->contentencoded);
     $this->assertNotContains('mpthreetest', $story->attributes->contentencoded);
     $this->assertNotContains('audio', $story->attributes->description);
     $this->assertNotContains('mpthreetest', $story->attributes->description);
     // but the embedded images are still there (for now)
     $this->assertContains('<img', $story->attributes->contentencoded);
     $this->assertContains('imagetest', $story->attributes->contentencoded);
     $this->assertNotContains('imagetest', $story->attributes->description);
 }
 /**
  * pull tags into post
  */
 function test_pull_tags()
 {
     $tags = wp_get_post_tags($this->wp_post->ID);
     $this->assertCount(0, $tags);
     $this->pmp_story->attributes->tags = array('foo', 'bar', 'something else here');
     $syncer = new PmpPost($this->pmp_story, $this->wp_post);
     $this->assertTrue($syncer->pull(true));
     // check tags
     $tags = wp_get_post_tags($this->wp_post->ID);
     $this->assertCount(3, $tags);
     $get_tag_names = function ($tag) {
         return $tag->name;
     };
     $ordered_tags = array_map($get_tag_names, $tags);
     sort($ordered_tags);
     $this->assertEquals('bar', $ordered_tags[0]);
     $this->assertEquals('foo', $ordered_tags[1]);
     $this->assertEquals('something else here', $ordered_tags[2]);
     // additional tag
     $this->pmp_story->attributes->tags = array('bar', 'tags are additive!');
     $syncer = new PmpPost($this->pmp_story, $this->wp_post);
     $this->assertTrue($syncer->pull(true));
     // should have added new tag
     $tags = wp_get_post_tags($this->wp_post->ID);
     $this->assertCount(4, $tags);
     $ordered_tags = array_map($get_tag_names, $tags);
     sort($ordered_tags);
     $this->assertEquals('bar', $ordered_tags[0]);
     $this->assertEquals('foo', $ordered_tags[1]);
     $this->assertEquals('something else here', $ordered_tags[2]);
     $this->assertEquals('tags are additive!', $ordered_tags[3]);
     // they don't just go away
     unset($this->pmp_story->attributes->tags);
     $syncer = new PmpPost($this->pmp_story, $this->wp_post);
     $this->assertTrue($syncer->pull(true));
     $tags = wp_get_post_tags($this->wp_post->ID);
     $this->assertCount(4, $tags);
 }