HackerOne users: Testing against this community violates our program's Terms of Service and will result in your bounty being denied.

How to Embed a Facebook Video on Vanilla forum

How do I embed a video from Facebook onto a Vanilla forum?

Comments

  • @R_Jno replies here also

  • Adds iframe code to database, but not displaying data.

  • <iframe src="https://www.facebook.com/plugins/video.php?href=https%3A%2F%2Fwww.facebook.com%2Fsandvik%2Fvideos%2F1055493134654052%2F&amp;show_text=0&amp;width=560" width="560" height="315" style="border:none;overflow:hidden" scrolling="no" frameborder="0" allowtransparency="true" allowfullscreen="true"></iframe>

  • R_JR_J Ex-Fanboy Munich Admin

    There is a method in class.format.php which handles embedding videos:


       private static function embedReplacement($url) {
           $embeds = [
               'YouTube' => [
                   'regex' => ['/https?:\/\/(?:(?:www.)|(?:m.))?(?:(?:youtube.com)|(?:youtu.be))\/(?:(?:playlist?)|(?:(?:watch\?v=)?(?P<videoId>[\w-]{11})))(?:\?|\&)?(?:list=(?P<listId>[\w-]*))?(?:t=(?:(?P<minutes>\d*)m)?(?P<seconds>\d*)s)?(?:#t=(?P<start>\d*))?/i']
               ],
               'Twitter' => [
                   'regex' => ['/https?:\/\/(?:www\.)?twitter\.com\/(?:#!\/)?(?:[^\/]+)\/status(?:es)?\/([\d]+)/i']
               ],
               'Vimeo' => [
                   'regex' => ['/https?:\/\/(?:www\.)?vimeo\.com\/(?:channels\/[a-z0-9]+\/)?(\d+)/i']
               ],
               'Vine' => [
                   'regex' => ['/https?:\/\/(?:www\.)?vine\.co\/(?:v\/)?([\w]+)/i']
               ],
               'Instagram' => [
                   'regex' => ['/https?:\/\/(?:www\.)?instagr(?:\.am|am\.com)\/p\/([\w-]+)/i']
               ],
               'Pinterest' => [
                   'regex' => [
                       '/https?:\/\/(?:www\.)?pinterest\.com\/pin\/([\d]+)/i',
                       '/https?:\/\/(?:www\.)?pinterest\.ca\/pin\/([\d]+)/i'
                   ]
               ],
               'Getty' => [
                   'regex' => ['/https?:\/\/embed.gettyimages\.com\/([\w=?&;+-_]*)\/([\d]*)\/([\d]*)/i']
               ],
               'Twitch' => [
                   'regex' => ['/https?:\/\/(?:www\.)?twitch\.tv\/([\w]+)$/i']
               ],
               'TwitchRecorded' => [
                   'regex' => ['/https?:\/\/(?:www\.)?twitch\.tv\/videos\/(\w+)$/i']
               ],
               'Soundcloud' => [
                   'regex' => ['/https?:(?:www\.)?\/\/soundcloud\.com\/([\w=?&;+-_]*)\/([\w=?&;+-_]*)/i']
               ],
               'Gifv' => [
                   'regex' => ['/https?:\/\/i\.imgur\.com\/([a-z0-9]+)\.gifv/i'],
               ],
               'Wistia' => [
                   'regex' => [
                       '/https?:\/\/(?:[A-za-z0-9\-]+\.)?(?:wistia\.com|wi\.st)\/.*?\?wvideo=(?<videoID>([A-za-z0-9]+))(\?wtime=(?<time>((\d)+m)?((\d)+s)?))?/i',
                       '/https?:\/\/([A-za-z0-9\-]+\.)?(wistia\.com|wi\.st)\/medias\/(?<videoID>[A-za-z0-9]+)(\?wtime=(?<time>((\d)+m)?((\d)+s)?))?/i'
                   ]
               ]
           ];
           ...
    
    

    As you can see, facebook isn't on that list. So there is no setting or something you can do on any other way, I'd say. You will need to write your own custom plugin "FacebookVideoEmbed".

    I hate facebook, so I will not be the one who writes such a plugin. But I must confess I have taken a look how it would have to be done.

    I think you should use the fireFilter that is in the processHtml method and by copying much of the Vanilla code you end up with something like this:


       public function format_filterHtml_handler($in, $dummy = []) {
           $linksCallback = function ($matches) {
               static $inTag = 0;
               static $inAnchor = false;
    
               $inOut = $matches[1];
               $tag = strtolower($matches[2]);
    
               if ($inOut == '<') {
                   $inTag++;
                   if ($tag == 'a') {
                       $inAnchor = true;
                   }
               } elseif ($inOut == '</') {
                   $inTag++;
                   if ($tag == 'a') {
                       $inAnchor = false;
                   }
               } elseif ($matches[3]) {
                   $inTag--;
               }
    
               if (!isset($matches[4]) || $inTag || $inAnchor) {
                   return $matches[0];
               }
    
               // We are not in a tag and what we matched starts with //
               if (preg_match('#^//#', $matches[4])) {
                   return $matches[0];
               }
    
               $url = $matches[4];
               list($width, $height) = Gdn_Format::getEmbedSize();
    
               $urlParts = parse_url($url);
               if ($urlParts['host'] != 'www.facebook.com' && $urlParts['scheme'] != 'https') {
                   return $url;
               }
    
               $queryString = $urlParts['query'] ?? '';
               parse_str($queryString, $query);
               // There's the possibility the query string could be encoded, resulting in parameters that begin with "amp;"
               foreach ($query as $key => $val) {
                   $newKey = stringBeginsWith($key, 'amp;', false, true);
                   if ($newKey !== $key) {
                       $query[$newKey] = $val;
                       unset($query[$key]);
                   }
               }
    // Everything needed is now available in $query or $urlParts['path']. Transmogrify it and return that bloated html
               return 'Facebook ist Käse';
           };
    
           if (unicodeRegexSupport()) {
               $regex = "`(?:(</?)([!a-z]+))|(/?\s*>)|((?:(?:https?|ftp):)?//[@\p{L}\p{N}\x21\x23-\x27\x2a-\x2e\x3a\x3b\/\x3f-\x7a\x7e\x3d]+)`iu";
           } else {
               $regex = "`(?:(</?)([!a-z]+))|(/?\s*>)|((?:(?:https?|ftp):)?//[@a-z0-9\x21\x23-\x27\x2a-\x2e\x3a\x3b\/\x3f-\x7a\x7e\x3d]+)`i";
           }
    
           $out = Gdn_Format::replaceButProtectCodeBlocks(
               $regex,
               $linksCallback,
               $in,
               true
           );
    
           return $out;
       }
    


  • I am not that much expertise into this, I have found the function in class.format.php , but i m not able to figure out , how to proceed to fix this issue.

    kindly help me out on this.

  • charrondevcharrondev Developer Lead (PHP, JS) Montreal Vanilla Staff

    @R_J that embed replacement code is what we have for Advanced Editor posts. Rich editor has a different pipeline and support for more embeds.

    This issue was just moved into our planning pipeline, and I think the extendable new Rich embed system (with documentation and examples) will be ready for the 3.1 release.

    Another ongoing goal (definitely this year, although the exact month will depend on how successful our hiring is right now. We're hiring a bunch of developers at the moment) is the refactoring & unification of our content rendering pipelines. That would bring some additional configuration options and administration pages.

  • ShadowdareShadowdare r_j MVP
    edited May 2019

    Like @R_J, mentioned, you'd have to create your own plugin to add support for Facebook embeds by taking the formatted output of discussion/comment bodies and replacing links to Facebook videos with its embed code.

    I've actually put together a prototype addon to add support for various video site embeds, but haven't done much with it. I added a base_links_handler and used Gdn_Format::replaceButProtectCodeBlocks(). It was mainly just an experiment of Garden Container's DI where developers can just drop in class files in a folder to add more sites, instead of tightly coupling the embed logic for each site in the addon's main code. This was probably over-engineered, though. 😂

    Rather, would the new embed system (EmbedManager) only be for the Rich Editor, or an extension to formatting in general for any format that would provide the ability to add more sites, @charrondev?

    Add Pages to Vanilla with the Basic Pages app

  • charrondevcharrondev Developer Lead (PHP, JS) Montreal Vanilla Staff
    edited May 2019

    @Shadowdare

    Rather, would the new embed system (EmbedManager) only be for the Rich Editor, or an extension to formatting in general for any format that would provide the ability to add more sites?

    In the next couple of week I'll be finalizing the public API. The actual unification of the text formatting pipelines will be going into planning this week, and likely will be implemented in the next couple of months.

    The plan is as follows:

    1. Cover Gdn_Format with tests.
    2. Finalize the new embed interface (currently only in Rich Editor).
    3. Break apart Gdn_Format and unify our backend rendering into a single pipeline. This means Rich Editor will get the pieces it's missing (trusted domains, and a couple other addons that do HTML processing), and the existing HTML based pipelines will get the new embed system.

    I'm thinking we'll enable the new system by default with a feature flag, and put out a release note of how to keep using the old embed system if you have some integration there. Step 1 is completed, Step 2 is in progress, and Step 3 is in planning.

Sign In or Register to comment.