2011-02-11 47 views
1

我有兩個選擇這個插件。preg_match幫助互斥條件匹配

(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相匹配的鏈接?

function save_my_nofollow($content) { 
$my_folder = get_option('my_nofollow_folder'); 
$matches = array(); 
    preg_match_all('~<a.*>~isU',$content["post_content"],$matches); 
    for ($i = 0; $i <= sizeof($matches[0]); $i++){ 
     if (isset($matches[0][$i]) && (preg_match('~' . $my_folder . '~', $matches[0][$i]) 
       || !preg_match('~'.get_bloginfo('url').'~',$matches[0][$i]))){ 
     $result = trim($matches[0][$i],">"); 
     $result .= ' rel="nofollow">'; 
     $content["post_content"] = str_replace($matches[0][$i], $result, $content["post_content"]); 
     } 
    } 
    return $content; 
} 

更新的代碼與最佳答案:

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

不要用正則表達式解析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的...

+0

@ ircmaxell:哇!現在檢查出來,會回報:) – 2011-02-11 18:48:46