0

I'm sorry for my english. I discover a strange behavior in WP get_posts when i try to detect from a post an attachment (in my case a pdf file) inserted from the library. This is my code:

$my_query_referenze = new WP_Query( array( 'category_name' => 'referenze', 'paged' => get_query_var('paged') ) );
                while ( $my_query_referenze->have_posts() ) : $my_query_referenze->the_post();
                    $content_referenze = apply_filters('the_content', get_the_content());
                    $idpost = $my_query_referenze->post->ID ;
                    $args_referenze = array(
                        'post_type' => 'attachment',
                        'post_parent' => $idpost,
                        'numberposts' => 1,
                        ); 
                    $attachments_referenze = get_posts($args_referenze);
                    if ( $attachments_referenze ) {
                        foreach ( $attachments_referenze as $attachment_referenze ) {
                            $indirizzoallegato_referenze= wp_get_attachment_url( $attachment_referenze->ID , false );
                        }
                    }

If i upload a file and i attach it this code works properly. If i try to attach a file from the media library it doesn't work.

I found a discussion in WP official forum where the people say that there isn't a solution for this case but is it possible?

Isn't there any way to catch the images in both the situation?

1 Answer 1

1

When you upload a media from a post, the post_parent attribute is setted to the post ID you are uploading from. Not so when you simple insert a post from the library: in that case if the media was already attached to a post, its post_parent is already setted, and once a media can have only one parent, you can't get the media using get_posts.

However, there are a lot of ways you can do the trick. If your aim is simply output something using the url of the media, probably best choice is a shortcode.

If you need the url to do something, you can use a regex to extract the pdf urls from the post content.

If you are using WP 3.7+, there is a function wp_extract_urls that help you a lot to perform that task.

Here I'm posting a general function to extract urls form a post content and collect them by their extension:

function post_media_urls( $target = '' ) {
  if ( empty($target) )  {
    $target = get_the_content();
  } elseif ( is_numeric($target) ) {
    $post = get_post($target);
    $target = empty($post) ? FALSE : $post->post_content;
  }
  if ( empty($target) ) return false;
  // apply filters to support shortcodes
  $target = apply_filters('the_content', $target);
  // extract urls
  $urls = wp_extract_urls( $content );
  $out = array();
  if ( ! empty($urls) ) {
    // parse only several media extensions, but allow filtering 
    $exts = apply_filters( 'post_media_urls_exts', array('jpg','gif','png','pdf') );
    foreach( $urls as $url ) {
      $ext = strtolower( pathinfo( basename($url) , PATHINFO_EXTENSION ) );
      if ( $ext === 'jpeg' ) $ext = 'jpg';
      if ( ! empty($ext) && in_array( $ext, $exts) ) {
        if ( ! isset($out[$ext]) ) $out[$ext] = array();
        $out[$ext][] = $url;
      }
    }
  }
  return $out;
}

This function can be used in 3 ways. First is passing a post id:

$urls = post_media_urls(10);

Second is pass a post content (any string, indeed):

$urls = post_media_urls($post->post_content);

Third is using it inside a loop, without any argument, will be used the current post content:

$urls = post_media_urls();

In all 3 cases, what you get is an associative multidimensional array of urls where first level keys are file extensions (lowercased), something like:

Array(
  [pdf] => Array(
     [0] => 'http://example.com/wp-content/2014/01/sample.pdf',
     [1] => 'http://example.com/wp-content/2014/01/sample2.pdf'
  ),
  [jpg] => Array(
     [0] => 'http://example.com/wp-content/2014/01/sample.jpeg',
     [1] => 'http://example.com/wp-content/2014/01/sample2.jpg',
  ),
  [gif] => Array(
     [0] => 'http://example.com/wp-content/2014/01/sample.gif',
  )
)

In your example, the function should be used like this:

$args = array( 'category_name' => 'referenze', 'paged' => get_query_var('paged') );
$my_query_referenze = new WP_Query( $args );
while ( $my_query_referenze->have_posts() ) : $my_query_referenze->the_post();
  $content_referenze = apply_filters('the_content', get_the_content() );
  $attachments_referenze = post_media_urls();
  // to get only pdf
  if ( ! empty($attachments_referenze) && isset($attachments_referenze['pdf']) ) {
    foreach ( $attachments_referenze['pdf'] as $pdfurl ) {
      $indirizzoallegato_referenze = $pdfurl
    }
  }
endwhile;

Of course this function can be used only if the media urls you want to retrive are inserted inside the post content.

An additional note. The function do not parse all the urls, but only the urls that end with a set of specific file extensions, in this way any web link (e.g. to other site pages) are skipped. I've used a very restricted set of extensions, but I've also inserted a filter 'post_media_urls_exts' to allow changing the allowed extensions.

1
  • Thanks, you are really great!!!! Now i study your solution and i try to implement it in my code and i let you know. Thanks a lot for the detailed explanation. Jan 4, 2014 at 10:16

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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