Commit | Line | Data |
---|---|---|
6570e38e | 1 | <?php |
a9229942 | 2 | |
6570e38e | 3 | namespace wcf\acp\form; |
a9229942 | 4 | |
fec77826 | 5 | use wcf\data\IStorableObject; |
e568316b MS |
6 | use wcf\data\package\Package; |
7 | use wcf\data\package\PackageCache; | |
6570e38e | 8 | use wcf\data\template\group\TemplateGroup; |
fec77826 | 9 | use wcf\data\template\group\TemplateGroupNodeTree; |
6570e38e MW |
10 | use wcf\data\template\Template; |
11 | use wcf\data\template\TemplateAction; | |
fec77826 C |
12 | use wcf\form\AbstractFormBuilderForm; |
13 | use wcf\system\cache\builder\TemplateGroupCacheBuilder; | |
dd1bae1b | 14 | use wcf\system\database\util\PreparedStatementConditionBuilder; |
43a250e6 | 15 | use wcf\system\exception\IllegalLinkException; |
fec77826 C |
16 | use wcf\system\form\builder\container\FormContainer; |
17 | use wcf\system\form\builder\data\processor\CustomFormDataProcessor; | |
18 | use wcf\system\form\builder\data\processor\VoidFormDataProcessor; | |
19 | use wcf\system\form\builder\field\HiddenFormField; | |
fec77826 | 20 | use wcf\system\form\builder\field\SingleSelectionFormField; |
59e1e354 | 21 | use wcf\system\form\builder\field\SourceCodeFormField; |
fec77826 C |
22 | use wcf\system\form\builder\field\TextFormField; |
23 | use wcf\system\form\builder\field\validation\FormFieldValidationError; | |
24 | use wcf\system\form\builder\field\validation\FormFieldValidator; | |
25 | use wcf\system\form\builder\IFormDocument; | |
df8845ad | 26 | use wcf\system\template\TemplateEngine; |
6570e38e | 27 | use 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 | 36 | class 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 | } |