preg_match справка по взаимоисключающему условному сопоставлению - PullRequest
1 голос
/ 11 февраля 2011

У меня есть два варианта этого плагина.

(1) nofollow все внешние ссылки в контенте

и / или

(2) нет последующих ссылок на эту целевую папку (введите абсолютный URL-адрес целевой папки)

В варианте 2 ссылки могут быть внутренними ИЛИ внешними.

Обе опции могут быть установлены, ни одна опция не может быть установлена, или может быть установлена ​​одна опция.

if(get_option('my_nofollow') || get_option('my_nofollow_folder')){add_filter('wp_insert_post_data', 'save_my_nofollow' );}

Так что я устанавливаю фильтр, когда любой из этих параметров установлен, для функции ниже.У меня вопрос, как мне изменить функцию, чтобы, если (2) установлен, но не (1), я только добавлял nofollow к ссылкам, соответствующим URL-адресу целевой папки?

if(get_option('rseo_nofollow') 
    || get_option('rseo_nofollow_folder')){
    add_filter('wp_insert_post_data', 'save_rseo_nofollow' );
    }

function save_rseo_nofollow($content) {
    $folder =  get_option('rseo_nofollow_folder');
    $externalNoFollow = get_option('rseo_nofollow_external');
    $folderNoFollow = get_option('rseo_nofollow_folder');
    $extRegex = '~'.preg_quote(get_bloginfo('url'), '~') . '~i';
    $intRegex = '~'.preg_quote($folder, '~') . '~i';

    $dom = new DomDocument();
    libxml_use_internal_errors(true);
    $dom->loadXml('<root>' . $content['post_content'] . '</root>');

    $links = $dom->getElementsByTagName('a');
    foreach ($links as $link) {
        $href = $link->getAttribute('href');
        if ($href && $externalNoFollow && !preg_match($extRegex, $href)) {
            $link->setAttribute('rel', 'nofollow');
        } elseif ($href && $folderNoFollow && preg_match($intRegex, $href)) {
            $link->setAttribute('rel', 'nofollow');
        }
    }
//  print $dom->saveXml();die;
    //Since we want to strip the root element, we must do so:
    $newContent = '';
    $root = $dom->getElementsByTagName('root')->item(0);
    foreach ($root->childNodes as $child) {
        $newContent .= $dom->saveXml($child);
    }
    $content['post_content'] = $newContent;
return $content;
}

Вход

This is the <a href="http://cnn.com">test</a>. This is the test.

Выход

This is the <a rel="nofollow" href="&quot;http://cnn.com&quot;">test</a>. This is the test.

1 Ответ

1 голос
/ 11 февраля 2011

Не анализируйте HTML с помощью регулярных выражений.Это не очень хорошая идея ... Вместо этого используйте функции Dom.Обратите внимание, что вам может понадобиться обернуть содержимое во внешний корневой тег (для чего я добавил <root> здесь) (.

$externalNoFollow = get_option('my_nofollow_external');
$folderNoFollow = get_option('my_nofollow_folder');
$extRegex = '~'.preg_quote(get_bloginfo('url'), '~') . '~i';
$intRegex = '~'.preg_quote($folder, '~') . '~i';

$dom = new DomDocument();
libxml_use_internal_errors(true);
if (!$dom->loadHtml('<html><body>' . $content['post_content'] . '</body></html>')) {
    /** Error out, since the loading failed. 
        Make sure `$content['post_content']` is valid html
    **/
    die('Invalid HTML detected');
}

$links = $dom->getElementsByTagName('a');
foreach ($links as $link) {
    $href = $link->getAttribute('href');
    if ($href && $externalNoFollow && !preg_match($extRegex, $href)) {
        $link->setAttribute('rel', 'nofollow');
    } elseif ($href && $folderNoFollow && preg_match($intRegex, $href)) {
        $link->setAttribute('rel', 'nofollow');
    }
}
//Since we want to strip the root element, we must do so:
$newContent = '';
$root = $dom->getElementsByTagName('body')->item(0);
foreach ($root->childNodes as $child) {
    $newContent .= $dom->saveXml($child);
}

$content['post_content'] = $newContent;
return $content;

Обратите внимание, вы должны добавить фактическую обработку ошибок в случае некорректного HTML ...

...