diff --git a/classes/privacy/provider.php b/classes/privacy/provider.php index 2dbe528..a0b7198 100644 --- a/classes/privacy/provider.php +++ b/classes/privacy/provider.php @@ -27,7 +27,7 @@ defined('MOODLE_INTERNAL') || die(); /** - * The mod_modname module does not store any data. + * The filter_oembed module does not store any data. * */ class provider implements \core_privacy\local\metadata\null_provider { diff --git a/classes/provider/provider.php b/classes/provider/provider.php index f9d089b..9778941 100644 --- a/classes/provider/provider.php +++ b/classes/provider/provider.php @@ -181,9 +181,39 @@ public function get_oembed_request($text) { * @param string $url The consumer request URL. * @return array JSON decoded array. */ - public function oembed_response($url) { - $ret = download_file_content($url, null, null, true, 300, 20, false, null, false); - return json_decode($ret->results, true); + public function oembed_response($url, $retryno = 0) { + static $cache; + + if (!isset($cache)) { + $cache = \cache::make('filter_oembed', 'embeddata'); + } + + if ($ret = $cache->get(md5($url))) { + return json_decode($ret, true); + } + + $curl = new \curl(); + $ret = $curl->get($url); + + // Check if curl call fails. + if ($curl->errno == CURLE_OK) { + $cache->set(md5($url), $ret); + $result = json_decode($ret, true); + return $result; + } + + $retrylimit = get_config('filter_oembed', 'retrylimit'); + // Check if error is due to network connection. + if (!in_array($curl->errno, [6, 7, 28])) { + return null; + } + // Try curl call up to $retrylimit times. + usleep(50000); + $retryno = (!is_int($retryno)) ? 0 : $retryno + 1; + if ($retryno >= $retrylimit) { + return null; + } + return $this->oembed_response($url, $retryno); } /** @@ -224,6 +254,7 @@ protected function endpoints_regex(endpoint $endpoint) { $find = ['.', '*']; $replace = ['\.', '.*?']; $url = str_replace($find, $replace, $url); + $url = str_replace('.*??', '.*?\?', $url); $regexarr[] = '(' . $url . ')'; } diff --git a/filter.php b/filter.php index ac150fa..71fc886 100644 --- a/filter.php +++ b/filter.php @@ -68,7 +68,7 @@ public function filter($text, array $options = array()) { return $text; } - $filtered = $text; // We need to return the original value if regex fails! + $filtered = $this->embed_extra_mappings($text); // We need to return the original value if regex fails! if ($targettag == 'divtag') { $search = '/\]*data-oembed-href="(.*?)"(.*?)>(.*?)\<\/div\>/'; } else { // Using 'atag'. @@ -84,6 +84,35 @@ public function filter($text, array $options = array()) { } } + private function embed_extra_mappings($html) { + $extra = get_config('filter_oembed', 'extra_mappings'); + if (empty($extra)) { + return $html; + } + + $mappings = explode("\n", trim($extra)); + foreach ($mappings as $mapping) { + $mapping = trim($mapping); + $params = explode('=>', $mapping); + if (count($params) != 2) { + if ($params != '') { // Ignore empty lines. + debugging('Invalid extra mapping: '.$mapping); + } + continue; + } + + $html = $this->embed_extra_mapping($html, trim($params[0]), trim($params[1])); + } + + return $html; + } + + private function embed_extra_mapping($html, $url, $endpoint) { + $search = '#]*href="('.$url.')"(.*?)>(.*?)#is'; // URL to Link filter will create tags. + $html = preg_replace_callback($search, 'self::find_oembeds_callback', $html); + return $html; + } + /** * Callback function to be used by the main filter * diff --git a/lang/en/filter_oembed.php b/lang/en/filter_oembed.php index acc21a0..cc5d7a6 100644 --- a/lang/en/filter_oembed.php +++ b/lang/en/filter_oembed.php @@ -63,4 +63,9 @@ $string['targettag'] = 'Target tag'; $string['targettag_desc'] = 'What tag type should be filtered - anchors or divs with the oembed class.'; $string['updateproviders'] = 'Update Oembed provider information.'; +$string['extramappings'] = 'Extra Mappings'; +$string['extramappingsdescription'] = 'Format: REGEX => ENDPOINT
Where REGEX is what to replace and ENDPOINT is where to fetch the JSON parameters for the embed.'; $string['privacy:metadata'] = 'Oembed filter does not store any personal data.'; +$string['once'] = 'Once'; +$string['retrylimit'] = 'Limit to retry getting filtered content'; +$string['times'] = '{$a} times'; \ No newline at end of file diff --git a/settings.php b/settings.php index c58a481..412e4b4 100644 --- a/settings.php +++ b/settings.php @@ -31,26 +31,42 @@ use filter_oembed\service\oembed; -$ADMIN->add('filtersettings', new admin_category('filteroembedfolder', get_string('filtername', 'filter_oembed'))); -$settings = new admin_settingpage($section, get_string('settings')); +$ADMIN->add('filtersettings', new admin_category('filteroembedfolder', new lang_string('filtername', 'filter_oembed'))); +$settings = new admin_settingpage($section, new lang_string('settings')); if ($ADMIN->fulltree) { $targettags = [ - 'a' => get_string('atag', 'filter_oembed'), - 'div' => get_string('divtag', 'filter_oembed') + 'a' => new lang_string('atag', 'filter_oembed'), + 'div' => new lang_string('divtag', 'filter_oembed') ]; $config = get_config('filter_oembed'); + $item = new admin_setting_configtextarea( + 'filter_oembed/extra_mappings', + get_string('extramappings', 'filter_oembed'), + get_string('extramappingsdescription', 'filter_oembed'), + '', + PARAM_RAW + ); + $settings->add($item); + $item = new admin_setting_configselect( 'filter_oembed/targettag', - get_string('targettag', 'filter_oembed'), - get_string('targettag_desc', 'filter_oembed'), + new lang_string('targettag', 'filter_oembed'), + new lang_string('targettag_desc', 'filter_oembed'), 'atag', ['atag' => 'atag', 'divtag' => 'divtag'] ); $settings->add($item); + $retrylist = array('0' => new lang_string('none'), '1' => new lang_string('once', 'filter_oembed'), + '2' => new lang_string('times', 'filter_oembed', '2'), + '3' => new lang_string('times', 'filter_oembed', '3')); + $item = new admin_setting_configselect('filter_oembed/retrylimit', + new lang_string('retrylimit', 'filter_oembed'), '', '1', $retrylist); + $settings->add($item); + $item = new admin_setting_configcheckbox('filter_oembed/lazyload', new lang_string('lazyload', 'filter_oembed'), '', 1); $settings->add($item); } @@ -58,6 +74,6 @@ $ADMIN->add('filteroembedfolder', $settings); $ADMIN->add('filteroembedfolder', new admin_externalpage('filter_oembed_providers', - get_string('manageproviders', 'filter_oembed'), new moodle_url('/filter/oembed/manageproviders.php'))); + new lang_string('manageproviders', 'filter_oembed'), new moodle_url('/filter/oembed/manageproviders.php'))); $settings = null; \ No newline at end of file