<dl{if $errorField == 'regex'} class="formError"{/if}>
<dt><label for="regex">{lang}wcf.acp.bbcode.mediaProvider.regex{/lang}</label></dt>
<dd>
- <textarea id="regex" name="regex" cols="40" rows="10" required>{$regex}</textarea>
+ <textarea id="regex" name="regex" cols="40" rows="5" required>{$regex}</textarea>
{if $errorField == 'regex'}
<small class="innerError">
{if $errorType == 'empty'}
<dl{if $errorField == 'html'} class="formError"{/if}>
<dt><label for="html">{lang}wcf.acp.bbcode.mediaProvider.html{/lang}</label></dt>
<dd>
- <textarea id="html" name="html" cols="40" rows="10" required>{$html}</textarea>
+ <textarea id="html" name="html" cols="40" rows="10">{$html}</textarea>
{if $errorField == 'html'}
<small class="innerError">
{if $errorType == 'empty'}
</dd>
</dl>
+ <dl{if $errorField == 'className'} class="formError"{/if}>
+ <dt><label for="className">{lang}wcf.acp.bbcode.mediaProvider.className{/lang}</label></dt>
+ <dd>
+ <input type="text" id="className" name="className" value="{$className}" pattern="^\\?([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*\\)*[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*$" class="long">
+ {if $errorField == 'className'}
+ <small class="innerError">
+ {if $errorType == 'empty'}
+ {lang}wcf.global.form.error.empty{/lang}
+ {else}
+ {lang}wcf.acp.bbcode.mediaProvider.className.error.{@$errorType}{/lang}
+ {/if}
+ </small>
+ {/if}
+ </dd>
+ </dl>
+
{event name='dataFields'}
</div>
*/
public $activeMenuItem = 'wcf.acp.menu.link.bbcode.mediaProvider.add';
+ /**
+ * media provider class name
+ * @var string
+ */
+ public $className = '';
+
/**
* html value
* @var string
if (isset($_POST['title'])) $this->title = StringUtil::trim($_POST['title']);
if (isset($_POST['regex'])) $this->regex = StringUtil::trim($_POST['regex']);
if (isset($_POST['html'])) $this->html = StringUtil::trim($_POST['html']);
+ if (isset($_POST['className'])) $this->className = StringUtil::trim($_POST['className']);
}
/**
if (empty($this->regex)) {
throw new UserInputException('regex');
}
- if (empty($this->html)) {
+ if (empty($this->className) && empty($this->html)) {
throw new UserInputException('html');
}
+ // validate class name
+ if (!empty($this->className) && !class_exists($this->className)) {
+ throw new UserInputException('className', 'notFound');
+ }
$lines = explode("\n", StringUtil::unifyNewlines($this->regex));
$this->objectAction = new BBCodeMediaProviderAction([], 'create', ['data' => array_merge($this->additionalFields, [
'title' => $this->title,
'regex' => $this->regex,
- 'html' => $this->html
+ 'html' => $this->html,
+ 'className' => $this->className
])]);
$this->objectAction->executeAction();
$this->saved();
// reset values
- $this->title = $this->regex = $this->html = '';
+ $this->title = $this->regex = $this->html = $this->className = '';
// show success message
WCF::getTPL()->assign('success', true);
'action' => 'add',
'title' => $this->title,
'regex' => $this->regex,
- 'html' => $this->html
+ 'html' => $this->html,
+ 'className' => $this->className
]);
}
}
$this->objectAction = new BBCodeMediaProviderAction([$this->providerID], 'update', ['data' => array_merge($this->additionalFields, [
'title' => $this->title,
'regex' => $this->regex,
- 'html' => $this->html
+ 'html' => $this->html,
+ 'className' => $this->className
])]);
$this->objectAction->executeAction();
$this->title = $this->mediaProvider->title;
$this->regex = $this->mediaProvider->regex;
$this->html = $this->mediaProvider->html;
+ $this->className = $this->mediaProvider->className;
}
}
<?php
namespace wcf\data\bbcode\media\provider;
use wcf\data\DatabaseObject;
+use wcf\system\bbcode\media\provider\IBBCodeMediaProvider;
use wcf\system\cache\builder\BBCodeMediaProviderCacheBuilder;
use wcf\system\request\IRouteController;
use wcf\system\Regex;
* @property-read string $title title of the bbcode media provider (shown in acp)
* @property-read string $regex regular expression to recognize media elements/element urls
* @property-read string $html html code used to render media elements
+ * @property-read string $className callback class name
*/
class BBCodeMediaProvider extends DatabaseObject implements IRouteController {
/**
*/
protected static $cache = null;
+ /**
+ * media provider callback instance
+ * @var IBBCodeMediaProvider
+ */
+ protected $callback;
+
/**
* Loads the provider cache.
*
$regex = new Regex($line);
if (!$regex->match($url)) continue;
- $output = $this->html;
- foreach ($regex->getMatches() as $name => $value) {
- $output = str_replace('{$'.$name.'}', $value, $output);
+ if ($this->getCallback() !== null) {
+ return $this->getCallback()->parse($url, $regex->getMatches());
+ }
+ else {
+ $output = $this->html;
+ foreach ($regex->getMatches() as $name => $value) {
+ $output = str_replace('{$' . $name . '}', $value, $output);
+ }
+ return $output;
}
- return $output;
}
return '';
public function getTitle() {
return $this->title;
}
+
+ /**
+ * Returns media provider callback instance.
+ *
+ * @return IBBCodeMediaProvider
+ */
+ public function getCallback() {
+ if (!$this->className) return null;
+
+ if ($this->callback === null) {
+ $this->callback = new $this->className;
+ }
+
+ return $this->callback;
+ }
}
--- /dev/null
+<?php
+namespace wcf\system\bbcode\media\provider;
+
+/**
+ * Interface for media provider callbacks.
+ *
+ * @author Marcel Werk
+ * @copyright 2001-2017 WoltLab GmbH
+ * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @package WoltLabSuite\Core\System\Bbcode\Media\Provider
+ */
+interface IBBCodeMediaProvider {
+ /**
+ * Parses given media url and returns output html.
+ *
+ * @param string $url media url
+ * @param string[] $matches
+ * @return string output html
+ */
+ public function parse($url, array $matches = []);
+}
--- /dev/null
+<?php
+namespace wcf\system\bbcode\media\provider;
+
+/**
+ * Media provider callback for YouTube urls.
+ *
+ * @author Marcel Werk
+ * @copyright 2001-2017 WoltLab GmbH
+ * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @package WoltLabSuite\Core\System\Bbcode\Media\Provider
+ */
+class YouTubeBBCodeMediaProvider implements IBBCodeMediaProvider {
+ /**
+ * @inheritDoc
+ */
+ public function parse($url, array $matches = []) {
+ $start = 0;
+ if (!empty($matches['start'])) {
+ if (preg_match('~^(?:(?:(?P<h>\d+)h)?(?P<m>\d+)m(?P<s>\d+))|(?P<t>\d+)~', $matches['start'], $match)) {
+ if (!empty($match['h'])) {
+ $start += intval($match['h']) * 3600;
+ }
+ if (!empty($match['m'])) {
+ $start += intval($match['m']) * 60;
+ }
+ if (!empty($match['s'])) {
+ $start += intval($match['s']);
+ }
+ if (!empty($match['t'])) {
+ $start += intval($match['t']);
+ }
+ }
+ }
+
+ return '<div class="videoContainer"><iframe src="https://www.youtube.com/embed/' . $matches['ID'] . '?wmode=transparent' . ($start ? '&start='.$start : '') . '" allowfullscreen></iframe></div>';
+ }
+}
<item name="wcf.acp.bbcode.list"><![CDATA[BBCodes]]></item>
<item name="wcf.acp.bbcode.mediaProvider.add"><![CDATA[Medienanbieter hinzufügen]]></item>
+ <item name="wcf.acp.bbcode.mediaProvider.className"><![CDATA[Klassen-Name]]></item>
+ <item name="wcf.acp.bbcode.mediaProvider.className.error.notFound"><![CDATA[Diese Klasse wurde nicht gefunden.]]></item>
<item name="wcf.acp.bbcode.mediaProvider.delete.sure"><![CDATA[{if LANGUAGE_USE_INFORMAL_VARIANT}Willst du{else}Wollen Sie{/if} den Medienanbieter <span class="confirmationObject">{$mediaProvider->title}</span> wirklich löschen?]]></item>
<item name="wcf.acp.bbcode.mediaProvider.edit"><![CDATA[Medienanbieter bearbeiten]]></item>
<item name="wcf.acp.bbcode.mediaProvider.html"><![CDATA[HTML-Code]]></item>
<item name="wcf.acp.bbcode.list"><![CDATA[BBCodes]]></item>
<item name="wcf.acp.bbcode.mediaProvider.add"><![CDATA[Add Media Provider]]></item>
+ <item name="wcf.acp.bbcode.mediaProvider.className"><![CDATA[PHP Class Name]]></item>
+ <item name="wcf.acp.bbcode.mediaProvider.className.error.notFound"><![CDATA[Unable to find specified class.]]></item>
<item name="wcf.acp.bbcode.mediaProvider.delete.sure"><![CDATA[Do you really want to delete the media provider <span class="confirmationObject">{$mediaProvider->title}</span>?]]></item>
<item name="wcf.acp.bbcode.mediaProvider.edit"><![CDATA[Edit Media Provider]]></item>
<item name="wcf.acp.bbcode.mediaProvider.html"><![CDATA[HTML Code]]></item>
providerID INT(10) NOT NULL AUTO_INCREMENT PRIMARY KEY,
title VARCHAR(255) NOT NULL,
regex TEXT NOT NULL,
- html TEXT NOT NULL
+ html TEXT NOT NULL,
+ className varchar(255) NOT NULL DEFAULT ''
);
DROP TABLE IF EXISTS wcf1_box;
-- media providers
-- Videos
-- Youtube
- INSERT INTO wcf1_bbcode_media_provider (title, regex, html) VALUES ('YouTube', 'https?://(?:.+?\\.)?youtu(?:\\.be/|be\\.com/(?:#/)?watch\\?(?:.*?&)?v=)(?P<ID>[a-zA-Z0-9_-]+)(?:(?:\\?|&)t=(?P<start>\\d+)$)?', '<div class="videoContainer"><iframe src="https://www.youtube.com/embed/{$ID}?wmode=transparent&start={$start}" allowfullscreen></iframe></div>');
+ INSERT INTO wcf1_bbcode_media_provider (title, regex, html, className) VALUES ('YouTube', 'https?://(?:.+?\\.)?youtu(?:\\.be/|be\\.com/(?:#/)?watch\\?(?:.*?&)?v=)(?P<ID>[a-zA-Z0-9_-]+)(?:(?:\\?|&)t=(?P<start>[0-9hms]+)$)?', '', 'wcf\\system\\bbcode\\media\\provider\\YouTubeBBCodeMediaProvider');
-- Youtube playlist
INSERT INTO wcf1_bbcode_media_provider (title, regex, html) VALUES ('YouTube Playlist', 'https?://(?:.+?\\.)?youtu(?:\\.be/|be\\.com/)playlist\\?(?:.*?&)?list=(?P<ID>[a-zA-Z0-9_-]+)', '<div class="videoContainer"><iframe src="https://www.youtube.com/embed/videoseries?list={$ID}" allowfullscreen></iframe></div>');
-- Vimeo
- INSERT INTO wcf1_bbcode_media_provider (title, regex, html) VALUES ('Vimeo', 'https?://vimeo\\.com/(?:channels/[^/]+/)?(?P<ID>\\d+)', '<iframe src="https://player.vimeo.com/video/{$ID}" width="400" height="225" webkitAllowFullScreen mozallowfullscreen allowFullScreen></iframe>');
+ INSERT INTO wcf1_bbcode_media_provider (title, regex, html) VALUES ('Vimeo', 'https?://vimeo\\.com/(?:channels/[^/]+/)?(?P<ID>\\d+)\nhttps?://vimeo\\.com/groups/[^/]+/videos/(?P<ID>\\d+)', '<div class="videoContainer"><iframe src="https://player.vimeo.com/video/{$ID}" allowfullscreen></iframe></div>');
-- Clipfish
INSERT INTO wcf1_bbcode_media_provider (title, regex, html) VALUES ('Clipfish', 'http://(?:www\\.)?clipfish\\.de/(?:.*?/)?video/(?P<ID>\\d+)/', '<div style="width:464px; height:404px;"><div style="width:464px; height:384px;"><iframe src="http://www.clipfish.de/embed_video/?vid={$ID}&as=0&col=990000" name="Clipfish Embedded Video" width="464" height="384" align="left" marginheight="0" marginwidth="0" scrolling="no"></iframe></div></div>');
-- Veoh