0

First time poster, pardon my mistakes.

I am trying to use the content_save_pre filter to grab a URL in the first line of a post and save it into a custom meta, and also set the post format as a link. All of that works fine, for the most part.

public function save_content($content) {

    // short circuit if special ignore tag is included anywhere in content
    if ( stripos($content, "<!--ignore-->") != false ) {
        return $content;
    }

    $lines = explode("\n", $content);

    // added href handling so that HTML anchor-links can be handled
    $regex = '/(?:href="([^\s"]+))|((?:http|https|ftp|ftps)\:\/\/[a-zA-Z0-9\-\.]+\.[a-zA-Z]{2,4}(?:\/\S*)?)/';

    $match = preg_match($regex, $lines[0], $matches);

    if ( $match ) {
        $url = $matches[0];
        $url = preg_replace('/&?utm_(.*?)\=[^&]+/im', '', $url);

        global $post;
        if ( $post == null || !isset($post->ID) ) {
            // this is part of the problem
            return $content;
        }

        $result = $this->common_save($post->ID, \LinkedList\Meta::SOURCE_URL, $url);

        // prevent save fields from overwriting a blank on top of just added value
        add_filter('linked_list_save_fields', function($bool){
            return false;
        });

        set_post_format($post->id, 'link');

        unset($lines[0]);
        return join("\n", $lines);

    }

    return $content;

}

I add the filter for that method elsewhere, but like so:

add_filter('content_save_pre', array($this, 'save_content'), 9, 1);

The problem I am having is when using the Android/iOS WordPress app, which I think is using the XML-RPC interface to the self hosted WordPress, the global $post is not populated, and common_save (a method that saves custom meta fields) and set_post_format do not work without it.

Is there anyway to the $post->ID while in the XML-RPC "content_save_pre" so this could work? I have been using the add_action('all', ...) to see if the XML-RPC saving actually works, and it is definitely being called, it just cannot continue because of the lack of $post being populated.

Another alternative I thought would be to attach a special custom meta and then use a frequently scheduled cron handle it later, but that seems complicated and I would have to dive really deep into that.

Thanks!

1

After asking around and looking for alternatives, I came up with a working solution that works in the web frontend and in the Android/iOS XML-RPC based apps.

This is the filter.

add_filter('wp_insert_post_data', array($this, 'save_content2'), 9, 2);

I am pretty sure it is called before the content_save_pre filter. It allows direct access to the post fields like the post content and the post metadata like the ID.

public function save_content2($data, $post) {

    $content = $data['post_content'];

    // short circuit if special ignore tag is included anywhere in content
    if ( stripos($content, "<!--ignore-->") != false ) {
        return $data;
    }

    if ( trim($content) == '' ) {
        return $data;
    }

    $lines = explode("\n", $content);

    if ( count($lines) == 0 ) {
        return $data;
    }

    // added href handling so that HTML anchor-links can be handled
    $regex = '/(?:href="([^\s"]+))|((?:http|https|ftp|ftps)\:\/\/[a-zA-Z0-9\-\.]+\.[a-zA-Z]{2,4}(?:\/\S*)?)/';

    $match = preg_match($regex, $lines[0], $matches);

    if ( $match ) {
        $url = $matches[0];
        $url = preg_replace('/&?utm_(.*?)\=[^&]+/im', '', $url);

        if ( !isset($post) || !isset($post['ID']) || $post['ID'] == 0 ) {
            return $data;
        }

        $result = $this->common_save($post['ID'], \LinkedList\Meta::SOURCE_URL, $url);

        // prevent save fields from overwriting a blank on top of just added value
        add_filter('linked_list_save_fields', function($bool){
            return false;
        });

        set_post_format($post['ID'], 'link');

        unset($lines[0]);
        $data['post_content'] = join("\n", $lines);
        return $data;
    }

    return $data;

}

What has changed: the arguments, now the data and some post metadata like the ID, both are available here cleanly. The return values have been swapped from $content to $data and when the first line is indeed altered, the result is saved back into the $data['post_content'] field and the entire array is returned.

While this works, any other suggestions are absolutely welcome.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.