Merge pull request #5987 from WoltLab/acp-dahsboard-box-hight
[GitHub/WoltLab/WCF.git] / wcfsetup / install / files / lib / acp / form / TemplateAddForm.class.php
CommitLineData
6570e38e 1<?php
a9229942 2
6570e38e 3namespace wcf\acp\form;
a9229942 4
fec77826 5use wcf\data\IStorableObject;
e568316b
MS
6use wcf\data\package\Package;
7use wcf\data\package\PackageCache;
6570e38e 8use wcf\data\template\group\TemplateGroup;
fec77826 9use wcf\data\template\group\TemplateGroupNodeTree;
6570e38e
MW
10use wcf\data\template\Template;
11use wcf\data\template\TemplateAction;
fec77826
C
12use wcf\form\AbstractFormBuilderForm;
13use wcf\system\cache\builder\TemplateGroupCacheBuilder;
dd1bae1b 14use wcf\system\database\util\PreparedStatementConditionBuilder;
43a250e6 15use wcf\system\exception\IllegalLinkException;
fec77826
C
16use wcf\system\form\builder\container\FormContainer;
17use wcf\system\form\builder\data\processor\CustomFormDataProcessor;
18use wcf\system\form\builder\data\processor\VoidFormDataProcessor;
19use wcf\system\form\builder\field\HiddenFormField;
fec77826 20use wcf\system\form\builder\field\SingleSelectionFormField;
59e1e354 21use wcf\system\form\builder\field\SourceCodeFormField;
fec77826
C
22use wcf\system\form\builder\field\TextFormField;
23use wcf\system\form\builder\field\validation\FormFieldValidationError;
24use wcf\system\form\builder\field\validation\FormFieldValidator;
25use wcf\system\form\builder\IFormDocument;
df8845ad 26use wcf\system\template\TemplateEngine;
6570e38e 27use wcf\system\WCF;
6570e38e
MW
28
29/**
30 * Shows the form for adding new templates.
a9229942
TD
31 *
32 * @author Marcel Werk
fec77826 33 * @copyright 2001-2024 WoltLab GmbH
a9229942 34 * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
6570e38e 35 */
fec77826 36class TemplateAddForm extends AbstractFormBuilderForm
a9229942
TD
37{
38 /**
39 * @inheritDoc
40 */
41 public $activeMenuItem = 'wcf.acp.menu.link.template.add';
42
43 /**
44 * @inheritDoc
45 */
46 public $neededPermissions = ['admin.template.canManageTemplate'];
47
48 /**
fec77826 49 * @inheritDoc
a9229942 50 */
fec77826 51 public $objectActionClass = TemplateAction::class;
a9229942
TD
52
53 /**
fec77826 54 * @inheritDoc
a9229942 55 */
fec77826 56 public $objectEditLinkController = TemplateEditForm::class;
a9229942
TD
57
58 /**
59 * id of copied template
60 * @var int
61 */
fec77826 62 public int $copy = 0;
a9229942
TD
63
64 /**
65 * copied template object
66 * @var Template
67 */
fec77826 68 public Template $copiedTemplate;
a9229942 69
fec77826
C
70 #[\Override]
71 protected function createForm()
72 {
73 parent::createForm();
74
75 $this->form->appendChildren([
76 FormContainer::create('general')
77 ->appendChildren([
78 SingleSelectionFormField::create('templateGroupID')
79 ->label('wcf.acp.template.group')
80 ->options(new TemplateGroupNodeTree(), true)
81 ->addValidator(
82 new FormFieldValidator('sharedTemplate', function (SingleSelectionFormField $formField) {
83 $templateGroupID = $formField->getSaveValue();
84 $templateGroup = TemplateGroupCacheBuilder::getInstance()->getData(
85 [],
86 $templateGroupID
87 );
88 \assert($templateGroup instanceof TemplateGroup);
89
90 $tplNameFormField = $formField->getDocument()->getNodeById('templateName');
91 \assert($tplNameFormField instanceof TextFormField);
92 $tplName = $tplNameFormField->getSaveValue();
93
94 if (
df8845ad 95 TemplateEngine::isSharedTemplate($tplName)
fec77826
C
96 && $templateGroup->templateGroupFolderName !== '_wcf_shared/'
97 ) {
98 $formField->addValidationError(
99 new FormFieldValidationError(
100 'invalid',
856915dd 101 'wcf.acp.template.group.error.shared'
fec77826
C
102 )
103 );
104 } elseif (
df8845ad 105 !TemplateEngine::isSharedTemplate($tplName)
fec77826
C
106 && $templateGroup->templateGroupFolderName === '_wcf_shared/'
107 ) {
108 $formField->addValidationError(
109 new FormFieldValidationError(
110 'invalid',
856915dd 111 'wcf.acp.template.group.error.notShared'
fec77826
C
112 )
113 );
114 }
115 })
116 ),
117 TextFormField::create('templateName')
118 ->required()
119 ->label('wcf.global.name')
120 ->addValidator(
121 new FormFieldValidator('fileName', function (TextFormField $formField) {
122 $tplName = $formField->getSaveValue();
123 if (!\preg_match('/^[a-z0-9_\-]+$/i', $tplName)) {
124 $formField->addValidationError(
125 new FormFieldValidationError('invalid', 'wcf.acp.template.name.error.invalid')
126 );
127 }
128 })
129 )
130 ->addValidator(
131 new FormFieldValidator('unique', function (TextFormField $formField) {
132 $templateGroupIDFormField = $formField->getDocument()->getNodeById('templateGroupID');
133 \assert($templateGroupIDFormField instanceof SingleSelectionFormField);
134
135 $conditionBuilder = new PreparedStatementConditionBuilder();
136 $conditionBuilder->add('templateName = ?', [$formField->getSaveValue()]);
137 $conditionBuilder->add('templateGroupID = ?', [
138 $templateGroupIDFormField->getSaveValue()
139 ]);
140
141 if (isset($this->copiedTemplate)) {
142 $conditionBuilder->add(
143 '(packageID = ? OR application = ?)',
144 [$this->copiedTemplate->packageID, $this->copiedTemplate->application]
145 );
146 } else {
147 $conditionBuilder->add('packageID = ?', [1]);
148 }
149
150 if ($this->formAction === 'edit') {
151 $conditionBuilder->add('templateID <> ?', [$this->formObject->getObjectID()]);
152 }
153
154 $sql = "SELECT COUNT(*)
155 FROM wcf" . WCF_N . "_template
156 " . $conditionBuilder;
157 $statement = WCF::getDB()->prepareStatement($sql);
158 $statement->execute($conditionBuilder->getParameters());
159
160 if ($statement->fetchSingleColumn()) {
161 $formField->addValidationError(
162 new FormFieldValidationError(
163 'notUnique',
164 'wcf.acp.template.name.error.notUnique'
165 )
166 );
167 }
168 })
169 ),
170 ]),
171 FormContainer::create('source')
172 ->label('wcf.acp.template.source')
173 ->appendChildren([
59e1e354
C
174 SourceCodeFormField::create('templateSource')
175 ->language('smarty')
fec77826 176 ->label('wcf.acp.template.source'),
fec77826
C
177 ]),
178 HiddenFormField::create('copy')
179 ->value($this->copy),
180 ]);
a9229942 181
fec77826
C
182 $this->form->getDataHandler()
183 ->addProcessor(
184 new CustomFormDataProcessor(
185 'source',
186 static function (IFormDocument $document, array $parameters) {
187 $parameters['source'] = $parameters['data']['templateSource'];
188
189 return $parameters;
190 },
191 function (IFormDocument $document, array $data, IStorableObject $object) {
192 \assert($object instanceof Template);
193 $data['templateSource'] = $object->getSource();
194
195 return $data;
196 }
197 )
198 )
199 ->addProcessor(new VoidFormDataProcessor('copy'))
200 ->addProcessor(new VoidFormDataProcessor('templateSource'));
201
202 if ($this->formAction === 'create') {
203 $this->form->getDataHandler()
204 ->addProcessor(
205 new CustomFormDataProcessor(
206 'application',
207 function (IFormDocument $document, array $parameters) {
208 if (isset($this->copiedTemplate)) {
209 $parameters['data']['application'] = $this->copiedTemplate->application;
210 } else {
211 $sql = "SELECT packageID
212 FROM wcf" . WCF_N . "_template
213 WHERE templateName = ?
214 AND templateGroupID IS NULL";
215 $statement = WCF::getDB()->prepareStatement($sql);
216 $statement->execute([
217 $parameters['data']['templateName']
218 ]);
219 $packageID = $statement->fetchSingleRow() ?: 1;
220
221 $parameters['data']['application'] = Package::getAbbreviation(
222 PackageCache::getInstance()->getPackage($packageID)->package
223 );
224 }
225
226 return $parameters;
227 }
228 )
229 );
230 }
231 }
232
233 #[\Override]
a9229942
TD
234 public function readParameters()
235 {
236 parent::readParameters();
a9229942
TD
237 if (!empty($_REQUEST['copy'])) {
238 $this->copy = \intval($_REQUEST['copy']);
239 $this->copiedTemplate = new Template($this->copy);
240 if (!$this->copiedTemplate->templateID) {
241 throw new IllegalLinkException();
242 }
a9229942 243 }
a9229942
TD
244 }
245
fec77826 246 #[\Override]
a9229942
TD
247 public function readData()
248 {
249 parent::readData();
250
fec77826
C
251 if ($_POST === [] && isset($this->copiedTemplate)) {
252 $this->form->getNodeById('templateSource')->value($this->copiedTemplate->getSource());
253 $this->form->getNodeById('templateName')->value($this->copiedTemplate->templateName);
a9229942
TD
254 }
255 }
6570e38e 256}