Wordpress: Automatically change URLs in the_content section
autoembed
is hooked at the_content
with priority 8 on wp-includes/class-wp-embed.php:39
Try to lower the priority of the the_content
filter so that the URL replacement happens before the embed, something like this:
add_filter( 'the_content', function ( $content ) { /* * Here, we define the replacements for each site in the network. * '1' = main blog * '2' = site 2 in the network, and so on * * To add more sites, just add the key number '3', etc */ $network_replacements = [ '1' => [ [ 'shop' => 'shop1.com', 'id' => '11111' ], [ 'shop' => 'shop2.co.uk', 'id' => '11112' ], ], '2' => [ [ 'shop' => 'shop-x1.com', 'id' => '11413' ], [ 'shop' => 'shop-x2.net', 'id' => '11212' ], ] ]; // Early bail: Current blog ID does not have replacements defined if ( ! array_key_exists( get_current_blog_id(), $network_replacements ) ) { return $content; } $replacements = $network_replacements[ get_current_blog_id() ]; return preg_replace_callback( '/"+(http|https)(\:\/\/\S*' . $replacements['shop'] . '\S*")/', function( $matches ) use ( $replacements ) { foreach ( $replacements as $rule ) { if ( strpos( $matches[0], $rule['shop'] ) !== false ) { $raw_url = trim( $matches[0], '"' ); return '"https://www.network-x.com/click/' . $rule['id'] . 'lorem_lorem=' . rawurlencode( $raw_url ) . '"'; } } }, $content );}, 1, 1 );
This is not a copy and paste solution, but should get you going. You might need to tweak your "preg_replace_callback" code, but you said it was working so I just left it is it was.
I wrote solution without test. Your code is hard to test without your site but I think that problem is with regex. Callback is hard to debugging. My version below.
First step, change your structure. I suspect that domains are unique. One dimensional array is more useful.
$domains = array( 'shop1.com'=>'11111', 'shop2.co.uk'=>'11112', 'shop-x1.com'=>'11413', 'shop-x2.net'=>'11212', );
Next:
$dangerouschars = array( '.'=>'\.',);function wpso_change_urls( $content ) { global $domains,$dangerouschars; foreach($domains as $domain=>$id){ $escapedDomain = str_replace(array_keys($dangerouschars),array_values($dangerouschars), $domain); if (preg_match_all('/=\s*"(\s*https?:\/\/(www\.)?'.$escapedDomain.'[^"]+)\s*"\s+/mi', $content, $matches)){ // $matches[0] - ="https://example.com" // $matches[1] - https://example.com for($i = 0; $i<count($matches[0]); $i++){ $matchedUrl = $matches[1][$i]; $url = rawurlencode($matchedUrl); //is very important to replace with ="..." $content = str_replace($matches[0][$i], "=\"https://www.network-x.com/click/{$id}lorem_lorem={$url}\" ", $content); } } } return $content;}