View source
<?php
namespace Drupal\soembed\Plugin\Filter;
use Drupal\filter\FilterProcessResult;
use Drupal\filter\Plugin\FilterBase;
use Drupal\Core\Form\FormStateInterface;
class SoEmbedFilter extends FilterBase {
public function process($text, $langcode) {
$lines = explode("\n", $text);
if (!empty($this->settings['soembed_replace_inline'])) {
$lines = preg_replace_callback('#()(https?://[^\\s<]+)#', [
$this,
'embed',
], $lines);
}
else {
$lines = preg_replace_callback('#^(<p>)?(https?://\\S+?)(</p>)?$#', [
$this,
'embed',
], $lines);
}
$text = implode("\n", $lines);
return new FilterProcessResult($text);
}
private function embed($match) {
static $providers = [];
if (empty($providers)) {
$providers_string = $this->settings['soembed_providers'];
$providers_line = explode("\n", $providers_string);
foreach ($providers_line as $value) {
$items = explode(" | ", $value);
$key = array_shift($items);
$providers[$key] = $items;
}
}
$url = $match[2];
foreach ($providers as $matchmask => $data) {
list($providerurl, $regex) = $data;
$regex = preg_replace('/\\s+/', '', $regex);
if ($regex == 'false') {
$regex = false;
}
if (!$regex) {
$matchmask = '#' . str_replace('___wildcard___', '(.+)', preg_quote(str_replace('*', '___wildcard___', $matchmask), '#')) . '#i';
}
if (preg_match($matchmask, $url)) {
$provider = $providerurl;
break;
}
}
if (!empty($provider)) {
if ($regex === 'LOCAL') {
$output = $this
->getContents($provider, $url);
}
else {
$client = \Drupal::httpClient();
$response = '';
try {
$request = $client
->get($provider . '?url=' . $url . '&format=json&maxwidth=' . $this->settings['soembed_maxwidth']);
$response = $request
->getBody();
} catch (\Exception $e) {
watchdog_exception('soembed', $e);
}
if (!empty($response)) {
$embed = json_decode($response);
if (!empty($embed->html)) {
$output = $embed->html;
}
elseif ($embed->type == 'photo') {
$output = '<img src="' . $embed->url . '" title="' . $embed->title . '" style="width: 100%" />';
$output = '<a href="' . $url . '">' . $output . '</a>';
}
}
}
}
$output = empty($output) ? $url : $output;
if (count($match) > 3) {
$output = $match[1] . $output . $match[3];
}
return $output;
}
private function getContents($provider, $url) {
$width = $this->settings['soembed_maxwidth'];
switch ($provider) {
case 'google-maps':
$height = (int) ($width / 1.3);
$embed = "<iframe width='{$width}' height='{$height}' frameborder='0' scrolling='no' marginheight='0' marginwidth='0' src='{$url}&output=embed'></iframe><br /><small><a href='{$url}&source=embed' style='color:#0000FF;text-align:left'>View Larger Map</a></small>";
break;
case 'google-docs':
$height = (int) ($width * 1.5);
$embed = "<iframe width='{$width}' height='{$height}' frameborder='0' src='{$url}&widget=true'></iframe>";
break;
default:
$embed = $url;
}
return $embed;
}
public function settingsForm(array $form, FormStateInterface $form_state) {
$form['soembed_providers'] = [
'#type' => 'textarea',
'#title' => $this
->t('Providers'),
'#default_value' => $this->settings['soembed_providers'],
'#description' => $this
->t('A list of oEmbed providers. Add your own by adding a new line and using this pattern: [Url to match] | [oEmbed endpoint] | [Use regex (true or false)]'),
];
$form['soembed_maxwidth'] = [
'#type' => 'textfield',
'#title' => $this
->t('Maximum width of media embed'),
'#default_value' => $this->settings['soembed_maxwidth'],
'#description' => $this
->t('Set the maximum width of an embedded media. The unit is in pixels, but only put a number in the textbox.'),
];
$form['soembed_replace_inline'] = [
'#type' => 'checkbox',
'#title' => $this
->t('Replace in-line URLs'),
'#default_value' => $this->settings['soembed_replace_inline'],
'#description' => $this
->t('If this option is checked, the filter will recognize URLs even when they are not on their own lines.'),
];
return $form;
}
}