Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Wordpress: Automatically change specific URLs in posts

I have found a solution to change links in my wordpress theme, but not the links in the content. How is it possible to get the URL in the content, so I can also changed them?

I need to use the content filter. But how is it possible to change URLs like apple.com/test/ apple.com/test-123/, apple.com, microsoft.com, microsoft.com/test/. The function should also change correctly every matched URL in the content.

add_filter('the_content ', 'function_name');

The answer of a similiar question unfortunately doesn't work.

This is my working solution to change links, but not the links in the content.

add_filter('rh_post_offer_url_filter', 'link_change_custom');
function link_change_custom($offer_post_url){

$shops= array(
        array('shop'=>'apple.com','id'=>'1234'),
        array('shop'=>'microsoft.com','id'=>'5678'),
        array('shop'=>'dell.com','id'=>'9876'), 
    );
    foreach( $shops as $rule ) {
        if (!empty($offer_post_url) && strpos($offer_post_url, $rule['shop']) !== false) {      
            $offer_post_url = 'https://www.network.com/promotion/click/id='.$rule['id'].'-yxz?param0='.rawurlencode($offer_post_url);
}    
    }
$shops2= array(
        array('shop'=>'example.com','id'=>'1234'),
        array('shop'=>'domain2.com','id'=>'5678'),
        array('shop'=>'domain3','id'=>'9876'),  
    );
    foreach( $shops2 as $rule ) {
        if (!empty($offer_post_url) && strpos($offer_post_url, $rule['shop']) !== false) {      
            $offer_post_url = 'https://www.second-network.com/promotion/click/id='.$rule['id'].'-yxz?param0='.rawurlencode($offer_post_url);
}    
    }

        return $offer_post_url; 
}
like image 987
Grischa Avatar asked Mar 24 '20 11:03

Grischa


2 Answers

If I understood you correctly, that is what you need

add_filter( 'the_content', 'replace_links_by_promotions' );
function replace_links_by_promotions( $content ) {
    $shop_ids = array(
        'apple.com'     => '1234',
        'microsoft.com' => '5678',
        'dell.com'      => '9876',
    );

    preg_match_all( '/https?:\/\/(www\.)?([-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6})\b([-a-zA-Z0-9()@:%_\+.~#?&\/=]*)/', $content, $matches, PREG_OFFSET_CAPTURE );

    foreach ( $matches[2] as $index => $match ) {
        if ( ! isset( $shop_ids[ $match[0] ] ) ) {
            continue;
        }

        $offer_post_url = 'https://www.network.com/promotion/click/id=' . $shop_ids[ $match[0] ] . '-yxz?param0=' . rawurlencode( $matches[0][ $index ][0] );
        $content        = substr_replace( $content, $offer_post_url, $matches[0][ $index ][1], strlen( $matches[0][ $index ][0] ) );
    }

    return $content;
}
like image 56
Boris Diádus Avatar answered Sep 28 '22 10:09

Boris Diádus


I think this works. Note that, as written, it will match every "apple.", "dell.", and "microsoft." link in every type of content that uses the content filter - posts, pages, excerpts, many custom post types, etc. - so, if you don't really want that, and you very well may not, then the main replacement function will have to be conditionalized, and the regex function more precisely targeted..., and that can get complicated.

(Also, come to think of it, I'm not sure whether the quotes in the anchor tags that the Regex finds will require special handling. If this doesn't work, we can look at that, too. Or maybe switch to a DOM parser, like maybe I should have started out by doing... )

/** INITIATE FILTER FUNCTION **/
add_filter( 'the_content', 'wpso_change_urls' ) ;

/**
 * PREG CALLBACK FUNCTION
 * Match Matches to id #s
 * and return replacement urls enclosed in quotes (as found)
 */ 
function wpso_found_urls( $matches ) { 

  //someone else probably has a v clever parsimonious way to do this next part
  //but at least this makes what's happening easy to read
  if ( strpos( $matches[0], 'apple' ) ) {

      $id = '1234' ;

  } 

  if ( strpos( $matches[0], 'microsoft' ) ) {

      $id = '5678' ;

  } 

  if ( strpos( $matches[0], 'dell' ) ) {

      $id = '9876' ;

  } 

  $raw_url = trim( $matches[0], '"' ) ;

  return '"https://www.network.com/promotion/click/id='. $id .'-yxz?param0='.rawurlencode( $raw_url) . '"' ; 

}

/** ENDURING A DREADFUL FATE USING REGEX TO PARSE HTML **/
function wpso_change_urls( $content ) { 

    $find_urls = array( 
        '/"+(http|https)(\:\/\/\S*apple.\S*")/',
        '/"+(http|https)(\:\/\/\S*microsoft.\S*")/',
        '/"+(http|https)(\:\/\/\S*dell.\S*")/',
    );

    return preg_replace_callback( $find_urls, 'wpso_found_urls', $content ) ; 

}

Returning (note: example prior to trimming quotes from the "raw URL" before encoded):

Converted Links

...from original (post editor) content like this:

enter image description here

like image 23
CK MacLeod Avatar answered Sep 28 '22 08:09

CK MacLeod