From: Matthias Schmidt Date: Wed, 18 Jul 2018 17:05:58 +0000 (+0200) Subject: Add GUI for clipboardAction package installation plugin X-Git-Tag: 5.2.0_Alpha_1~692 X-Git-Url: https://git.stricted.de/?a=commitdiff_plain;h=a0e1011e509fbe6f7c85a3716e35a3a032301d99;p=GitHub%2FWoltLab%2FWCF.git Add GUI for clipboardAction package installation plugin See #2545 --- diff --git a/wcfsetup/install/files/lib/system/devtools/pip/TXmlGuiPackageInstallationPlugin.class.php b/wcfsetup/install/files/lib/system/devtools/pip/TXmlGuiPackageInstallationPlugin.class.php index 9012bbfe85..8c8bd947c1 100644 --- a/wcfsetup/install/files/lib/system/devtools/pip/TXmlGuiPackageInstallationPlugin.class.php +++ b/wcfsetup/install/files/lib/system/devtools/pip/TXmlGuiPackageInstallationPlugin.class.php @@ -6,6 +6,7 @@ use wcf\data\IEditableCachedObject; use wcf\system\form\builder\field\IFormField; use wcf\system\form\builder\IFormDocument; use wcf\system\form\builder\IFormNode; +use wcf\system\package\PackageInstallationDispatcher; use wcf\system\WCF; use wcf\util\DOMUtil; use wcf\util\StringUtil; @@ -403,6 +404,7 @@ XML; * @param callable $sortFunction */ protected function sortChildNodes(\DOMNodeList $nodeList, callable $sortFunction) { + /** @var \DOMElement $node */ foreach ($nodeList as $node) { $childNodes = array_filter(iterator_to_array($node->childNodes), function($element) { return $element instanceof \DOMElement; diff --git a/wcfsetup/install/files/lib/system/package/plugin/ClipboardActionPackageInstallationPlugin.class.php b/wcfsetup/install/files/lib/system/package/plugin/ClipboardActionPackageInstallationPlugin.class.php index 25c8989dc5..a74ac2db27 100644 --- a/wcfsetup/install/files/lib/system/package/plugin/ClipboardActionPackageInstallationPlugin.class.php +++ b/wcfsetup/install/files/lib/system/package/plugin/ClipboardActionPackageInstallationPlugin.class.php @@ -3,18 +3,32 @@ declare(strict_types=1); namespace wcf\system\package\plugin; use wcf\data\clipboard\action\ClipboardAction; use wcf\data\clipboard\action\ClipboardActionEditor; -use wcf\system\devtools\pip\IIdempotentPackageInstallationPlugin; +use wcf\data\clipboard\action\ClipboardActionList; +use wcf\system\clipboard\action\IClipboardAction; +use wcf\system\devtools\pip\IDevtoolsPipEntryList; +use wcf\system\devtools\pip\IGuiPackageInstallationPlugin; +use wcf\system\devtools\pip\TXmlGuiPackageInstallationPlugin; +use wcf\system\form\builder\container\FormContainer; +use wcf\system\form\builder\field\ClassNameFormField; +use wcf\system\form\builder\field\IntegerFormField; +use wcf\system\form\builder\field\ItemListFormField; +use wcf\system\form\builder\field\TextFormField; +use wcf\system\form\builder\field\validation\FormFieldValidationError; +use wcf\system\form\builder\field\validation\FormFieldValidator; +use wcf\system\form\builder\IFormDocument; use wcf\system\WCF; /** * Installs, updates and deletes clipboard actions. * - * @author Alexander Ebert + * @author Alexander Ebert, Matthias Schmidt * @copyright 2001-2018 WoltLab GmbH * @license GNU Lesser General Public License * @package WoltLabSuite\Core\Acp\Package\Plugin */ -class ClipboardActionPackageInstallationPlugin extends AbstractXMLPackageInstallationPlugin implements IIdempotentPackageInstallationPlugin { +class ClipboardActionPackageInstallationPlugin extends AbstractXMLPackageInstallationPlugin implements IGuiPackageInstallationPlugin { + use TXmlGuiPackageInstallationPlugin; + /** * @inheritDoc */ @@ -151,8 +165,206 @@ class ClipboardActionPackageInstallationPlugin extends AbstractXMLPackageInstall /** * @inheritDoc + * @since 3.1 */ public static function getSyncDependencies() { return []; } + + /** + * @inheritDoc + * @since 3.2 + */ + public function addFormFields(IFormDocument $form) { + /** @var FormContainer $dataContainer */ + $dataContainer = $form->getNodeById('data'); + + $dataContainer->appendChildren([ + TextFormField::create('actionName') + ->objectProperty('name') + ->label('wcf.acp.pip.clipboardAction.actionName') + ->description('wcf.acp.pip.clipboardAction.actionName.description') + ->required() + ->addValidator(new FormFieldValidator('format', function(TextFormField $formField) { + if (!preg_match('~^[a-z][A-z]+$~', $formField->getValue())) { + $formField->addValidationError( + new FormFieldValidationError( + 'format', + 'wcf.acp.pip.clipboardAction.actionName.error.format' + ) + ); + } + })), + + ClassNameFormField::create('actionClassName') + ->label('wcf.acp.pip.clipboardAction.actionClassName') + ->objectProperty('actionclassname') + ->required() + ->implementedInterface(IClipboardAction::class) + ->addValidator(new FormFieldValidator('uniqueness', function(ClassNameFormField $formField) { + /** @var TextFormField $actionNameFormField */ + $actionNameFormField = $formField->getDocument()->getNodeById('actionName'); + + if ( + $formField->getDocument()->getFormMode() === IFormDocument::FORM_MODE_CREATE || + ( + $this->editedEntry->getAttribute('name') !== $actionNameFormField->getSaveValue() || + $this->editedEntry->getElementsByTagName('actionclassname')->item(0)->nodeValue !== $formField->getSaveValue() + ) + ) { + $clipboardActionList = new ClipboardActionList(); + $clipboardActionList->getConditionBuilder()->add('actionName = ?', [$actionNameFormField->getSaveValue()]); + $clipboardActionList->getConditionBuilder()->add('actionClassName = ?', [$formField->getSaveValue()]); + + if ($clipboardActionList->countObjects() > 0) { + $actionNameFormField->addValidationError( + new FormFieldValidationError( + 'notUnique', + 'wcf.acp.pip.clipboardAction.actionClassName.error.notUnique' + ) + ); + } + } + })), + + IntegerFormField::create('showOrder') + ->objectProperty('showorder') + ->label('wcf.acp.pip.clipboardAction.showOrder') + ->description('wcf.acp.pip.clipboardAction.showOrder.description') + ->nullable(), + + ItemListFormField::create('pages') + ->label('wcf.acp.pip.clipboardAction.pages') + ->description('wcf.acp.pip.clipboardAction.pages.description') + ->saveValueType(ItemListFormField::SAVE_VALUE_TYPE_ARRAY) + ->required() + ]); + } + + /** + * @inheritDoc + * @since 3.2 + */ + protected function getElementData(\DOMElement $element, bool $saveData = false): array { + $data = [ + 'actionClassName' => $element->getElementsByTagName('actionclassname')->item(0)->nodeValue, + 'actionName' => $element->getAttribute('name'), + 'packageID' => $this->installation->getPackage()->packageID, + 'pages' => [] + ]; + + $showOrder = $element->getElementsByTagName('showorder')->item(0); + if ($showOrder !== null) { + $data['showOrder'] = $showOrder->nodeValue; + } + + /** @var \DOMElement $page */ + foreach ($element->getElementsByTagName('pages')->item(0)->childNodes as $page) { + if ($page->nodeName === 'page') { + $data['pages'][] = $page->nodeValue; + } + } + + if (!$saveData) { + $data['pages'] = implode(',', $data['pages']); + } + + return $data; + } + + /** + * @inheritDoc + * @since 3.2 + */ + public function getElementIdentifier(\DOMElement $element): string { + return sha1( + $element->getElementsByTagName('actionclassname')->item(0)->nodeValue . '/' . + $element->getAttribute('name') + ); + } + + /** + * @inheritDoc + * @since 3.2 + */ + protected function setEntryListKeys(IDevtoolsPipEntryList $entryList) { + $entryList->setKeys([ + 'actionName' => 'wcf.acp.pip.clipboardAction.actionName', + 'actionClassName' => 'wcf.acp.pip.clipboardAction.actionClassName' + ]); + } + + /** + * @inheritDoc + * @since 3.2 + */ + protected function sortDocument(\DOMDocument $document) { + $this->sortImportDelete($document); + + $sortFunction = function(\DOMElement $element1, \DOMElement $element2) { + $className1 = $element1->getElementsByTagName('actionclassname')->item(0)->nodeValue; + $className2 = $element2->getElementsByTagName('actionclassname')->item(0)->nodeValue; + + $compare = strcmp($className1, $className2); + + if ($compare !== 0) { + return $compare; + } + + $showOrder1 = $element1->getElementsByTagName('showorder')->item(0); + $showOrder2 = $element2->getElementsByTagName('showorder')->item(0); + + if ($showOrder1 !== null) { + if ($showOrder2 !== null) { + $compare = $showOrder1->nodeValue <=> $showOrder2->nodeValue; + + if ($compare !== 0) { + return $compare; + } + } + + return -1; + } + else if ($showOrder2 !== null) { + return 1; + } + + return strcmp( + $element1->getAttribute('name'), + $element2->getAttribute('name') + ); + }; + + $this->sortChildNodes($document->getElementsByTagName('import'), $sortFunction); + $this->sortChildNodes($document->getElementsByTagName('delete'), $sortFunction); + } + + /** + * @inheritDoc + * @since 3.2 + */ + protected function writeEntry(\DOMDocument $document, IFormDocument $form): \DOMElement { + $formData = $form->getData(); + $data = $formData['data']; + + $clipboardAction = $document->createElement($this->tagName); + $clipboardAction->setAttribute('name', $data['name']); + + $clipboardAction->appendChild($document->createElement('actionclassname', $data['actionclassname'])); + + if (!empty($data['showorder'])) { + $clipboardAction->appendChild($document->createElement('showorder', (string)$data['showorder'])); + } + + $pages = $document->createElement('pages'); + $clipboardAction->appendChild($pages); + + foreach ($formData['pages'] as $page) { + $pages->appendChild($document->createElement('page', $page)); + } + + $document->getElementsByTagName('import')->item(0)->appendChild($clipboardAction); + + return $clipboardAction; + } } diff --git a/wcfsetup/install/lang/en.xml b/wcfsetup/install/lang/en.xml index fd4e723755..1771515198 100644 --- a/wcfsetup/install/lang/en.xml +++ b/wcfsetup/install/lang/en.xml @@ -2049,6 +2049,15 @@ If you have already bought the licenses for the listed apps, th + + + + + + + + +