Add explicit `return null;` statements
[GitHub/WoltLab/WCF.git] / wcfsetup / install / files / lib / data / bbcode / media / provider / BBCodeMediaProvider.class.php
1 <?php
2
3 namespace wcf\data\bbcode\media\provider;
4
5 use wcf\data\DatabaseObject;
6 use wcf\system\bbcode\media\provider\IBBCodeMediaProvider;
7 use wcf\system\cache\builder\BBCodeMediaProviderCacheBuilder;
8 use wcf\system\Regex;
9 use wcf\system\request\IRouteController;
10 use wcf\system\WCF;
11 use wcf\util\StringUtil;
12 use wcf\util\Url;
13
14 /**
15 * Represents a BBCode media provider.
16 *
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
27 */
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|null
140 */
141 public function getCallback()
142 {
143 if (!$this->className) {
144 return null;
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 }
177 }