Commit | Line | Data |
---|---|---|
dcc2332d | 1 | <?php |
a9229942 | 2 | |
dcc2332d | 3 | namespace wcf\data\bbcode\media\provider; |
a9229942 | 4 | |
dcc2332d | 5 | use wcf\data\DatabaseObject; |
cba8f591 | 6 | use wcf\system\bbcode\media\provider\IBBCodeMediaProvider; |
dcc2332d | 7 | use wcf\system\cache\builder\BBCodeMediaProviderCacheBuilder; |
dcc2332d | 8 | use wcf\system\Regex; |
a9229942 | 9 | use wcf\system\request\IRouteController; |
3ffe6e3f | 10 | use wcf\system\WCF; |
dcc2332d | 11 | use wcf\util\StringUtil; |
3ffe6e3f | 12 | use wcf\util\Url; |
dcc2332d MW |
13 | |
14 | /** | |
15 | * Represents a BBCode media provider. | |
e9335ed9 | 16 | * |
a9229942 TD |
17 | * @author Tim Duesterhus |
18 | * @copyright 2001-2020 WoltLab GmbH | |
19 | * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php> | |
20 | * @package WoltLabSuite\Core\Data\Bbcode\Media\Provider | |
21 | * | |
22 | * @property-read int $providerID unique id of the bbcode media provider | |
23 | * @property-read string $title title of the bbcode media provider (shown in acp) | |
24 | * @property-read string $regex regular expression to recognize media elements/element urls | |
25 | * @property-read string $html html code used to render media elements | |
26 | * @property-read string $className callback class name | |
dcc2332d | 27 | */ |
a9229942 TD |
28 | class BBCodeMediaProvider extends DatabaseObject implements IRouteController |
29 | { | |
30 | /** | |
31 | * @inheritDoc | |
32 | */ | |
33 | protected static $databaseTableName = 'bbcode_media_provider'; | |
34 | ||
35 | /** | |
36 | * cached providers | |
37 | * @var BBCodeMediaProvider[] | |
38 | */ | |
39 | protected static $cache = null; | |
40 | ||
41 | /** | |
42 | * media provider callback instance | |
43 | * @var IBBCodeMediaProvider | |
44 | */ | |
45 | protected $callback; | |
46 | ||
47 | /** | |
48 | * Loads the provider cache. | |
49 | * | |
50 | * @return BBCodeMediaProvider[] | |
51 | */ | |
52 | public static function getCache() | |
53 | { | |
54 | if (self::$cache === null) { | |
55 | self::$cache = BBCodeMediaProviderCacheBuilder::getInstance()->getData(); | |
56 | } | |
57 | ||
58 | return self::$cache; | |
59 | } | |
60 | ||
61 | /** | |
62 | * Returns true if given URL is a media URL. | |
63 | * | |
64 | * @param string $url | |
65 | * @return bool | |
66 | */ | |
67 | public static function isMediaURL($url) | |
68 | { | |
69 | foreach (static::getCache() as $provider) { | |
70 | if ($provider->matches($url)) { | |
71 | return true; | |
72 | } | |
73 | } | |
74 | ||
75 | return false; | |
76 | } | |
77 | ||
78 | /** | |
79 | * Checks whether this provider matches the given URL. | |
80 | * | |
81 | * @param string $url | |
82 | * @return bool | |
83 | */ | |
84 | public function matches($url) | |
85 | { | |
86 | $lines = \explode("\n", StringUtil::unifyNewlines($this->regex)); | |
87 | ||
88 | foreach ($lines as $line) { | |
89 | if (Regex::compile($line)->match($url)) { | |
90 | return true; | |
91 | } | |
92 | } | |
93 | ||
94 | return false; | |
95 | } | |
96 | ||
97 | /** | |
98 | * Returns the html for this provider. | |
99 | * | |
100 | * @param string $url | |
101 | * @return string | |
102 | */ | |
103 | public function getOutput($url) | |
104 | { | |
105 | $lines = \explode("\n", StringUtil::unifyNewlines($this->regex)); | |
106 | ||
107 | foreach ($lines as $line) { | |
108 | $regex = new Regex($line); | |
109 | if (!$regex->match($url)) { | |
110 | continue; | |
111 | } | |
112 | ||
113 | if ($this->getCallback() !== null) { | |
114 | return $this->getOutputForUserConsent($url, $this->getCallback()->parse($url, $regex->getMatches())); | |
115 | } else { | |
116 | $output = $this->html; | |
117 | foreach ($regex->getMatches() as $name => $value) { | |
118 | $output = \str_replace('{$' . $name . '}', $value, $output); | |
119 | } | |
120 | ||
121 | return $this->getOutputForUserConsent($url, $output); | |
122 | } | |
123 | } | |
124 | ||
125 | return ''; | |
126 | } | |
127 | ||
128 | /** | |
129 | * @inheritDoc | |
130 | */ | |
131 | public function getTitle() | |
132 | { | |
133 | return $this->title; | |
134 | } | |
135 | ||
136 | /** | |
137 | * Returns media provider callback instance. | |
138 | * | |
139 | * @return IBBCodeMediaProvider | |
140 | */ | |
141 | public function getCallback() | |
142 | { | |
143 | if (!$this->className) { | |
144 | return; | |
145 | } | |
146 | ||
147 | if ($this->callback === null) { | |
148 | $this->callback = new $this->className(); | |
149 | } | |
150 | ||
151 | return $this->callback; | |
152 | } | |
153 | ||
154 | /** | |
155 | * Replaces embedded media with an approval dialog. | |
156 | * | |
157 | * @param string $url | |
158 | * @param string $html | |
159 | * @return string | |
160 | */ | |
161 | protected function getOutputForUserConsent($url, $html) | |
162 | { | |
163 | if (!MESSAGE_ENABLE_USER_CONSENT) { | |
164 | return $html; | |
165 | } | |
166 | ||
167 | if (WCF::getUser()->userID && WCF::getUser()->getUserOption('enableEmbeddedMedia')) { | |
168 | return $html; | |
169 | } | |
170 | ||
171 | return WCF::getTPL()->fetch('messageUserConsent', 'wcf', [ | |
172 | 'host' => Url::parse($url)['host'], | |
173 | 'payload' => \base64_encode($html), | |
174 | 'url' => $url, | |
175 | ]); | |
176 | } | |
dcc2332d | 177 | } |