Merge branch '3.0'
[GitHub/WoltLab/WCF.git] / wcfsetup / install / files / lib / system / template / plugin / JsFunctionTemplatePlugin.class.php
CommitLineData
66a35294
AE
1<?php
2namespace wcf\system\template\plugin;
3use wcf\system\exception\SystemException;
208bac1e 4use wcf\system\request\RequestHandler;
66a35294
AE
5use wcf\system\template\TemplateEngine;
6use wcf\system\WCF;
7use wcf\util\StringUtil;
8
9/**
10 * Template function plugin which script tags. File extension is automatically added
11 * to the script source and MUST NOT be provided.
12 *
13 * If ENABLE_DEBUG_MODE=0 then the extension is '.min.js', don't fail to provide it.
14 *
0d20df38
AE
15 * The option VISITOR_USE_TINY_BUILD enables a specialized build, that is designed to
16 * provide smaller builds for visitors in order to decrease the overall payload and
17 * reduce page load time. Supporting them is optional and can be supplied by setting
18 * `hasTiny=true`, the extension is assumed to be `.tiny.min.js`.
19 *
66a35294
AE
20 * Usage:
21 * {js application='wbb' file='WBB'}
22 * http://example.com/js/WBB.js
23 *
24 * {js application='wcf' file='WCF.Like' bundle='WCF.Combined'}
25 * http://example.com/wcf/js/WCF.Like.js (ENABLE_DEBUG_MODE=1)
26 * http://example.com/wcf/js/WCF.Combined.min.js (ENABLE_DEBUG_MODE=0)
27 *
28 * {js application='wcf' lib='jquery'}
29 * http://example.com/wcf/js/3rdParty/jquery.js
30 *
31 * {js application='wcf' lib='jquery-ui' file='awesomeWidget'}
32 * http://example.com/wcf/js/3rdParty/jquery-ui/awesomeWidget.js
0d20df38
AE
33 *
34 * {js application='wcf' file='WCF.Like' bundle='WCF.Combined' hasTiny=true}
35 * http://example.com/wcf/js/WCF.Like.js (ENABLE_DEBUG_MODE=1)
36 * http://example.com/wcf/js/WCF.Combined.min.js (ENABLE_DEBUG_MODE=0)
37 * http://example.com/wcf/js/WCF.Combined.tiny.min.js (ENABLE_DEBUG_MODE=0 && VISITOR_USE_TINY_BUILD=1)
66a35294
AE
38 *
39 * @author Alexander Ebert
c839bd49 40 * @copyright 2001-2018 WoltLab GmbH
66a35294 41 * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
e71525e4
MW
42 * @package WoltLabSuite\Core\System\Template\Plugin
43 * @since 3.0
66a35294
AE
44 */
45class JsFunctionTemplatePlugin implements IFunctionTemplatePlugin {
d5cccc0c
AE
46 /**
47 * list of already included JavaScript files
7a23a706 48 * @var string[]
d5cccc0c
AE
49 */
50 protected $includedFiles = [];
51
66a35294 52 /**
0fcfe5f6 53 * @inheritDoc
66a35294
AE
54 */
55 public function execute($tagArgs, TemplateEngine $tplObj) {
56 // needed arguments: application and lib/file
57 if (empty($tagArgs['application'])) throw new SystemException("missing 'application' argument in js tag");
58 if (empty($tagArgs['file']) && empty($tagArgs['lib'])) throw new SystemException("missing 'file' or 'lib' argument in js tag");
59
e3b8ca06
AE
60 $isJquery = false;
61 if (isset($tagArgs['lib']) && ($tagArgs['lib'] === 'jquery' || $tagArgs['lib'] === 'jquery-ui') && empty($tagArgs['file'])) {
66a35294 62 $tagArgs['bundle'] = '';
e3b8ca06 63 $isJquery = true;
66a35294
AE
64 }
65
208bac1e 66 $src = WCF::getPath($tagArgs['application']) . (isset($tagArgs['acp']) && $tagArgs['acp'] === 'true' ? 'acp/' : '') . 'js/';
66a35294
AE
67 if (!empty($tagArgs['bundle']) && !ENABLE_DEBUG_MODE) {
68 $src .= $tagArgs['bundle'];
69 }
70 else if (!empty($tagArgs['lib'])) {
e3b8ca06 71 if ($isJquery) {
63b9817b 72 $src .= ENABLE_DEBUG_MODE ? '3rdParty/' . $tagArgs['lib'] : 'WCF.Combined';
66a35294
AE
73 }
74 else {
75 $src .= '3rdParty/' . $tagArgs['lib'];
76 if (!empty($tagArgs['file'])) {
77 $src .= '/' . $tagArgs['file'];
78 }
79 }
80 }
81 else {
82 $src .= $tagArgs['file'];
83 }
84
a8160b8d 85 if (isset($this->includedFiles[$src])) {
d5cccc0c
AE
86 return '';
87 }
88
a8160b8d 89 $this->includedFiles[$src] = true;
0d20df38 90 if (!ENABLE_DEBUG_MODE) {
5426c65e 91 if (defined('VISITOR_USE_TINY_BUILD') && VISITOR_USE_TINY_BUILD && !WCF::getUser()->userID && !empty($tagArgs['hasTiny'])) {
0d20df38
AE
92 $src .= '.tiny';
93 }
94
95 $src .= '.min';
96 }
97 $src .= '.js?v=' . LAST_UPDATE_TIME;
66a35294 98
208bac1e
AE
99 $relocate = !RequestHandler::getInstance()->isACPRequest() && (!isset($tagArgs['core']) || $tagArgs['core'] !== 'true');
100 $html = '<script' . ($relocate ? ' data-relocate="true"' : '') . ' src="' . $src . '"></script>'."\n";
66a35294
AE
101
102 if (isset($tagArgs['encodeJs']) && $tagArgs['encodeJs'] === 'true') {
103 $html = StringUtil::encodeJS($html);
104 }
105
106 return $html;
107 }
108}