3 namespace wcf\system\bbcode
;
5 use wcf\data\bbcode\BBCode
;
6 use wcf\data\bbcode\BBCodeCache
;
7 use wcf\system\application\ApplicationHandler
;
8 use wcf\system\package\license\LicenseApi
;
9 use wcf\system\SingletonFactory
;
11 use wcf\util\ArrayUtil
;
13 use wcf\util\StringUtil
;
16 * Handles BBCodes displayed as buttons within the WYSIWYG editor.
18 * @author Alexander Ebert
19 * @copyright 2001-2019 WoltLab GmbH
20 * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
22 class BBCodeHandler
extends SingletonFactory
25 * list of BBCodes displayed as buttons
28 protected $buttonBBCodes = [];
31 * list of BBCodes disallowed for usage
34 protected $disallowedBBCodes = [];
37 * list of BBCodes which contain raw code (disabled BBCode parsing)
40 protected $sourceBBCodes;
43 * meta information about highlighters
46 protected $highlighterMeta;
51 protected function init()
53 foreach (BBCodeCache
::getInstance()->getBBCodes() as $bbcode) {
54 if ($bbcode->showButton
) {
55 $this->buttonBBCodes
[] = $bbcode;
61 * Returns true if the BBCode with the given tag is available in the WYSIWYG editor.
63 public function isAvailableBBCode(string $bbCodeTag, bool $overrideFormattingRemoval = false): bool
65 if ($overrideFormattingRemoval === false) {
66 if ($bbCodeTag === "color" && \FORMATTING_REMOVE_COLOR
) {
70 if ($bbCodeTag === "font" && \FORMATTING_REMOVE_FONT
) {
74 if ($bbCodeTag === "size" && \FORMATTING_REMOVE_SIZE
) {
79 return !\
in_array($bbCodeTag, $this->disallowedBBCodes
);
83 * Returns all bbcodes.
87 public function getBBCodes()
89 return BBCodeCache
::getInstance()->getBBCodes();
93 * Returns a list of BBCodes displayed as buttons.
95 * @param bool $excludeCoreBBCodes do not return bbcodes that are available by default
98 public function getButtonBBCodes($excludeCoreBBCodes = false)
121 foreach ($this->buttonBBCodes
as $bbcode) {
122 if ($excludeCoreBBCodes && \
in_array($bbcode->bbcodeTag
, $coreBBCodes)) {
126 if ($this->isAvailableBBCode($bbcode->bbcodeTag
)) {
127 $buttons[] = $bbcode;
135 * Sets the disallowed BBCodes.
137 * @param string[] $bbCodes
139 public function setDisallowedBBCodes(array $bbCodes)
141 $this->disallowedBBCodes
= $bbCodes;
145 * Returns a list of BBCodes which contain raw code (disabled BBCode parsing)
148 * @deprecated 3.1 - This method is no longer supported.
150 public function getSourceBBCodes()
156 * Returns metadata about the highlighters.
160 public function getHighlighterMeta()
162 if ($this->highlighterMeta
=== null) {
163 $this->highlighterMeta
= JSON
::decode(\
preg_replace(
164 '/.*\/\*!START\*\/\s*const\s*metadata\s*=\s*(.*)\s*;\s*\/\*!END\*\/.*/s',
166 \file_get_contents
(WCF_DIR
. '/js/WoltLabSuite/Core/prism-meta.js')
170 return $this->highlighterMeta
;
174 * Returns a list of known highlighters.
178 public function getHighlighters()
180 return \array_keys
($this->getHighlighterMeta());
184 * Returns the list of languages that are available for selection in the
185 * UI of CKEditor’s code block.
187 * @return list<string>
190 public function getCodeBlockLanguages(): array
192 return \
explode("\n", StringUtil
::unifyNewlines(\MESSAGE_PUBLIC_HIGHLIGHTERS
));
196 * Returns a list of hostnames that are permitted as image sources.
201 public function getImageExternalSourceWhitelist()
204 // Hide these hosts unless external sources are actually denied.
205 if (!IMAGE_ALLOW_EXTERNAL_SOURCE
) {
206 $hosts = ArrayUtil
::trim(\
explode(
210 \IMAGE_EXTERNAL_SOURCE_WHITELIST
,
216 $hosts[] = ApplicationHandler
::getInstance()->getDomainName();
218 return \array_unique
($hosts);
222 * Exports a require.js requirement for the localization of the editor based
223 * on the current locale. Returns an empty string when there is no available
224 * localization or the locale equals the bundled value 'en'.
228 public function getEditorLocalization(): string
230 $availableTranslations = [
302 $locale = \
strtolower(WCF
::getLanguage()->getBcp47());
303 if (\
in_array($locale, $availableTranslations, true)) {
305 '"ckeditor5-translation/%s",',
310 // Some languages offer both specialized variants for certain locales
311 // but also provide a "generic" variant. For example, "en-gb" and "en".
312 [$languageCode] = \
explode('-', $locale, 2);
313 if (\
in_array($languageCode, $availableTranslations, true)) {
315 '"ckeditor5-translation/%s",',
320 // The default locale "en" is part of the generated bundle, we must not
321 // yield any module if this locale is (implicitly) requested.
328 public function getCkeditorLicenseKey(): string
330 $licenseApi = new LicenseApi();
331 $licenseData = $licenseApi->readFromFile();
333 if ($licenseData === null) {
337 return $licenseData->license
['ckeditorLicenseKey'] ??
'';