b4c1d34300e25c9290ba789afad75938688b5702
[GitHub/WoltLab/WCF.git] /
1 <?php
2 namespace wcf\system\package\plugin;
3 use wcf\data\object\type\definition\ObjectTypeDefinitionEditor;
4 use wcf\data\object\type\ObjectTypeCache;
5 use wcf\system\devtools\pip\IDevtoolsPipEntryList;
6 use wcf\system\devtools\pip\IGuiPackageInstallationPlugin;
7 use wcf\system\devtools\pip\TXmlGuiPackageInstallationPlugin;
8 use wcf\system\form\builder\container\FormContainer;
9 use wcf\system\form\builder\field\validation\FormFieldValidationError;
10 use wcf\system\form\builder\field\validation\FormFieldValidator;
11 use wcf\system\form\builder\field\TextFormField;
12 use wcf\system\form\builder\field\validation\FormFieldValidatorUtil;
13 use wcf\system\form\builder\IFormDocument;
14 use wcf\system\WCF;
15
16 /**
17 * Installs, updates and deletes object type definitions.
18 *
19 * @author Alexander Ebert
20 * @copyright 2001-2018 WoltLab GmbH
21 * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
22 * @package WoltLabSuite\Core\Acp\Package\Plugin
23 */
24 class ObjectTypeDefinitionPackageInstallationPlugin extends AbstractXMLPackageInstallationPlugin implements IGuiPackageInstallationPlugin {
25 use TXmlGuiPackageInstallationPlugin;
26
27 /**
28 * @inheritDoc
29 */
30 public $className = ObjectTypeDefinitionEditor::class;
31
32 /**
33 * @inheritDoc
34 */
35 public $tagName = 'definition';
36
37 /**
38 * @inheritDoc
39 */
40 protected function handleDelete(array $items) {
41 $sql = "DELETE FROM wcf".WCF_N."_".$this->tableName."
42 WHERE definitionName = ?
43 AND packageID = ?";
44 $statement = WCF::getDB()->prepareStatement($sql);
45 foreach ($items as $item) {
46 $statement->execute([
47 $item['attributes']['name'],
48 $this->installation->getPackageID()
49 ]);
50 }
51 }
52
53 /**
54 * @inheritDoc
55 */
56 protected function prepareImport(array $data) {
57 return [
58 'interfaceName' => isset($data['elements']['interfacename']) ? $data['elements']['interfacename'] : '',
59 'definitionName' => $data['elements']['name'],
60 'categoryName' => isset($data['elements']['categoryname']) ? $data['elements']['categoryname'] : ''
61 ];
62 }
63
64 /**
65 * @inheritDoc
66 */
67 protected function findExistingItem(array $data) {
68 $sql = "SELECT *
69 FROM wcf".WCF_N."_".$this->tableName."
70 WHERE definitionName = ?";
71 $parameters = [$data['definitionName']];
72
73 return [
74 'sql' => $sql,
75 'parameters' => $parameters
76 ];
77 }
78
79 /**
80 * @inheritDoc
81 * @since 3.1
82 */
83 public static function getSyncDependencies() {
84 return [];
85 }
86
87 /**
88 * @inheritDoc
89 * @since 5.2
90 */
91 protected function addFormFields(IFormDocument $form) {
92 /** @var FormContainer $dataContainer */
93 $dataContainer = $form->getNodeById('data');
94
95 $dataContainer->appendChildren([
96 TextFormField::create('definitionName')
97 ->objectProperty('name')
98 ->label('wcf.acp.pip.objectTypeDefinition.definitionName')
99 ->description('wcf.acp.pip.objectTypeDefinition.definitionName.description', ['project' => $this->installation->getProject()])
100 ->required()
101 ->addValidator(FormFieldValidatorUtil::getDotSeparatedStringValidator(
102 'wcf.acp.pip.objectTypeDefinition.definitionName',
103 4
104 ))
105 ->addValidator(new FormFieldValidator('uniqueness', function(TextFormField $formField) {
106 if ($formField->getValue()) {
107 $objectTypeDefinition = ObjectTypeCache::getInstance()->getDefinitionByName($formField->getValue());
108
109 // the definition name is not unique if such an object type definition
110 // already exists and (a) a new definition is added or (b) an existing
111 // definition is edited but the new definition name is not the old definition
112 // name so that the existing definition is not the definition currently edited
113 if ($objectTypeDefinition !== null && (
114 $formField->getDocument()->getFormMode() === IFormDocument::FORM_MODE_CREATE ||
115 $this->editedEntry->getElementsByTagName('name')->item(0)->nodeValue !== $formField->getValue()
116 )) {
117 $formField->addValidationError(
118 new FormFieldValidationError(
119 'notUnique',
120 'wcf.acp.pip.objectTypeDefinition.definitionName.error.notUnique'
121 )
122 );
123 }
124 }
125 })),
126
127 TextFormField::create('interfaceName')
128 ->objectProperty('interfacename')
129 ->label('wcf.acp.pip.objectTypeDefinition.interfaceName')
130 ->description('wcf.acp.pip.objectTypeDefinition.interfaceName.description')
131 ->addValidator(new FormFieldValidator('interfaceExists', function(TextFormField $formField) {
132 if ($formField->getValue() && !interface_exists($formField->getValue())) {
133 $formField->addValidationError(
134 new FormFieldValidationError(
135 'nonExistent',
136 'wcf.acp.pip.objectTypeDefinition.interfaceName.error.nonExistent'
137 )
138 );
139 }
140 }))
141 ]);
142 }
143
144 /**
145 * @inheritDoc
146 * @since 5.2
147 */
148 protected function fetchElementData(\DOMElement $element, $saveData) {
149 $data = [
150 'definitionName' => $element->getElementsByTagName('name')->item(0)->nodeValue,
151 'packageID' => $this->installation->getPackage()->packageID
152 ];
153
154 $interfaceName = $element->getElementsByTagName('interfacename')->item(0);
155 if ($interfaceName) {
156 $data['interfaceName'] = $interfaceName->nodeValue;
157 }
158 else if ($saveData) {
159 $data['interfaceName'] = '';
160 }
161
162 return $data;
163 }
164
165 /**
166 * @inheritDoc
167 * @since 5.2
168 */
169 public function getElementIdentifier(\DOMElement $element) {
170 return $element->getElementsByTagName('name')->item(0)->nodeValue;
171 }
172
173 /**
174 * @inheritDoc
175 * @since 5.2
176 */
177 protected function setEntryListKeys(IDevtoolsPipEntryList $entryList) {
178 $entryList->setKeys([
179 'definitionName' => 'wcf.acp.pip.objectTypeDefinition.definitionName',
180 'interfaceName' => 'wcf.acp.pip.objectTypeDefinition.interfaceName'
181 ]);
182 }
183
184 /**
185 * @inheritDoc
186 * @since 5.2
187 */
188 protected function prepareXmlElement(\DOMDocument $document, IFormDocument $form) {
189 $definition = $document->createElement($this->tagName);
190
191 $this->appendElementChildren(
192 $definition,
193 [
194 'name',
195 'interfacename' => ''
196 ],
197 $form
198 );
199
200 return $definition;
201 }
202
203 /**
204 * @inheritDoc
205 * @since 5.2
206 */
207 protected function prepareDeleteXmlElement(\DOMElement $element) {
208 $objectTypeDefinition = $element->ownerDocument->createElement($this->tagName);
209 $objectTypeDefinition->setAttribute(
210 'name',
211 $element->getElementsByTagName('name')->item(0)->nodeValue
212 );
213
214 return $objectTypeDefinition;
215 }
216
217 /**
218 * @inheritDoc
219 * @since 5.2
220 */
221 protected function deleteObject(\DOMElement $element) {
222 $this->handleDelete([['attributes' => [
223 'name' => $element->getElementsByTagName('name')->item(0)->nodeValue
224 ]]]);
225 }
226 }