Wordpress: автоматическое изменение URL-адресов в разделе the_content - PullRequest
4 голосов
/ 14 апреля 2020

Решение с здесь не решает нашу проблему. У меня уже есть решение изменить все ссылки в форме поля в нашей теме. Я использую разные массивы для каждой сети, например $example_network_1 $example_network_2 с * foreach для каждой партнерской сети PHP.

Теперь мне нужно решение использовать эти же массивы для содержимого поста WordPress.

Это решение работает для одной сети, но оно вызвало ошибку 404e для видео YouTube. Мы помещаем URL из видео YouTube, и WordPress автоматически генерирует встроенное видео. С помощью следующего кода мы получаем ошибку 404 iframe или что-то вроде этого.

Нам нужно решение для нескольких сетей.

I Я очень благодарен за любую помощь!

    $example_network_1 = array(
            array('shop'=>'shop1.com','id'=>'11111'),   
            array('shop'=>'shop2.co.uk','id'=>'11112'),
        );
    $example_network_2 = array(
            array('shop'=>'shop-x1.com','id'=>'11413'), 
            array('shop'=>'shop-x2.net','id'=>'11212'),
        );

    add_filter( 'the_content', 'wpso_change_urls' ) ;
    function wpso_found_urls( $matches ) { 
    global $example_network_1,$example_network_2;   
        foreach( $example_network_1 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 ) . '"';   
             }  

/*
      foreach( $example_network_2 as $rule ) {
            if (strpos($matches[0], $rule['shop']) !== false) {
                $raw_url = trim( $matches[0], '"' ) ;
                return '"https://www.network-y.com/click/'. $rule['id'].'lorem='.rawurlencode($raw_url ) . '"';     
             }  
*/
        }
    }
    function wpso_change_urls( $content ) {
        global $example_network_1,example_network_2;    
           return preg_replace_callback( '/"+(http|https)(\:\/\/\S*'. $example_network_1 ['shop'] .'\S*")/', 'wpso_found_urls', $content ) ;
    //     return preg_replace_callback( '/"+(http|https)(\:\/\/\S*'. $example_network_2 ['shop'] .'\S*")/', 'wpso_found_urls', $content ) ;
        }

Ответы [ 3 ]

4 голосов
/ 20 апреля 2020

autoembed подключен на the_content с приоритетом 8 на wp-includes/class-wp-embed.php:39

Попробуйте уменьшить приоритет фильтра the_content, чтобы замена URL происходила до встраивания, что-то вроде этого:

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 );

Это не решение для копирования и вставки, но должно помочь вам. Возможно, вам придется настроить код «preg_replace_callback», но вы сказали, что он работает, поэтому я просто оставил его там.

0 голосов
/ 18 апреля 2020

Я написал решение без теста. Ваш код сложно протестировать без вашего сайта, но я думаю, что проблема в регулярных выражениях. Обратный вызов трудно отладить. Моя версия ниже.

Первый шаг, измени свою структуру. Я подозреваю, что домены являются уникальными. Одномерный массив более полезен.

$domains =  array(
            'shop1.com'=>'11111',   
            'shop2.co.uk'=>'11112',
            'shop-x1.com'=>'11413', 
            'shop-x2.net'=>'11212',
        );

Далее:

$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;
}

Пример сценария

0 голосов
/ 15 апреля 2020

Если предотвращение автоматического встраивания wp работает, просто добавьте эту строку в вашу тему functions.php

remove_filter( 'the_content', array( $GLOBALS['wp_embed'], 'autoembed' ), 8 );
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...