Joomla 3 内容插件:对于每个 preg_replace $row->full text duplicates first string

Joomla 3 content plugn: Foreach preg_replace $row->fulltext duplicates first string

我正在为 Joomla 3 设置一个新的内容插件,它应该用 html 内容替换插件标签。一切正常,直到我在 $row->fulltext 中 preg_replace 插件标签。

这是插件代码

public function onContentPrepare($context, &$row, &$params, $page = 0) {
$pattern = '#\{uni\}(.*){\/uni\}#sU';
    preg_match_all($pattern, $row->fulltext, $matches,  PREG_PATTERN_ORDER);

    foreach($matches[1] as $k=>$uni){

        preg_match('/\{uni-title\}(.*)[\{]/Ui', $uni, $unititle);
        preg_match('/\{uni-text\}(.*)/si', $uni, $unitext);

        $titleID = str_replace(' ', '_', trim($unititle[1]));

        $newString = '<span id="'.$titleID.'">'.$unititle[1].'</span><div class="university-info-holder"><div class="university-info"><i class="icon icon-close"></i>'.$unitext[1].'</div></div>';

        $row->fulltext = preg_replace($pattern,$newString,$row->fulltext);

    }
}

任何想法,为什么它重复第一个找到的匹配项,与 foreach 一样多?

顺便提一下,如果我这样做:

echo $unititle[1];

在 foreach 内部,项目不会重复,而是按应有的方式呈现。

原始代码存在一些问题。

  1. 应该使用$row->text而不是$row->fulltext。这是因为在呈现文章时,Joomla 合并了 introtextfulltext 字段。

  2. 替换时使用$pattern进行匹配是错误的。那是因为 $pattern 匹配所有项目。而是使用 $match[0][$k] 进行替换。使用 str_replace 而不是 preg_replace 因为现在您匹配的是确切的字符串并且不需要执行正则表达式。 这是整个事情的代码。

    class PlgContentLivefilter 扩展 JPlugin{ public 函数 onContentPrepare($context, &$row, &$params, $page = 0) { return $renderUniInfo = $this->renderUniInfo($row, $params, $page = 0);
    }

    私有函数 renderUniInfo(&$row, &$params, $page = 0) {

        $pattern = '#\{uni\}(.*){\/uni\}#sU';
    
        preg_match_all($pattern, $row->text, $matches);
    
        foreach($matches[0] as $k=>$uni){
    
    
    
                preg_match('/\{uni-title\}(.*)[\{]/Ui', $uni, $unititle);
                preg_match('/\{uni-text\}(.*)/si', $uni, $unitext);
    
                print_r($unititle[1]);
    
                $title = $unititle[1];
                $text = $unitext[1];
    
                if (preg_match('#(?:http://)?(?:https://)?(?:www\.)?(?:youtube\.com/(?:v/|embed/|watch\?v=)|youtu\.be/)([\w-]+)?#i', $unitext[1], $match)) {
                    $video_id = $match[1];
                    $video_string = '<div class="videoWrapper"><iframe src="http://youtube.com/embed/'.$video_id.'?rel=0"></iframe></div>';
                    $unitext[1] = preg_replace('#(?:http://)?(?:https://)?(?:www\.)?(?:youtube\.com/(?:v/|embed/|watch\?v=)|youtu\.be/)([\w-]+)?#i', $video_string, $unitext[1]);
                    $text = $unitext[1];
                }
    
                $titleID = str_replace(' ', '_', trim($title));
    
                $newString = '<span id="'.$titleID.'">'.$title.'</span><div class="university-info-holder"><div class="university-info"><i class="icon icon-close"></i>'.$text.'</div></div>';
    
    
                $row->text = str_replace($matches[0][$k],$newString,$row->text);
    
    
        }
    
    }
    

    }