$conf, $runtime; function_exists('chdir') AND chdir(APP_PATH); $r = 'mysql' == $conf['cache']['type'] ? website_set('runtime', $runtime) : cache_set('runtime', $runtime); } function runtime_truncate() { global $conf; 'mysql' == $conf['cache']['type'] ? website_set('runtime', '') : cache_delete('runtime'); } register_shutdown_function('runtime_save'); ?>Adding current user's ID to the end of PDF hyperlinks in post content|Programmer puzzle solving
最新消息:Welcome to the puzzle paradise for programmers! Here, a well-designed puzzle awaits you. From code logic puzzles to algorithmic challenges, each level is closely centered on the programmer's expertise and skills. Whether you're a novice programmer or an experienced tech guru, you'll find your own challenges on this site. In the process of solving puzzles, you can not only exercise your thinking skills, but also deepen your understanding and application of programming knowledge. Come to start this puzzle journey full of wisdom and challenges, with many programmers to compete with each other and show your programming wisdom! Translated with DeepL.com (free version)

Adding current user's ID to the end of PDF hyperlinks in post content

matteradmin9PV0评论

How can I add extra parameters after a hyperlink, for tracking purposes?

For example, let's say I inserted media into a post - http://mysite/wp-content/uploads/2018/12/My_PDF_File.pdf. How can I make a function to automatically insert the user id like this http://mysite/wp-content/uploads/2018/12/My_PDF_File.pdf?user=54

There will be multiple pdf links on the same page, I'm at a bit of a loss on how to do this.

How can I add extra parameters after a hyperlink, for tracking purposes?

For example, let's say I inserted media into a post - http://mysite/wp-content/uploads/2018/12/My_PDF_File.pdf. How can I make a function to automatically insert the user id like this http://mysite/wp-content/uploads/2018/12/My_PDF_File.pdf?user=54

There will be multiple pdf links on the same page, I'm at a bit of a loss on how to do this.

Share Improve this question edited Dec 14, 2018 at 23:24 Dave Romsey 17.9k11 gold badges56 silver badges70 bronze badges asked Dec 14, 2018 at 17:44 Drastec DevelopmentDrastec Development 134 bronze badges 4
  • What are the specific conditions in which you'd like to add the user parameter and value? Just pdf uploads, uploads to a specific post, uploads by a specific user role, or any combination of these etc. – Dave Romsey Commented Dec 14, 2018 at 18:17
  • 1 I'm looking to track all .pdf files when they are clicked. Specifically to tell how many .pdf files a specific user is clicking. I bulk add about 30.pdf files a day, these get replaced everyday with new ones on the same page every day. – Drastec Development Commented Dec 14, 2018 at 18:35
  • How are you tracking the clicks? – czerspalace Commented Dec 14, 2018 at 19:41
  • I'm tracking with Google Analytics and MonsterInsights with 'Event' of 'download' this tells me the URL of the pdf file and how many times it was clicked but doesn't tell me who it is. So that's why I want to attach the userID to the clicked URL. – Drastec Development Commented Dec 14, 2018 at 19:46
Add a comment  | 

1 Answer 1

Reset to default 1

Here's a solution that I came up with that will add the user query argument and the current user's ID to PDF links, e.g.:

http://mysite/wp-content/uploads/2018/12/My_PDF_File.pdf?user=54

This code works by inspecting the post's content using the the_content filter, then parsing the content using DOMDocument. I've run into various gotchas using DOMDocument and much of this code deals with handling those edge cases. Also note that we'll bail immediately if a user is not logged in, since there's nothing to do in that case.

The real meat and potatoes comes towards the end of wpse_append_current_user_id_to_pdf_links() where links are extracted from the content, checked to ensure they are PDFs, then add_query_arg() is used to append the user query argument and value.

/**
 * Filters post content and appends user query argument and user ID value
 * to PDF links.
 * 
 * @param string $content post content 
 */
add_filter( 'the_content', 'wpse_append_current_user_id_to_pdf_links' );
function wpse_append_current_user_id_to_pdf_links( $content ) {
    // Bail if there is no content to work with.
    if ( ! $content ) {
        return $content;
    }

    // Get the current user.
    $current_user = wp_get_current_user();

    // Bail if there is nobody logged in.
    if ( ! $current_user->exists() ) {
        return $content;
    }

    // Create an instance of DOMDocument.
    $dom = new \DOMDocument();

    // Supress errors due to malformed HTML.
    // See http://stackoverflow/a/17559716/3059883
    $libxml_previous_state = libxml_use_internal_errors( true );

    // Populate $dom with $content, making sure to handle UTF-8, otherwise
    // problems will occur with UTF-8 characters.
    // Also, make sure that the doctype and HTML tags are not added to our HTML fragment. http://stackoverflow/a/22490902/3059883
    $dom->loadHTML( mb_convert_encoding( $content, 'HTML-ENTITIES', 'UTF-8' ), LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD );

    // Restore previous state of libxml_use_internal_errors() now that we're done.
    libxml_use_internal_errors( $libxml_previous_state );

    // Create an instance of DOMXpath.
    $xpath = new \DOMXpath( $dom );

    // Get all links.
    $links = $xpath->query( "//a" );

    // Process the links.
    foreach ( $links as $link ) {
        $link_href = $link->getAttribute( 'href' );

        // Get the extension for this link.
        $extension = pathinfo( $link_href, PATHINFO_EXTENSION );

        // Only process PDF links.
        if ( 'pdf' === strtolower( $extension ) ) {
            $link->setAttribute( 'href', add_query_arg( 'user', $current_user->ID, $link_href ) );
        }   
    }

    // Save and return updated HTML.
    $new_content = $dom->saveHTML();
    return $new_content;
}
Post a comment

comment list (0)

  1. No comments so far