ElkArte plug-ins

Check-in [797f5ce34e]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:init
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | trunk
Files: files | file ages | folders
SHA3-256: 797f5ce34e3286c0f0f96c49b772e36faafc78d98e7a46fb17b495ca05c46abf
User & Date: Cthulhux 2019-09-11 20:23:21
Context
2019-09-11
20:23
init Leaf check-in: 797f5ce34e user: Cthulhux tags: trunk
20:20
initial empty check-in check-in: c2db8da21f user: Cthulhux tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Added OEmbed/OEmbed.Hook.php.















































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
<?php

/**
 * @name      OEmbed Support
 * @copyright Cthulhux
 * @license   WTFPL http://www.wtfpl.net/txt/copying/
 * @version   1.0.6
 *
 */


function get_all_urls($string)
{
    // Returns all URLs in <$string>.
    $regex = '/(?<!(=|\]))https?\:\/\/[^\s\]\["<>]+\b/im';
    preg_match_all($regex, $string, $matches);
    return $matches[0];
}

function download_from_url($url)
{
    // Downloads a website and returns its source code.
    $handle = curl_init();

    curl_setopt($handle, CURLOPT_URL, str_replace("&amp;", "&", $url));
    curl_setopt($handle, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($handle, CURLOPT_HEADER, 0);

    $ret = curl_exec($handle);

    curl_close($handle);

    return $ret;
}

function oembed_pre_parse(&$message)
{
    // This is the hook. Yay!
    global $user_info, $txt, $scripturl;

    if (!extension_loaded("curl")) {
        // Admins don't read READMEs. :'(
        return;
    }

    $curl = curl_multi_init();
    $arr_curl_hnd = array();

    // 1.0.4:
    // Some OEmbed sources return IFRAMEs. ElkArte purges those when checking
    // for a message's emptiness. We'll need to add a bogus character to the
    // end of a processed message or else ElkArte will break OEmbed. Well...
    $add_dummy_character = false;

    foreach (get_all_urls($message) as $url) {
        if (filter_var($url, FILTER_VALIDATE_URL) !== false) {
            // Yup, this is a URL. Get it:
            $ch = curl_init();
            curl_setopt($ch, CURLOPT_URL, $url);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
            curl_setopt($ch, CURLOPT_TIMEOUT, 25); // 1.0.6: Don't wait eternally.
            curl_setopt($ch, CURLOPT_HEADER, 0);

            // Add this cURL result to the array of handles:
            $arr_curl_hnd[$url] = $ch;
            curl_multi_add_handle($curl, $ch);
        }
    }

    $active = NULL;

    // Execute all handles asynchronously:
    do {
        $mrc = curl_multi_exec($curl, $active);
    }
    while ($active > 0);

    $re_oembed_json = "/<link.*?type=\"application\/json\+oembed\".*?>/i";
    $re_oembed_xml = "/<link.*?type=\"text\/xml\+oembed\".*?>/i";
    $re_url = '/https?\:\/\/[^\s"<>]+/i';

    // Iterate through the results:
    foreach ($arr_curl_hnd as $url=>$ch) {
        $html = curl_multi_getcontent($ch);

        // Now we probably have shiny HTML.
        // Check if there's oEmbed in it and replace where applicable:
        if (preg_match($re_oembed_json, $html, $matches)) {
            // $matches[0] is a JSON link tag now.
            if (preg_match($re_url, $matches[0], $json_urls)) {
                if (filter_var($json_urls[0], FILTER_VALIDATE_URL) == false) {
                    // Invalid OEmbed URL.
                    curl_multi_remove_handle($curl, $ch);
                    continue;
                }

                // Download and parse the OEmbed JSON:
                $returned_json = download_from_url($json_urls[0]);
                $decoded_json = json_decode($returned_json, true);

                if ($decoded_json == NULL) {
                    // Wrong JSON.
                    curl_multi_remove_handle($curl, $ch);
                    continue;
                }

                if (!array_key_exists("html", $decoded_json)) {
                    // Wrong OEmbed JSON.
                    curl_multi_remove_handle($curl, $ch);
                    continue;
                }

                // Do what needs to be done:
                $message = str_replace($url, $decoded_json["html"], $message);
                $add_dummy_character = true;
            }
        }
        if (extension_loaded("xml")) {
            // 1.0.5:
            // If the XML extension is not available, nothing will happen here.
            // JSON is always supported though.
            if (preg_match($re_oembed_xml, $html, $matches)) {
                // $matches[0] is an XML link tag now.
                if (preg_match($re_url, $matches[0], $xml_urls)) {
                    if (filter_var($xml_urls[0], FILTER_VALIDATE_URL) == false) {
                        // Invalid OEmbed URL.
                        curl_multi_remove_handle($curl, $ch);
                        continue;
                    }

                    // Download and parse the OEmbed XML:
                    $returned_xml = download_from_url($xml_urls[0]);

                    $parser = xml_parser_create();
                    $valid_xml = xml_parse_into_struct($parser, $returned_xml, $vals, $index);
                    xml_parser_free($parser);

                    if (!$valid_xml) {
                        // Nah.
                        curl_multi_remove_handle($curl, $ch);
                        continue;
                    }

                    if (!(array_key_exists("oembed", $vals) && array_key_exists("html", $vals["oembed"]))) {
                        // Invalid OEmbed XML
                        curl_multi_remove_handle($curl, $ch);
                        continue;
                    }

                    // Do what needs to be done:
                    $message = str_replace($url, $vals["oembed"]["html"], $message);
                    $add_dummy_character = true;
                }
            }
        }

        curl_multi_remove_handle($curl, $ch);
    }

    // Clean up:
    curl_multi_close($curl);

    // Add a dummy character when required:
    if ($add_dummy_character) {
        $message .= "&#8291;"; // This should work ... for now.
    }
}

Added OEmbed/Screenshot.png.

cannot compute difference between binary files

Added OEmbed/package-info.xml.



























































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<?xml version="1.0"?>
<!DOCTYPE package-info SYSTEM "http://www.elkarte.net/site/package-info">
<package-info xmlns="http://www.elkarte.net/site/package-info" xmlns:elk="http://www.elkarte.net/">
  <id>Cthulhux:OEmbed</id>
  <name>OEmbed Support</name>
  <type>modification</type>
  <version>1.0.6</version>
  <license><![CDATA[
  /**
  * OEmbed Support
  *
  * @license WTFPL http://www.wtfpl.net/txt/copying/
  *
  * @version 1.0.5
  */
  ]]></license>

  <install for="1.0 - 1.1.99">
    <readme type="file" parsebbc="true">readme.txt</readme>
    <require-file name="OEmbed.Hook.php" destination="SOURCEDIR" />
    <hook hook="integrate_pre_bbc_parser" function="oembed_pre_parse" file="SOURCEDIR/OEmbed.Hook.php" />
  </install>

  <uninstall for="1.0 - 1.1.99">
    <hook reverse="true" hook="integrate_pre_bbc_parser" function="oembed_pre_parse" file="SOURCEDIR/OEmbed.Hook.php" />
    <remove-file name="SOURCEDIR/OEmbed.Hook.php" />
  </uninstall>

</package-info>

Added OEmbed/readme.md.







































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# OEmbed Support

## License

This ElkArte add-on is released under the terms of the WTFPL. Take it and do with it what the fuck you want.

Parts of this add-on (mostly, the idea and the regular expressions) were ported from my [blog software](https://www.blogcpp.org) which is also licensed under the same terms.

## Features

Makes ElkArte support OEmbed, duh. Note that additional CSS is not a part of this add-on, but (e.g.) YouTube provides their own embedded stylesheets.

## Requirements

This add-on won't do anything unless your PHP installation has the `curl` extension enabled. By default, only JSON OEmbeds are recognized. If the `xml` extension is available, XML OEmbeds will be respected as well.

## Donations

In case you absolutely want to make me richer, you can donate some money: [PayPal](https://paypal.me/GebtmireuerGeld).

Added README.txt.



>
1
A collection of ElkArte plug-ins.