Question

Sorry about the title I honestly dont know how to explain it properly.

I am making a small shortcode function that needs to replace shortcodes with html output.

The preg_match_all finds everything I need but the preg_replace is replacing the same match over and over again. Here is the demo https://eval.in/139727

I am sure I made a mess in those foreach loops but just cant figure it out.

$text = 'Some text and some [link link="linkhref1" text="Text1"],[link link="linkhref2" text="Text2"]';


function shortcodes($text) {
    $shortcodes = array(
        'link' => array(
            "check" => "[link",
            "type" => "link",
            "match" => "#\[link(.*?)link\=\"(.*?)\"(.*?)text\=\"(.*?)\"#Ui",
            "replace" => "/\[link(.*?)\]/s"
        )
    );
    foreach ($shortcodes as $index => $shortcode) {
        if (strpos($text, $shortcode['check']) !== false) {
            $text = shortcode_replace($shortcode, $text);
        }
    }
    return $text;
}


function shortcode_replace($shortcode, $text) {
    $replacement = '';
    preg_match_all($shortcode['match'], $text, $matches);
    switch ($shortcode['type']) {
        case "link":
            foreach ($matches[4] as $index => $match) {
                $link     = $matches[2][$index];
                $linktext = $matches[4][$index];
                $replacement .= '<a href="' . $link . '">' . $linktext . '</a>';
                $text = preg_replace($shortcode['replace'], $replacement, $text);
            }
    }

    return $text;
}



echo shortcodes($text);

any help is appreciated!

Was it helpful?

Solution

There was a problem in regex i've changed it. Also you don't need preg_replace there.

<?php
$text = 'Some text and some [link link="linkhref1" text="Text1"],[link link="linkhref2" text="Text2"]';


function shortcodes($text) {
    $shortcodes = array(
        'link' => array(
            "check" => "[link",
            "type" => "link",
            "match" => "#\[link(\s+)link\=\"([^\"]+)\"(\s+)text\=\"([^\"]+)\"\]#Ui",
            "replace" => "/\[link(.*?)\]/s"
        )
    );
    foreach ($shortcodes as $index => $shortcode) {
        if (strpos($text, $shortcode['check']) !== false) {
            $text = shortcode_replace($shortcode, $text);
        }
    }
    return $text;
}


function shortcode_replace($shortcode, $text) {
    $replace = '';
    preg_match_all($shortcode['match'], $text, $matches);
    switch ($shortcode['type']) {
        case "link":
            var_dump($matches);
            foreach ($matches[4] as $index => $match) {
                $link     = $matches[2][$index];
                $linktext = $matches[4][$index];
                $replace = '<a href="' . $link . '">' . $linktext . '</a>';
                $text = str_replace($matches[0][$index], $replace, $text);
            }
    }

    return $text;
}



echo shortcodes($text);

OTHER TIPS

Here is a working version :

<?php
$text = 'Some text and some [link link="linkhref1" text="Text1"],[link link="linkhref2" text="Text2"]';


function shortcodes($text) {
    $shortcodes = array(
        'link' => array(
            "check" => "[link",
            "type" => "link",
            "match" => "#\[link(.*?)link\=\"(.*?)\"(.*?)text\=\"(.*?)\"#",
            "replace" => "/\[link(.*?)\]/s"
        )
    );
    foreach ($shortcodes as $index => $shortcode) {
        if (strpos($text, $shortcode['check']) !== false) {
            $text = shortcode_replace($shortcode, $text);
        }
    }
    return $text;
}


function shortcode_replace($shortcode, $text) {
    $replace = '';
    preg_match_all($shortcode['match'], $text, $matches);

    switch ($shortcode['type']) {
        case "link":
            foreach ($matches[4] as $index => $match) {
                $link     = $matches[2][$index];
                $linktext = $matches[4][$index];
                $replace .= '<a href="' . $link . '">' . $linktext . '</a>';
                $whatToReplace = '[link link="'.$link.'" text="'.$linktext.'"]';


                $text = str_replace($whatToReplace, $replace, $text);
            }
    }

    return $text;
}



echo shortcodes($text);

I'm not very good at RegExp, i modified the "match" to match all the links ( with what you got, it didn't )

You need to identify the exact [link ] to replace, and not all all of them. In my opinion, this is the correct way to identify the link, You can also identify it using strpos() ( getting the start and end of the string) or see where the [link starts and the first ] is .

A better option can be to create a regexp with the unique values for it , which can compensate for extra spaces between tags

Hopefully this is of help to you

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top