0

This is my function:

function bbc2html($content) {
    $search = array (
      '/(\[b\])(.*?)(\[\/b\])/',
      '/(\[u\])(.*?)(\[\/u\])/',
      '/(\[i\])(.*?)(\[\/i\])/',
      '/(\[youtube\])(.*?)(\[\/youtube\])/'
    );
  
    $replace = array (
      '<b>$2</b>',
      '<u>$2</u>',
      '<i>$2</i>',
      '<div class="video_wrapper card border-0 shadow text-center m-2" style="width: 25rem;">
       <div class="video_trigger card-body" data-source="'.getYoutubeVideoID('$2').'" data-type="youtube">
          <p class="text-center">As soon as you click on the button you accept that cookies from YouTube to be loaded</p>
          <input type="button" class="btn btn-success" value="OK">
          <a href="$2" type="button" target="_blank" class="btn btn-danger"><i class="fa-brands fa-youtube pe-1"></i>direct link</a>
       </div>
       <div class="video_layer" style="display: none;">
          <iframe src="" border="0" data-scaling="true" data-format="16:9" style="height: 0px;"></iframe>
       </div>
       </div>'
    );
    
    return preg_replace($search, $replace , $content);
  }
function getYoutubeVideoID($link):string{
    $baseUrl = parse_url($link, PHP_URL_HOST); 

    if($baseUrl == "youtu.be"){
        $urlParts = explode('/',$link);
        $id = end($urlParts);
    } elseif (preg_match('/(youtube.com)/i',$baseUrl)) {
        if(preg_match('/(youtube.com\/watch\?v=)/i',$link)){
            $urlParts = explode('?v=',$link);
            $id = end($urlParts);
        } elseif(preg_match('/(youtube.com\/)/i',$link)) {
            $urlParts = explode('/',$link);
            $id = end($urlParts);
        } else {
            return "";
        }
    } else {
        return "";
    }

    return $id;
}

I want to pass the variable ($2, contains the link to the youtube video) to the function (getYoutubeVideoID, returns only the id of the video), but it just pass '$2' instead of the link.

Example: [youtube] https://www.youtube.com/watch?v=LXb3EKWsInQ [/youtube]

This should be replaced with:

<div class="video_wrapper card border-0 shadow text-center m-2" style="width: 25rem;">
       <div class="video_trigger card-body" data-source="LXb3EKWsInQ" data-type="youtube">
          <p class="text-center">As soon as you click on the button you accept that cookies from YouTube to be loaded</p>
          <input type="button" class="btn btn-success" value="OK">
          <a href="https://www.youtube.com/watch?v=LXb3EKWsInQ" type="button" target="_blank" class="btn btn-danger"><i class="fa-brands fa-youtube pe-1"></i>direct link</a>
       </div>
       <div class="video_layer" style="display: none;">
          <iframe src="" border="0" data-scaling="true" data-format="16:9" style="height: 0px;"></iframe>
       </div>
       </div>
4

1 Answer 1

2

The standard preg_replace doesn't allow you to execute a function on the replacement values, you can only pass literals with replacement placeholders.

You can get around this in multiple ways, however preg_replace_callback with that specific case might be the easiest to read. In the following code I also took the liberty of combining your first three shortcodes into a single one that uses a back-reference. I also removed captures that you we're using (for no good reason except to help me debug).

<?php

var_dump(bbc2html('[b]stuff[/b][youtube]abc[/youtube]'));

function getYoutubeVideoID($id)
{
    // Just a demo function
    return '!!'.$id.'!!';
}

function bbc2html($content)
{
    $search = '/\[(b|u|i)]([^\[]*)\[\/\1]/';
    $replace = '<$1>$2</$1>';

    $newContent = preg_replace($search, $replace, $content);

    return preg_replace_callback(
        '/\[youtube](.*?)\[\/youtube]/',
        static function ($matches) {
            return '<div class="video_wrapper card border-0 shadow text-center m-2" style="width: 25rem;">
      <div class="video_trigger card-body" data-source="'.getYoutubeVideoID($matches[1]).'" data-type="youtube">
          <p class="text-center">As soon as you click on the button you accept that cookies from YouTube to be loaded</p>
          <input type="button" class="btn btn-success" value="OK">
          <a href="$2" type="button" target="_blank" class="btn btn-danger"><i class="fa-brands fa-youtube pe-1"></i>direct link</a>
      </div>
      <div class="video_layer" style="display: none;">
          <iframe src="" border="0" data-scaling="true" data-format="16:9" style="height: 0px;"></iframe>
      </div>
      </div>';
        },
        $newContent
    );
}

Demo: https://3v4l.org/0hkQj

Sign up to request clarification or add additional context in comments.

1 Comment

Just as a minor improvement, you could write the alternatives \[(b|u|i)] as a character class \[([bui])]

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.