diff --git a/.github/workflows/gradle.yml b/.github/workflows/gradle.yml index 94244ea64..6f92519b8 100644 --- a/.github/workflows/gradle.yml +++ b/.github/workflows/gradle.yml @@ -5,7 +5,7 @@ name: Run automated tests on: pull_request: - branches: [ master, 4.3.0-develop ] + branches: [ master, '*-develop', 'mainline*' ] jobs: build-linux: @@ -107,6 +107,7 @@ jobs: run: ./gradlew checkstyleCI -i --no-daemon env: MODIFIED_FILES: ${{ steps.file_changes.outputs.files}} + ACTIONS_STEP_DEBUG: true - name: Run PMD Quality Check run: ./gradlew pmdCI -i --no-daemon env: diff --git a/resources/META-INF/plugin.xml b/resources/META-INF/plugin.xml index 74c52dbff..81a8e1e67 100644 --- a/resources/META-INF/plugin.xml +++ b/resources/META-INF/plugin.xml @@ -101,6 +101,14 @@ + + + + + + + + @@ -200,6 +208,7 @@ + diff --git a/resources/fileTemplates/code/Magento Category Admin Form XML Decoration.xml.ft b/resources/fileTemplates/code/Magento Category Admin Form XML Decoration.xml.ft new file mode 100644 index 000000000..09ce53202 --- /dev/null +++ b/resources/fileTemplates/code/Magento Category Admin Form XML Decoration.xml.ft @@ -0,0 +1,7 @@ +#if(${INCLUDE_FIELDSET}) +
+#end + +#if(${INCLUDE_FIELDSET}) +
+#end \ No newline at end of file diff --git a/resources/fileTemplates/internal/Magento Category Admin Form XML.xml.ft b/resources/fileTemplates/internal/Magento Category Admin Form XML.xml.ft new file mode 100644 index 000000000..ffe195975 --- /dev/null +++ b/resources/fileTemplates/internal/Magento Category Admin Form XML.xml.ft @@ -0,0 +1,4 @@ + +
+
diff --git a/resources/fileTemplates/internal/Magento Customer Eav Attribute Data Patch Class.php.ft b/resources/fileTemplates/internal/Magento Customer Eav Attribute Data Patch Class.php.ft new file mode 100644 index 000000000..52d51a592 --- /dev/null +++ b/resources/fileTemplates/internal/Magento Customer Eav Attribute Data Patch Class.php.ft @@ -0,0 +1,122 @@ +moduleDataSetup = $moduleDataSetup; + $this->eavSetupFactory = $eavSetupFactory; + $this->eavConfig = $eavConfig; + $this->attributeResource = $attributeResource; + } + + /** + * Run code inside patch + * If code fails, patch must be reverted, in case when we are speaking about schema - then under revert + * means run PatchInterface::revert() + * + * If we speak about data, under revert means: $transaction->rollback() + * + * @return $this + */ + public function apply() + { +/** @var ${EAV_SETUP} $eavSetup */ + $eavSetup = $this->eavSetupFactory->create(['setup' => $this->moduleDataSetup]); + + $eavSetup->addAttribute( + ${ENTITY_CLASS}::ENTITY, + '${ATTRIBUTE_CODE}', + [ + #set ($attributeSet = ${ATTRIBUTE_SET}) + #foreach ($attribute in $attributeSet.split("->")) + $attribute + #end +] + ); + + $eavSetup->addAttributeToSet( + ${CUSTOMER_METADATA_INTERFACE}::ENTITY_TYPE_CUSTOMER, + ${CUSTOMER_METADATA_INTERFACE}::ATTRIBUTE_SET_ID_CUSTOMER, + null, + '${ATTRIBUTE_CODE}' + ); + + #if (${CUSTOMER_FORMS}) + $attribute = $this->eavConfig->getAttribute(${ENTITY_CLASS}::ENTITY, '${ATTRIBUTE_CODE}'); + $attribute->setData( + 'used_in_forms', + [${CUSTOMER_FORMS}] + ); + $this->attributeResource->save($attribute); + #end + + return $this; + } + + /** + * Get array of patches that have to be executed prior to this. + * + * Example of implementation: + * + * [ + * \Vendor_Name\Module_Name\Setup\Patch\Patch1::class, + * \Vendor_Name\Module_Name\Setup\Patch\Patch2::class + * ] + * + * @return string[] + */ + public static function getDependencies() + { + return []; + } + + /** + * Get aliases (previous names) for the patch. + * + * @return string[] + */ + public function getAliases() + { + return []; + } +} diff --git a/resources/fileTemplates/internal/Magento Customer Eav Attribute Data Patch Class.php.html b/resources/fileTemplates/internal/Magento Customer Eav Attribute Data Patch Class.php.html new file mode 100644 index 000000000..0a2028f8b --- /dev/null +++ b/resources/fileTemplates/internal/Magento Customer Eav Attribute Data Patch Class.php.html @@ -0,0 +1,15 @@ + + + + +

+ Data patch for the customer EAV attribute +

+
+ + \ No newline at end of file diff --git a/resources/fileTemplates/internal/Magento Eav Attribute Data Patch Class.php.ft b/resources/fileTemplates/internal/Magento Eav Attribute Data Patch Class.php.ft new file mode 100644 index 000000000..7c6813869 --- /dev/null +++ b/resources/fileTemplates/internal/Magento Eav Attribute Data Patch Class.php.ft @@ -0,0 +1,87 @@ +moduleDataSetup = $moduleDataSetup; + $this->eavSetupFactory = $eavSetupFactory; + } + + /** + * Run code inside patch + * If code fails, patch must be reverted, in case when we are speaking about schema - then under revert + * means run PatchInterface::revert() + * + * If we speak about data, under revert means: $transaction->rollback() + */ + public function apply() + { + /** @var ${EAV_SETUP} $eavSetup */ + $eavSetup = $this->eavSetupFactory->create(['setup' => $this->moduleDataSetup]); + + $eavSetup->addAttribute( + ${ENTITY_CLASS}::ENTITY, + '${ATTRIBUTE_CODE}', + [ + #set ($attributeSet = ${ATTRIBUTE_SET}) + #foreach ($attribute in $attributeSet.split("->")) + $attribute + #end +] + ); + } + + /** + * Get array of patches that have to be executed prior to this. + * + * Example of implementation: + * + * [ + * \Vendor_Name\Module_Name\Setup\Patch\Patch1::class, + * \Vendor_Name\Module_Name\Setup\Patch\Patch2::class + * ] + * + * @return string[] + */ + public static function getDependencies() + { + return []; + } + + /** + * Get aliases (previous names) for the patch. + * + * @return string[] + */ + public function getAliases() + { + return []; + } +} diff --git a/resources/fileTemplates/internal/Magento Source Model Class.php.ft b/resources/fileTemplates/internal/Magento Source Model Class.php.ft new file mode 100644 index 000000000..108281c0e --- /dev/null +++ b/resources/fileTemplates/internal/Magento Source Model Class.php.ft @@ -0,0 +1,22 @@ + options; + private Map optionsSortOrder; + + @Override + public void setCode(final String code) { + this.code = code; + } + + @Override + public void setType(final String type) { + this.type = type; + } + + @Override + public void setLabel(final String label) { + this.label = label; + } + + @Override + public void setInput(final String input) { + this.input = input; + } + + @Override + public void setNamespace(final String namespace) { + this.namespace = namespace; + } + + @Override + public void setModuleName(final String moduleName) { + this.moduleName = moduleName; + } + + @Override + public void setDirectory(final String directory) { + this.directory = directory; + } + + @Override + public void setDataPatchName(final String dataPatchName) { + this.dataPatchName = dataPatchName; + } + + @Override + public void setSource(final String source) { + this.source = source; + } + + @Override + public void setSortOrder(final int sortOrder) { + this.sortOrder = sortOrder; + } + + @Override + public void setOptions(final Map options) { + this.options = options; + } + + @Override + public void setOptionsSortOrder(final Map optionsSortOrder) { + this.optionsSortOrder = optionsSortOrder; + } + + @Override + public void setRequired(final boolean required) { + this.required = required; + } + + @Override + public void setVisible(final boolean visible) { + this.visible = visible; + } + + @Override + public void setBackendModel(final String model) { + this.backendModel = model; + } + + public void setGroup(final String group) { + this.group = group; + } + + public void setScope(final String scope) { + this.scope = scope; + } + + @Override + public String getCode() { + return code; + } + + @Override + public String getType() { + return type; + } + + @Override + public String getLabel() { + return label; + } + + @Override + public String getInput() { + return input; + } + + @Override + public String getNamespace() { + return namespace; + } + + @Override + public String getModuleName() { + return moduleName; + } + + @Override + public String getDirectory() { + return directory; + } + + @Override + public String getDataPatchName() { + return dataPatchName; + } + + @Override + public String getEntityClass() { + return EavEntity.CATEGORY.getEntityClass(); + } + + @Override + public String getSource() { + return source; + } + + @Override + public String getBackendModel() { + return backendModel; + } + + @Override + public int getSortOrder() { + return sortOrder; + } + + @Override + public Map getOptions() { + return options; + } + + @Override + public Map getOptionsSortOrder() { + return optionsSortOrder; + } + + @Override + public boolean isRequired() { + return this.required; + } + + @Override + public boolean isVisible() { + return this.visible; + } + + public String getGroup() { + return group; + } + + public String getScope() { + return scope; + } +} diff --git a/src/com/magento/idea/magento2plugin/actions/generation/data/CategoryFormXmlData.java b/src/com/magento/idea/magento2plugin/actions/generation/data/CategoryFormXmlData.java new file mode 100644 index 000000000..7598502e3 --- /dev/null +++ b/src/com/magento/idea/magento2plugin/actions/generation/data/CategoryFormXmlData.java @@ -0,0 +1,58 @@ +/* + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + * + */ + +package com.magento.idea.magento2plugin.actions.generation.data; + +import org.jetbrains.annotations.NotNull; + +public class CategoryFormXmlData { + private final String fieldSetName; + private final String fieldName; + private final String attributeInput; + private final int sortOrder; + + /** + * Category Form data class. + * + * @param fieldSetName name of the fieldset + * @param fieldName field name + * @param attributeInput attribute input + * @param sortOrder sort order + */ + public CategoryFormXmlData( + @NotNull final String fieldSetName, + @NotNull final String fieldName, + @NotNull final String attributeInput, + @NotNull final int sortOrder + ) { + this.fieldSetName = convertGroupNameToFieldSet(fieldSetName); + this.fieldName = fieldName; + this.attributeInput = attributeInput; + this.sortOrder = sortOrder; + } + + private String convertGroupNameToFieldSet(final String groupName) { + final String[] nameParts = groupName.toLowerCase().split(" ");//NOPMD + + return String.join("_", nameParts); + } + + public String getFieldSetName() { + return fieldSetName; + } + + public String getFieldName() { + return fieldName; + } + + public int getSortOrder() { + return sortOrder; + } + + public String getAttributeInput() { + return attributeInput; + } +} diff --git a/src/com/magento/idea/magento2plugin/actions/generation/data/CustomerEntityData.java b/src/com/magento/idea/magento2plugin/actions/generation/data/CustomerEntityData.java new file mode 100644 index 000000000..db45bf7c7 --- /dev/null +++ b/src/com/magento/idea/magento2plugin/actions/generation/data/CustomerEntityData.java @@ -0,0 +1,269 @@ +/* + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +package com.magento.idea.magento2plugin.actions.generation.data; + +import com.magento.idea.magento2plugin.magento.packages.eav.EavEntity; +import java.util.Map; + +@SuppressWarnings({"PMD.TooManyFields", "PMD.ExcessivePublicCount"}) +public class CustomerEntityData implements EavEntityDataInterface { + + private String code; + private String type; + private String label; + private String input; + private String namespace; + private String moduleName; + private String directory; + private String dataPatchName; + private String source; + private int sortOrder; + private Map options; + private String model; + private Map optionsSortOrder; + private boolean required; + private boolean visible; + private boolean userDefined; + private boolean useInAdminhtmlCustomerForm; + private boolean useInAdminhtmlCheckoutForm; + private boolean useInCustomerAccountCreateForm; + private boolean useInCustomerAccountEditForm; + private boolean usedInGrid; + private boolean visibleInGrid; + private boolean filterableInGrid; + private boolean system; + + @Override + public void setCode(final String code) { + this.code = code; + } + + @Override + public void setType(final String type) { + this.type = type; + } + + @Override + public void setLabel(final String label) { + this.label = label; + } + + @Override + public void setInput(final String input) { + this.input = input; + } + + @Override + public void setNamespace(final String namespace) { + this.namespace = namespace; + } + + @Override + public void setModuleName(final String moduleName) { + this.moduleName = moduleName; + } + + @Override + public void setDirectory(final String directory) { + this.directory = directory; + } + + @Override + public void setDataPatchName(final String dataPatchName) { + this.dataPatchName = dataPatchName; + } + + @Override + public void setSource(final String source) { + this.source = source; + } + + @Override + public void setSortOrder(final int sortOrder) { + this.sortOrder = sortOrder; + } + + @Override + public void setOptions(final Map options) { + this.options = options; + } + + @Override + public void setOptionsSortOrder(final Map optionsSortOrder) { + this.optionsSortOrder = optionsSortOrder; + } + + @Override + public void setRequired(final boolean required) { + this.required = required; + } + + @Override + public void setVisible(final boolean visible) { + this.visible = visible; + } + + @Override + public void setBackendModel(final String model) { + this.model = model; + } + + public void setUserDefined(final boolean userDefined) { + this.userDefined = userDefined; + } + + public void setUseInAdminhtmlCustomerForm(final boolean useInAdminhtmlCustomerForm) { + this.useInAdminhtmlCustomerForm = useInAdminhtmlCustomerForm; + } + + public void setUseInAdminhtmlCheckoutForm(final boolean useInAdminhtmlCheckoutForm) { + this.useInAdminhtmlCheckoutForm = useInAdminhtmlCheckoutForm; + } + + public void setUseInCustomerAccountCreateForm(final boolean useInCustomerAccountCreateForm) { + this.useInCustomerAccountCreateForm = useInCustomerAccountCreateForm; + } + + public void setUseInCustomerAccountEditForm(final boolean useInCustomerAccountEditForm) { + this.useInCustomerAccountEditForm = useInCustomerAccountEditForm; + } + + public void setUsedInGrid(final boolean usedInGrid) { + this.usedInGrid = usedInGrid; + } + + public void setVisibleInGrid(final boolean visibleInGrid) { + this.visibleInGrid = visibleInGrid; + } + + public void setFilterableInGrid(final boolean filterableInGrid) { + this.filterableInGrid = filterableInGrid; + } + + public void setSystem(final boolean system) { + this.system = system; + } + + @Override + public String getCode() { + return code; + } + + @Override + public String getType() { + return type; + } + + @Override + public String getLabel() { + return label; + } + + @Override + public String getInput() { + return input; + } + + @Override + public String getNamespace() { + return namespace; + } + + @Override + public String getModuleName() { + return moduleName; + } + + @Override + public String getDirectory() { + return directory; + } + + @Override + public String getDataPatchName() { + return dataPatchName; + } + + @Override + public String getEntityClass() { + return EavEntity.CUSTOMER.getEntityClass(); + } + + @Override + public String getSource() { + return source; + } + + @Override + public String getBackendModel() { + return null; + } + + @Override + public int getSortOrder() { + return sortOrder; + } + + @Override + public Map getOptions() { + return options; + } + + public String getModel() { + return model; + } + + @Override + public Map getOptionsSortOrder() { + return optionsSortOrder; + } + + @Override + public boolean isRequired() { + return required; + } + + @Override + public boolean isVisible() { + return visible; + } + + public boolean isUserDefined() { + return userDefined; + } + + public boolean isUseInAdminhtmlCustomerForm() { + return useInAdminhtmlCustomerForm; + } + + public boolean isUseInAdminhtmlCheckoutForm() { + return useInAdminhtmlCheckoutForm; + } + + public boolean isUseInCustomerAccountCreateForm() { + return useInCustomerAccountCreateForm; + } + + public boolean isUseInCustomerAccountEditForm() { + return useInCustomerAccountEditForm; + } + + public boolean isUsedInGrid() { + return usedInGrid; + } + + public boolean isVisibleInGrid() { + return visibleInGrid; + } + + public boolean isFilterableInGrid() { + return filterableInGrid; + } + + public boolean isSystem() { + return system; + } +} diff --git a/src/com/magento/idea/magento2plugin/actions/generation/data/EavEntityDataInterface.java b/src/com/magento/idea/magento2plugin/actions/generation/data/EavEntityDataInterface.java new file mode 100644 index 000000000..f25f64f68 --- /dev/null +++ b/src/com/magento/idea/magento2plugin/actions/generation/data/EavEntityDataInterface.java @@ -0,0 +1,74 @@ +/* + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +package com.magento.idea.magento2plugin.actions.generation.data; + +import java.util.Map; + +@SuppressWarnings({"PMD.UnnecessaryModifier"}) +public interface EavEntityDataInterface { + + void setCode(final String code); + + void setType(final String type); + + void setLabel(final String label); + + void setInput(final String input); + + void setNamespace(final String namespace); + + void setModuleName(final String moduleName); + + void setDirectory(final String directory); + + void setDataPatchName(final String dataPatchName); + + void setSource(final String source); + + void setSortOrder(final int sortOrder); + + void setOptions(final Map options); + + void setOptionsSortOrder(final Map optionsSortOrder); + + void setRequired(final boolean required); + + void setVisible(final boolean visible); + + void setBackendModel(final String model); + + String getCode(); + + String getType(); + + String getLabel(); + + String getInput(); + + String getNamespace(); + + String getModuleName(); + + String getDirectory(); + + String getDataPatchName(); + + String getEntityClass(); + + String getSource(); + + String getBackendModel(); + + int getSortOrder(); + + Map getOptions(); + + Map getOptionsSortOrder(); + + boolean isRequired(); + + boolean isVisible(); +} diff --git a/src/com/magento/idea/magento2plugin/actions/generation/data/ProductEntityData.java b/src/com/magento/idea/magento2plugin/actions/generation/data/ProductEntityData.java new file mode 100644 index 000000000..99ac0b70d --- /dev/null +++ b/src/com/magento/idea/magento2plugin/actions/generation/data/ProductEntityData.java @@ -0,0 +1,275 @@ +/* + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +package com.magento.idea.magento2plugin.actions.generation.data; + +import com.magento.idea.magento2plugin.magento.files.EavAttributeDataPatchFile; +import com.magento.idea.magento2plugin.magento.packages.eav.EavEntity; +import java.util.Map; + +@SuppressWarnings({"PMD.TooManyFields", "PMD.ExcessivePublicCount"}) +public class ProductEntityData implements EavEntityDataInterface { + private String group; + private String code; + private String type; + private String label; + private String input; + private String source; + private String scope; + private String applyTo; + private String backendModel; + private boolean required; + private boolean usedInGrid; + private boolean visibleInGrid; + private boolean filterableInGrid; + private boolean visible; + private boolean htmlAllowedOnFront; + private boolean visibleOnFront; + private int sortOrder; + private Map options; + private Map optionsSortOrder; + + private String dataPatchName; + private String namespace; + private String directory; + private String moduleName; + + /** + * Constructor. + */ + public ProductEntityData() { + this.required = false; + this.usedInGrid = false; + this.visibleInGrid = false; + this.filterableInGrid = false; + this.visible = true; + this.htmlAllowedOnFront = false; + this.visibleOnFront = false; + this.sortOrder = 0; + } + + public void setGroup(final String group) { + this.group = group; + } + + @Override + public void setCode(final String code) { + this.code = code; + } + + @Override + public void setType(final String type) { + this.type = type; + } + + @Override + public void setLabel(final String label) { + this.label = label; + } + + @Override + public void setInput(final String input) { + this.input = input; + } + + @Override + public void setSource(final String source) { + this.source = source; + } + + public void setScope(final String scope) { + this.scope = scope; + } + + public void setApplyTo(final String applyTo) { + this.applyTo = applyTo; + } + + @Override + public void setRequired(final boolean required) { + this.required = required; + } + + public void setUsedInGrid(final boolean usedInGrid) { + this.usedInGrid = usedInGrid; + } + + public void setVisibleInGrid(final boolean visibleInGrid) { + this.visibleInGrid = visibleInGrid; + } + + public void setFilterableInGrid(final boolean filterableInGrid) { + this.filterableInGrid = filterableInGrid; + } + + @Override + public void setVisible(final boolean visible) { + this.visible = visible; + } + + @Override + public void setBackendModel(final String model) { + this.backendModel = model; + } + + public void setHtmlAllowedOnFront(final boolean htmlAllowedOnFront) { + this.htmlAllowedOnFront = htmlAllowedOnFront; + } + + public void setVisibleOnFront(final boolean visibleOnFront) { + this.visibleOnFront = visibleOnFront; + } + + @Override + public void setSortOrder(final int sortOrder) { + this.sortOrder = sortOrder; + } + + @Override + public void setDataPatchName(final String dataPatchName) { + this.dataPatchName = dataPatchName; + } + + @Override + public void setNamespace(final String namespace) { + this.namespace = namespace; + } + + @Override + public void setDirectory(final String directory) { + this.directory = directory; + } + + @Override + public void setModuleName(final String moduleName) { + this.moduleName = moduleName; + } + + @Override + public void setOptions(final Map options) { + this.options = options; + } + + @Override + public void setOptionsSortOrder(final Map optionsSortOrder) { + this.optionsSortOrder = optionsSortOrder; + } + + @Override + public Map getOptions() { + return options; + } + + @Override + public Map getOptionsSortOrder() { + return optionsSortOrder; + } + + @Override + public String getCode() { + return code; + } + + @Override + public String getType() { + return type; + } + + @Override + public String getLabel() { + return label; + } + + @Override + public String getInput() { + return input; + } + + @Override + public String getNamespace() { + return namespace; + } + + @Override + public String getModuleName() { + return moduleName; + } + + @Override + public String getDirectory() { + if (directory == null) { + directory = EavAttributeDataPatchFile.DEFAULT_DIR; + } + + return directory; + } + + @Override + public String getDataPatchName() { + return dataPatchName; + } + + @Override + public String getEntityClass() { + return EavEntity.PRODUCT.getEntityClass(); + } + + public String getGroup() { + return group; + } + + @Override + public String getSource() { + return source; + } + + @Override + public String getBackendModel() { + return backendModel; + } + + public String getScope() { + return scope; + } + + public String getApplyTo() { + return applyTo; + } + + @Override + public boolean isRequired() { + return required; + } + + public boolean isUsedInGrid() { + return usedInGrid; + } + + public boolean isVisibleInGrid() { + return visibleInGrid; + } + + public boolean isFilterableInGrid() { + return filterableInGrid; + } + + @Override + public boolean isVisible() { + return visible; + } + + public boolean isHtmlAllowedOnFront() { + return htmlAllowedOnFront; + } + + public boolean isVisibleOnFront() { + return visibleOnFront; + } + + @Override + public int getSortOrder() { + return sortOrder; + } +} diff --git a/src/com/magento/idea/magento2plugin/actions/generation/data/SourceModelData.java b/src/com/magento/idea/magento2plugin/actions/generation/data/SourceModelData.java new file mode 100644 index 000000000..c5c1b862e --- /dev/null +++ b/src/com/magento/idea/magento2plugin/actions/generation/data/SourceModelData.java @@ -0,0 +1,52 @@ +/* + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +package com.magento.idea.magento2plugin.actions.generation.data; + +import com.magento.idea.magento2plugin.magento.files.SourceModelFile; + +public class SourceModelData { + private String className; + private String moduleName; + private String directory; + + public String getClassName() { + return className; + } + + /** + * Get default namespace. + * + * @return String + */ + public String getModuleName() { + return moduleName; + } + + /** + * Get directory path. + * + * @return String + */ + public String getDirectory() { + if (this.directory == null) { + return SourceModelFile.DEFAULT_DIR; + } + + return this.directory; + } + + public void setClassName(final String className) { + this.className = className; + } + + public void setModuleName(final String moduleName) { + this.moduleName = moduleName; + } + + public void setDirectory(final String directory) { + this.directory = directory; + } +} diff --git a/src/com/magento/idea/magento2plugin/actions/generation/dialog/NewCategoryEavAttributeDialog.form b/src/com/magento/idea/magento2plugin/actions/generation/dialog/NewCategoryEavAttributeDialog.form new file mode 100644 index 000000000..09e1bdc5a --- /dev/null +++ b/src/com/magento/idea/magento2plugin/actions/generation/dialog/NewCategoryEavAttributeDialog.form @@ -0,0 +1,425 @@ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/src/com/magento/idea/magento2plugin/actions/generation/dialog/NewCategoryEavAttributeDialog.java b/src/com/magento/idea/magento2plugin/actions/generation/dialog/NewCategoryEavAttributeDialog.java new file mode 100644 index 000000000..494e5c28e --- /dev/null +++ b/src/com/magento/idea/magento2plugin/actions/generation/dialog/NewCategoryEavAttributeDialog.java @@ -0,0 +1,274 @@ +/* + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +package com.magento.idea.magento2plugin.actions.generation.dialog; + +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiDirectory; +import com.magento.idea.magento2plugin.actions.generation.data.CategoryEntityData; +import com.magento.idea.magento2plugin.actions.generation.data.CategoryFormXmlData; +import com.magento.idea.magento2plugin.actions.generation.data.EavEntityDataInterface; +import com.magento.idea.magento2plugin.actions.generation.data.ui.ComboBoxItemData; +import com.magento.idea.magento2plugin.actions.generation.dialog.eavattribute.EavAttributeDialog; +import com.magento.idea.magento2plugin.actions.generation.dialog.util.eavdialog.AttributeUtil; +import com.magento.idea.magento2plugin.actions.generation.dialog.validator.annotation.FieldValidation; +import com.magento.idea.magento2plugin.actions.generation.dialog.validator.annotation.RuleRegistry; +import com.magento.idea.magento2plugin.actions.generation.dialog.validator.rule.Lowercase; +import com.magento.idea.magento2plugin.actions.generation.dialog.validator.rule.NotEmptyRule; +import com.magento.idea.magento2plugin.actions.generation.generator.CategoryFormXmlGenerator; +import com.magento.idea.magento2plugin.magento.packages.eav.AttributeScope; +import javax.swing.JButton; +import javax.swing.JCheckBox; +import javax.swing.JComboBox; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JTable; +import javax.swing.JTextField; + +@SuppressWarnings({ + "PMD.TooManyFields", + "PMD.ExcessiveImports", + "PMD.TooManyMethods", + "PMD.UnusedPrivateField" +}) +public class NewCategoryEavAttributeDialog extends EavAttributeDialog { + + private static final String ENTITY_NAME = "Category"; + private JPanel contentPanel; + private JButton buttonOK; + private JButton buttonCancel; + @FieldValidation(rule = RuleRegistry.NOT_EMPTY, + message = {NotEmptyRule.MESSAGE, "Attribute Code"}) + @FieldValidation(rule = RuleRegistry.LOWERCASE, + message = {Lowercase.MESSAGE, "Attribute Code"}) + private JTextField codeTextField; + @FieldValidation(rule = RuleRegistry.NOT_EMPTY, + message = {NotEmptyRule.MESSAGE, "Attribute Label"}) + private JTextField labelTextField; + @FieldValidation(rule = RuleRegistry.NOT_EMPTY, + message = {NotEmptyRule.MESSAGE, "Attribute Group"}) + private JTextField groupTextField; + @FieldValidation(rule = RuleRegistry.NOT_EMPTY, + message = {NotEmptyRule.MESSAGE, "Data Patch Name"}) + private JTextField dataPatchNameTextField; + @FieldValidation(rule = RuleRegistry.NOT_EMPTY, + message = {NotEmptyRule.MESSAGE, "Attribute Sort Order"}) + @FieldValidation(rule = RuleRegistry.ALPHANUMERIC, + message = {NotEmptyRule.MESSAGE, "Attribute Sort Order"}) + private JTextField sortOrderTextField; + private JComboBox inputComboBox; + private JComboBox typeComboBox; + private JComboBox scopeComboBox; + private JComboBox sourceComboBox; + private JCheckBox requiredCheckBox; + private JCheckBox visibleCheckBox; + private JPanel sourcePanel; + private JPanel customSourceModelPanel; + @FieldValidation(rule = RuleRegistry.NOT_EMPTY, + message = {NotEmptyRule.MESSAGE, "Source Model Directory"}) + private JTextField sourceModelDirectoryTextField; + @FieldValidation(rule = RuleRegistry.NOT_EMPTY, + message = {NotEmptyRule.MESSAGE, "Source Model Name"}) + private JTextField sourceModelNameTextField; + private JTable optionsTable; + private JButton addNewOptionButton; + private JPanel optionsPanel; + private JLabel codeTextFieldErrorMessage; + private JLabel labelTextFieldErrorMessage; + private JLabel dataPatchNameTextFieldErrorMessage; + private JLabel groupTextFieldErrorMessage; + private JLabel sourceModelDirectoryTextFieldErrorMessage; + private JLabel sourceModelNameTextFieldErrorMessage; + private JLabel sortOrderTextFieldErrorMessage; + + /** + * Constructor. + * + * @param project Project + * @param directory PsiDirectory + * @param actionName String + */ + public NewCategoryEavAttributeDialog( + final Project project, + final PsiDirectory directory, + final String actionName + ) { + super(project, directory, actionName); + } + + @Override + protected void initBaseDialogState() { + super.initBaseDialogState(); + fillAttributeScopeComboBoxes(); + } + + @SuppressWarnings("PMD.AvoidInstantiatingObjectsInLoops") + protected void fillAttributeScopeComboBoxes() { + for (final AttributeScope globalValue : AttributeScope.values()) { + scopeComboBox.addItem( + new ComboBoxItemData(globalValue.getScope(), globalValue.name()) + ); + } + } + + @Override + protected JPanel getContentPanel() { + return contentPanel; + } + + @Override + protected JButton getButtonOk() { + return buttonOK; + } + + @Override + protected JButton getButtonCancel() { + return buttonCancel; + } + + @Override + protected JComboBox getAttributeTypeCompoBox() { + return typeComboBox; + } + + @Override + protected JComboBox getAttributeInputComboBox() { + return inputComboBox; + } + + @Override + protected JTable getOptionsTable() { + return optionsTable; + } + + @Override + protected JButton getNewOptionButton() { + return addNewOptionButton; + } + + @Override + protected JComboBox getAttributeSourceComboBox() { + return sourceComboBox; + } + + @Override + protected JTextField getAttributeSourceModelNameTexField() { + return sourceModelNameTextField; + } + + @Override + protected JTextField getSourceModelDirectoryTextField() { + return sourceModelDirectoryTextField; + } + + @Override + protected JPanel getAttributeCustomSourceModelPanel() { + return customSourceModelPanel; + } + + @Override + protected JPanel getAttributeOptionsPanel() { + return optionsPanel; + } + + @Override + protected JTextField getAttributeCodeTextField() { + return codeTextField; + } + + @Override + protected JTextField getDataPatchNameTextField() { + return dataPatchNameTextField; + } + + @Override + protected JTextField getSourceModelNameTextField() { + return sourceModelNameTextField; + } + + @Override + protected JTextField getAttributeLabelTexField() { + return labelTextField; + } + + @Override + protected JTextField getAttributeSortOrderTextField() { + return sortOrderTextField; + } + + @Override + protected JCheckBox getAttributeRequiredCheckBox() { + return requiredCheckBox; + } + + @Override + protected JCheckBox getAttributeVisibleBox() { + return visibleCheckBox; + } + + @Override + protected String getEntityName() { + return ENTITY_NAME; + } + + @Override + protected EavEntityDataInterface getEavEntityData() { + return populateCategoryEntityData(new CategoryEntityData()); + } + + private CategoryEntityData populateCategoryEntityData( + final CategoryEntityData categoryEntityData + ) { + categoryEntityData.setModuleName(moduleName); + + categoryEntityData.setDataPatchName(getDataPatchName()); + categoryEntityData.setCode(getAttributeCode()); + categoryEntityData.setLabel(getAttributeLabel()); + categoryEntityData.setSortOrder(getAttributeSortOrder()); + categoryEntityData.setRequired(isRequiredAttribute()); + categoryEntityData.setVisible(isVisibleAttribute()); + categoryEntityData.setType(getAttributeBackendType()); + categoryEntityData.setInput(getAttributeInput()); + categoryEntityData.setScope( + AttributeUtil.getScopeClassBySelectedItem( + (ComboBoxItemData) scopeComboBox.getSelectedItem() + ) + ); + categoryEntityData.setSource(getAttributeSource(sourceModelData)); + categoryEntityData.setOptions( + getAttributeOptions(entityPropertiesTableGroupWrapper) + ); + categoryEntityData.setOptionsSortOrder( + getAttributeOptionsSortOrders(entityPropertiesTableGroupWrapper) + ); + + categoryEntityData.setGroup(groupTextField.getText().trim()); + + return categoryEntityData; + } + + @Override + protected void generateExtraFilesAfterDataPatchGeneration( + final EavEntityDataInterface eavEntityDataInterface + ) { + super.generateExtraFilesAfterDataPatchGeneration(eavEntityDataInterface); + generateCategoryAdminForm((CategoryEntityData) eavEntityDataInterface); + } + + private void generateCategoryAdminForm(final CategoryEntityData categoryEntityData) { + final CategoryFormXmlData categoryFormXmlData = new CategoryFormXmlData( + categoryEntityData.getGroup(), + categoryEntityData.getCode(), + categoryEntityData.getInput(), + categoryEntityData.getSortOrder() + ); + + new CategoryFormXmlGenerator( + categoryFormXmlData, + project, + moduleName + ).generate(actionName, false); + } +} diff --git a/src/com/magento/idea/magento2plugin/actions/generation/dialog/NewCustomerEavAttributeDialog.form b/src/com/magento/idea/magento2plugin/actions/generation/dialog/NewCustomerEavAttributeDialog.form new file mode 100644 index 000000000..1f26f958e --- /dev/null +++ b/src/com/magento/idea/magento2plugin/actions/generation/dialog/NewCustomerEavAttributeDialog.form @@ -0,0 +1,465 @@ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/src/com/magento/idea/magento2plugin/actions/generation/dialog/NewCustomerEavAttributeDialog.java b/src/com/magento/idea/magento2plugin/actions/generation/dialog/NewCustomerEavAttributeDialog.java new file mode 100644 index 000000000..47da9a97b --- /dev/null +++ b/src/com/magento/idea/magento2plugin/actions/generation/dialog/NewCustomerEavAttributeDialog.java @@ -0,0 +1,338 @@ +/* + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +package com.magento.idea.magento2plugin.actions.generation.dialog; + +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiDirectory; +import com.magento.idea.magento2plugin.actions.generation.data.CustomerEntityData; +import com.magento.idea.magento2plugin.actions.generation.data.EavEntityDataInterface; +import com.magento.idea.magento2plugin.actions.generation.data.ui.ComboBoxItemData; +import com.magento.idea.magento2plugin.actions.generation.dialog.eavattribute.EavAttributeDialog; +import com.magento.idea.magento2plugin.actions.generation.dialog.validator.annotation.FieldValidation; +import com.magento.idea.magento2plugin.actions.generation.dialog.validator.annotation.RuleRegistry; +import com.magento.idea.magento2plugin.actions.generation.dialog.validator.rule.Lowercase; +import com.magento.idea.magento2plugin.actions.generation.dialog.validator.rule.NotEmptyRule; +import com.magento.idea.magento2plugin.actions.generation.generator.CustomerEavAttributePatchGenerator; +import com.magento.idea.magento2plugin.magento.packages.eav.AttributeInput; +import com.magento.idea.magento2plugin.magento.packages.eav.AttributeSourceModel; +import com.magento.idea.magento2plugin.magento.packages.uicomponent.AvailableSourcesByInput; +import java.awt.event.ItemEvent; +import java.awt.event.ItemListener; +import java.util.List; +import javax.swing.JButton; +import javax.swing.JCheckBox; +import javax.swing.JComboBox; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JTable; +import javax.swing.JTextField; + +@SuppressWarnings({ + "PMD.TooManyFields", + "PMD.ExcessiveImports", + "PMD.TooManyMethods", + "PMD.UnusedPrivateField" +}) +public class NewCustomerEavAttributeDialog extends EavAttributeDialog { + + private static final String ENTITY_NAME = "Customer"; + private JPanel contentPanel; + private JButton buttonOK; + private JButton buttonCancel; + @FieldValidation(rule = RuleRegistry.NOT_EMPTY, + message = {NotEmptyRule.MESSAGE, "Attribute Code"}) + @FieldValidation(rule = RuleRegistry.LOWERCASE, + message = {Lowercase.MESSAGE, "Attribute Code"}) + private JTextField codeTextField; + @FieldValidation(rule = RuleRegistry.NOT_EMPTY, + message = {NotEmptyRule.MESSAGE, "Attribute Label"}) + private JTextField labelTextField; + @FieldValidation(rule = RuleRegistry.NOT_EMPTY, + message = {NotEmptyRule.MESSAGE, "Data Patch Name"}) + private JTextField dataPatchNameTextField; + @FieldValidation(rule = RuleRegistry.NOT_EMPTY, + message = {NotEmptyRule.MESSAGE, "Attribute Sort Order"}) + @FieldValidation(rule = RuleRegistry.ALPHANUMERIC, + message = {NotEmptyRule.MESSAGE, "Attribute Sort Order"}) + private JTextField sortOrderTextField; + private JComboBox inputComboBox; + private JComboBox typeComboBox; + private JComboBox sourceComboBox; + private JCheckBox requiredCheckBox; + private JCheckBox visibleCheckBox; + private JPanel sourcePanel; + private JPanel customSourceModelPanel; + @FieldValidation(rule = RuleRegistry.NOT_EMPTY, + message = {NotEmptyRule.MESSAGE, "Source Model Directory"}) + private JTextField sourceModelDirectoryTextField; + @FieldValidation(rule = RuleRegistry.NOT_EMPTY, + message = {NotEmptyRule.MESSAGE, "Source Model Name"}) + private JTextField sourceModelNameTextField; + private JTable optionsTable; + private JButton addNewOptionButton; + private JPanel optionsPanel; + private JLabel codeTextFieldErrorMessage; + private JLabel labelTextFieldErrorMessage; + private JLabel dataPatchNameTextFieldErrorMessage; + private JLabel sourceModelDirectoryTextFieldErrorMessage; + private JLabel sourceModelNameTextFieldErrorMessage; + private JLabel sortOrderTextFieldErrorMessage; + private JCheckBox userDefineCheckBox; + private JCheckBox useInAdminhtmlCustomerCheckBox; + private JCheckBox useInCustomerAccountCreateCheckBox; + private JCheckBox useInCustomerAccountEditCheckBox; + private JCheckBox useInGridCheckBox; + private JCheckBox filterableInGridCheckBox; + private JCheckBox visibleInGridCheckBox; + private JCheckBox systemAttributeCheckBox; + private JCheckBox useInAdminhtmlCheckoutCheckBox; + + /** + * Constructor. + * + * @param project Project + * @param directory PsiDirectory + * @param actionName String + */ + public NewCustomerEavAttributeDialog( + final Project project, + final PsiDirectory directory, + final String actionName + ) { + super(project, directory, actionName); + } + + @Override + protected JPanel getContentPanel() { + return contentPanel; + } + + @Override + protected JButton getButtonOk() { + return buttonOK; + } + + @Override + protected JButton getButtonCancel() { + return buttonCancel; + } + + @Override + protected JComboBox getAttributeTypeCompoBox() { + return typeComboBox; + } + + @Override + protected JComboBox getAttributeInputComboBox() { + return inputComboBox; + } + + @Override + protected JTable getOptionsTable() { + return optionsTable; + } + + @Override + protected JButton getNewOptionButton() { + return addNewOptionButton; + } + + @Override + protected JComboBox getAttributeSourceComboBox() { + return sourceComboBox; + } + + @Override + protected JTextField getAttributeSourceModelNameTexField() { + return sourceModelNameTextField; + } + + @Override + protected JTextField getSourceModelDirectoryTextField() { + return sourceModelDirectoryTextField; + } + + @Override + protected JPanel getAttributeCustomSourceModelPanel() { + return customSourceModelPanel; + } + + @Override + protected JPanel getAttributeOptionsPanel() { + return optionsPanel; + } + + @Override + protected JTextField getAttributeCodeTextField() { + return codeTextField; + } + + @Override + protected JTextField getDataPatchNameTextField() { + return dataPatchNameTextField; + } + + @Override + protected JTextField getSourceModelNameTextField() { + return sourceModelNameTextField; + } + + @Override + protected JTextField getAttributeLabelTexField() { + return labelTextField; + } + + @Override + protected JTextField getAttributeSortOrderTextField() { + return sortOrderTextField; + } + + @Override + protected JCheckBox getAttributeRequiredCheckBox() { + return requiredCheckBox; + } + + @Override + protected JCheckBox getAttributeVisibleBox() { + return visibleCheckBox; + } + + @Override + protected String getEntityName() { + return ENTITY_NAME; + } + + @Override + protected void generateDataPatchFile(final EavEntityDataInterface eavEntityDataInterface) { + new CustomerEavAttributePatchGenerator( + eavEntityDataInterface, + project, + true + ).generate(actionName, true); + } + + @Override + protected EavEntityDataInterface getEavEntityData() { + return populateCategoryEntityData(new CustomerEntityData()); + } + + private CustomerEntityData populateCategoryEntityData( + final CustomerEntityData customerEntityData + ) { + customerEntityData.setModuleName(moduleName); + customerEntityData.setType(getAttributeBackendType()); + customerEntityData.setDataPatchName(getDataPatchName()); + customerEntityData.setCode(getAttributeCode()); + customerEntityData.setLabel(getAttributeLabel()); + customerEntityData.setSortOrder(getAttributeSortOrder()); + customerEntityData.setRequired(isRequiredAttribute()); + customerEntityData.setVisible(isVisibleAttribute()); + customerEntityData.setInput(getAttributeInput()); + customerEntityData.setSource(getAttributeSource(sourceModelData)); + customerEntityData.setOptions( + getAttributeOptions(entityPropertiesTableGroupWrapper) + ); + customerEntityData.setOptionsSortOrder( + getAttributeOptionsSortOrders(entityPropertiesTableGroupWrapper) + ); + customerEntityData.setUserDefined(userDefineCheckBox.isSelected()); + customerEntityData.setUseInAdminhtmlCustomerForm( + useInAdminhtmlCustomerCheckBox.isSelected() + ); + customerEntityData.setUseInAdminhtmlCheckoutForm( + useInAdminhtmlCheckoutCheckBox.isSelected() + ); + customerEntityData.setUseInCustomerAccountCreateForm( + useInCustomerAccountCreateCheckBox.isSelected() + ); + customerEntityData.setUseInCustomerAccountEditForm( + useInCustomerAccountEditCheckBox.isSelected() + ); + customerEntityData.setVisibleInGrid(visibleInGridCheckBox.isSelected()); + customerEntityData.setUsedInGrid(useInGridCheckBox.isSelected()); + customerEntityData.setFilterableInGrid(filterableInGridCheckBox.isSelected()); + customerEntityData.setSystem(systemAttributeCheckBox.isSelected()); + + return customerEntityData; + } + + @Override + protected void addOptionPanelListener( + final JComboBox attributeSourceComboBox, + final JComboBox attributeInputComboBox, + final JPanel attributeOptionsPanel + ) { + if (attributeSourceComboBox == null + || attributeInputComboBox == null + || attributeOptionsPanel == null + ) { + return; + } + + attributeSourceComboBox.addItemListener(new ItemListener() { + @Override + public void itemStateChanged(final ItemEvent itemEvent) { + final ComboBoxItemData selectedInputItem = + (ComboBoxItemData) attributeInputComboBox.getSelectedItem(); + final String selectedInput = selectedInputItem == null + ? "" : selectedInputItem.toString(); + final boolean isAllowedInput = + AttributeInput.SELECT.getInput().equals(selectedInput) + || AttributeInput.MULTISELECT.getInput().equals(selectedInput); + + attributeOptionsPanel.setVisible(isAllowedInput); + } + }); + } + + @Override + protected void setAttributeInputComboBoxAction( + final JComboBox sourceComboBox, + final JComboBox inputComboBox + ) { + if (sourceComboBox == null || inputComboBox == null) { + return; + } + + inputComboBox.addItemListener(new ItemListener() { + @Override + public void itemStateChanged(final ItemEvent itemEvent) { + final String selectedInput = itemEvent.getItem().toString(); + + final List availableSources = + new AvailableSourcesByInput(selectedInput).getItems(); + sourceComboBox.removeAllItems(); + + if (!selectedInput.equals(AttributeInput.SELECT.getInput()) + || !selectedInput.equals(AttributeInput.MULTISELECT.getInput())) { + final ComboBoxItemData defaultSourceItem = new ComboBoxItemData( + AttributeSourceModel.NULLABLE_SOURCE.name(), + AttributeSourceModel.NULLABLE_SOURCE.getSource() + ); + + sourceComboBox.addItem(defaultSourceItem); + sourceComboBox.setSelectedItem(defaultSourceItem); + } + + if (availableSources.isEmpty()) { + return; + } + + for (final ComboBoxItemData comboBoxItemData : availableSources) { + sourceComboBox.addItem(comboBoxItemData); + + if (comboBoxItemData.getText().equals(AttributeSourceModel.TABLE.getSource())) { + sourceComboBox.setSelectedItem(comboBoxItemData); + } + } + } + }); + } + + private void createUIComponents() { //NOPMD - suppressed UnusedPrivateMethod + // TODO: place custom component creation code here + } +} diff --git a/src/com/magento/idea/magento2plugin/actions/generation/dialog/NewProductEavAttributeDialog.form b/src/com/magento/idea/magento2plugin/actions/generation/dialog/NewProductEavAttributeDialog.form new file mode 100644 index 000000000..fb8710dee --- /dev/null +++ b/src/com/magento/idea/magento2plugin/actions/generation/dialog/NewProductEavAttributeDialog.form @@ -0,0 +1,517 @@ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/src/com/magento/idea/magento2plugin/actions/generation/dialog/NewProductEavAttributeDialog.java b/src/com/magento/idea/magento2plugin/actions/generation/dialog/NewProductEavAttributeDialog.java new file mode 100644 index 000000000..faba8d9a1 --- /dev/null +++ b/src/com/magento/idea/magento2plugin/actions/generation/dialog/NewProductEavAttributeDialog.java @@ -0,0 +1,287 @@ +/* + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +package com.magento.idea.magento2plugin.actions.generation.dialog; + +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiDirectory; +import com.magento.idea.magento2plugin.actions.generation.data.EavEntityDataInterface; +import com.magento.idea.magento2plugin.actions.generation.data.ProductEntityData; +import com.magento.idea.magento2plugin.actions.generation.data.ui.ComboBoxItemData; +import com.magento.idea.magento2plugin.actions.generation.dialog.eavattribute.EavAttributeDialog; +import com.magento.idea.magento2plugin.actions.generation.dialog.event.eavdialog.ApplyToVisibleListener; +import com.magento.idea.magento2plugin.actions.generation.dialog.util.eavdialog.AttributeUtil; +import com.magento.idea.magento2plugin.actions.generation.dialog.validator.annotation.FieldValidation; +import com.magento.idea.magento2plugin.actions.generation.dialog.validator.annotation.RuleRegistry; +import com.magento.idea.magento2plugin.actions.generation.dialog.validator.rule.CommaSeparatedStringRule; +import com.magento.idea.magento2plugin.actions.generation.dialog.validator.rule.Lowercase; +import com.magento.idea.magento2plugin.actions.generation.dialog.validator.rule.NotEmptyRule; +import com.magento.idea.magento2plugin.magento.packages.eav.AttributeScope; +import com.magento.idea.magento2plugin.util.magento.GetProductTypesListUtil; +import java.util.List; +import javax.swing.DefaultListModel; +import javax.swing.JButton; +import javax.swing.JCheckBox; +import javax.swing.JComboBox; +import javax.swing.JLabel; +import javax.swing.JList; +import javax.swing.JPanel; +import javax.swing.JTable; +import javax.swing.JTextField; + +@SuppressWarnings({ + "PMD.TooManyFields", + "PMD.ExcessiveImports", + "PMD.TooManyMethods", + "PMD.UnusedPrivateField" +}) +public class NewProductEavAttributeDialog extends EavAttributeDialog { + + private static final String ENTITY_NAME = "Product"; + private JPanel contentPanel; + private JButton buttonOK; + private JButton buttonCancel; + @FieldValidation(rule = RuleRegistry.NOT_EMPTY, + message = {NotEmptyRule.MESSAGE, "Attribute Code"}) + @FieldValidation(rule = RuleRegistry.LOWERCASE, + message = {Lowercase.MESSAGE, "Attribute Code"}) + private JTextField codeTextField; + @FieldValidation(rule = RuleRegistry.NOT_EMPTY, + message = {NotEmptyRule.MESSAGE, "Attribute Label"}) + private JTextField labelTextField; + @FieldValidation(rule = RuleRegistry.NOT_EMPTY, + message = {NotEmptyRule.MESSAGE, "Attribute Group"}) + private JTextField groupTextField; + @FieldValidation(rule = RuleRegistry.NOT_EMPTY, + message = {NotEmptyRule.MESSAGE, "Data Patch Name"}) + private JTextField dataPatchNameTextField; + @FieldValidation(rule = RuleRegistry.NOT_EMPTY, + message = {NotEmptyRule.MESSAGE, "Attribute Sort Order"}) + @FieldValidation(rule = RuleRegistry.ALPHANUMERIC, + message = {NotEmptyRule.MESSAGE, "Attribute Sort Order"}) + private JTextField sortOrderTextField; + private JComboBox inputComboBox; + private JComboBox typeComboBox; + private JComboBox scopeComboBox; + private JComboBox sourceComboBox; + private JCheckBox requiredCheckBox; + private JCheckBox usedInGridGridCheckBox; + private JCheckBox visibleInGridCheckBox; + private JCheckBox filterableInGridCheckBox; + private JCheckBox visibleCheckBox; + private JCheckBox htmlAllowedOnCheckBox; + private JCheckBox visibleOnFrontCheckBox; + private JPanel sourcePanel; + private JPanel customSourceModelPanel; + @FieldValidation(rule = RuleRegistry.NOT_EMPTY, + message = {NotEmptyRule.MESSAGE, "Source Model Directory"}) + private JTextField sourceModelDirectoryTextField; + @FieldValidation(rule = RuleRegistry.NOT_EMPTY, + message = {NotEmptyRule.MESSAGE, "Source Model Name"}) + private JTextField sourceModelNameTextField; + private JTable optionsTable; + private JButton addNewOptionButton; + private JPanel optionsPanel; + @FieldValidation(rule = RuleRegistry.COMMA_SEPARATED_STRING, + message = {CommaSeparatedStringRule.MESSAGE, "Apply To"}) + private JCheckBox applyToAllProductsCheckBox; + private JPanel applyToPanel; + private JList productsTypesList; + private JLabel labelTextFieldErrorMessage; + private JLabel codeTextFieldErrorMessage; + private JLabel dataPatchNameTextFieldErrorMessage; + private JLabel groupTextFieldErrorMessage; + private JLabel sourceModelDirectoryTextFieldErrorMessage; + private JLabel sourceModelNameTextFieldErrorMessage; + private JLabel sortOrderTextFieldErrorMessage; + + /** + * Constructor. + * + * @param project Project + * @param directory PsiDirectory + */ + public NewProductEavAttributeDialog( + final Project project, + final PsiDirectory directory, + final String actionName + ) { + super(project, directory, actionName); + } + + @Override + protected void initBaseDialogState() { + super.initBaseDialogState(); + fillAttributeScopeComboBoxes(); + addApplyToVisibilityAction(); + fillProductsTypesList(); + } + + @SuppressWarnings("PMD.AvoidInstantiatingObjectsInLoops") + protected void fillAttributeScopeComboBoxes() { + for (final AttributeScope globalValue : AttributeScope.values()) { + scopeComboBox.addItem( + new ComboBoxItemData(globalValue.getScope(), globalValue.name()) + ); + } + } + + @Override + protected JPanel getContentPanel() { + return contentPanel; + } + + @Override + protected JButton getButtonOk() { + return buttonOK; + } + + @Override + protected JButton getButtonCancel() { + return buttonCancel; + } + + @Override + protected JComboBox getAttributeTypeCompoBox() { + return typeComboBox; + } + + @Override + protected JComboBox getAttributeInputComboBox() { + return inputComboBox; + } + + @Override + protected JTable getOptionsTable() { + return optionsTable; + } + + @Override + protected JButton getNewOptionButton() { + return addNewOptionButton; + } + + @Override + protected JComboBox getAttributeSourceComboBox() { + return sourceComboBox; + } + + @Override + protected JTextField getAttributeSourceModelNameTexField() { + return sourceModelNameTextField; + } + + @Override + protected JTextField getSourceModelDirectoryTextField() { + return sourceModelDirectoryTextField; + } + + @Override + protected JPanel getAttributeCustomSourceModelPanel() { + return customSourceModelPanel; + } + + @Override + protected JPanel getAttributeOptionsPanel() { + return optionsPanel; + } + + @Override + protected JTextField getAttributeCodeTextField() { + return codeTextField; + } + + @Override + protected JTextField getDataPatchNameTextField() { + return dataPatchNameTextField; + } + + @Override + protected JTextField getSourceModelNameTextField() { + return sourceModelNameTextField; + } + + @Override + protected JTextField getAttributeLabelTexField() { + return labelTextField; + } + + @Override + protected JTextField getAttributeSortOrderTextField() { + return sortOrderTextField; + } + + @Override + protected JCheckBox getAttributeRequiredCheckBox() { + return requiredCheckBox; + } + + @Override + protected JCheckBox getAttributeVisibleBox() { + return visibleCheckBox; + } + + @Override + protected String getEntityName() { + return ENTITY_NAME; + } + + @Override + protected EavEntityDataInterface getEavEntityData() { + return populateProductEntityData(new ProductEntityData()); + } + + private ProductEntityData populateProductEntityData(final ProductEntityData productEntityData) { + productEntityData.setModuleName(moduleName); + + productEntityData.setDataPatchName(getDataPatchName()); + productEntityData.setCode(getAttributeCode()); + productEntityData.setLabel(getAttributeLabel()); + productEntityData.setSortOrder(getAttributeSortOrder()); + productEntityData.setRequired(isRequiredAttribute()); + productEntityData.setVisible(isVisibleAttribute()); + productEntityData.setGroup(groupTextField.getText().trim()); + productEntityData.setUsedInGrid(usedInGridGridCheckBox.isSelected()); + productEntityData.setVisibleInGrid(visibleInGridCheckBox.isSelected()); + productEntityData.setFilterableInGrid(filterableInGridCheckBox.isSelected()); + productEntityData.setHtmlAllowedOnFront(htmlAllowedOnCheckBox.isSelected()); + productEntityData.setVisibleOnFront(visibleOnFrontCheckBox.isSelected()); + productEntityData.setType(getAttributeBackendType()); + productEntityData.setInput(getAttributeInput()); + productEntityData.setScope( + AttributeUtil.getScopeClassBySelectedItem( + (ComboBoxItemData) scopeComboBox.getSelectedItem() + ) + ); + productEntityData.setSource(getAttributeSource(sourceModelData)); + productEntityData.setOptions( + getAttributeOptions(entityPropertiesTableGroupWrapper) + ); + productEntityData.setOptionsSortOrder( + getAttributeOptionsSortOrders(entityPropertiesTableGroupWrapper) + ); + + if (!applyToAllProductsCheckBox.isSelected()) { + productEntityData.setApplyTo( + String.join(",", productsTypesList.getSelectedValuesList()) + ); + } + + return productEntityData; + } + + protected void addApplyToVisibilityAction() { + applyToAllProductsCheckBox.addChangeListener(new ApplyToVisibleListener(applyToPanel)); + } + + private void fillProductsTypesList() { + final List productTypes = GetProductTypesListUtil.execute(project); + + final DefaultListModel listModel = new DefaultListModel<>(); + listModel.addAll(productTypes); + productsTypesList.setModel(listModel); + productsTypesList.setSelectedIndex(0); + } +} diff --git a/src/com/magento/idea/magento2plugin/actions/generation/dialog/eavattribute/EavAttributeDialog.java b/src/com/magento/idea/magento2plugin/actions/generation/dialog/eavattribute/EavAttributeDialog.java new file mode 100644 index 000000000..885baff52 --- /dev/null +++ b/src/com/magento/idea/magento2plugin/actions/generation/dialog/eavattribute/EavAttributeDialog.java @@ -0,0 +1,526 @@ +/* + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +package com.magento.idea.magento2plugin.actions.generation.dialog.eavattribute; + +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiDirectory; +import com.magento.idea.magento2plugin.actions.generation.data.EavEntityDataInterface; +import com.magento.idea.magento2plugin.actions.generation.data.SourceModelData; +import com.magento.idea.magento2plugin.actions.generation.data.ui.ComboBoxItemData; +import com.magento.idea.magento2plugin.actions.generation.dialog.AbstractDialog; +import com.magento.idea.magento2plugin.actions.generation.dialog.event.eavdialog.AttributeCodeAdapter; +import com.magento.idea.magento2plugin.actions.generation.dialog.event.eavdialog.AttributeSourcePanelComponentListener; +import com.magento.idea.magento2plugin.actions.generation.dialog.event.eavdialog.AttributeSourceRelationsItemListener; +import com.magento.idea.magento2plugin.actions.generation.dialog.event.eavdialog.DataPatchNameAdapter; +import com.magento.idea.magento2plugin.actions.generation.dialog.event.eavdialog.EavAttributeInputItemListener; +import com.magento.idea.magento2plugin.actions.generation.dialog.event.eavdialog.OptionsPanelVisibilityChangeListener; +import com.magento.idea.magento2plugin.actions.generation.dialog.event.eavdialog.SourceModelNameAdapter; +import com.magento.idea.magento2plugin.actions.generation.dialog.util.eavdialog.AttributeUtil; +import com.magento.idea.magento2plugin.actions.generation.generator.EavAttributeSetupPatchGenerator; +import com.magento.idea.magento2plugin.actions.generation.generator.SourceModelGenerator; +import com.magento.idea.magento2plugin.actions.generation.generator.util.GetAttributeOptionPropertiesUtil; +import com.magento.idea.magento2plugin.magento.packages.eav.AttributeInput; +import com.magento.idea.magento2plugin.magento.packages.eav.AttributeSourceModel; +import com.magento.idea.magento2plugin.magento.packages.eav.AttributeType; +import com.magento.idea.magento2plugin.ui.table.TableGroupWrapper; +import com.magento.idea.magento2plugin.util.magento.GetModuleNameByDirectoryUtil; +import java.awt.event.KeyEvent; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; +import java.util.Arrays; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import javax.swing.JButton; +import javax.swing.JCheckBox; +import javax.swing.JComboBox; +import javax.swing.JComponent; +import javax.swing.JPanel; +import javax.swing.JTable; +import javax.swing.JTextField; +import javax.swing.KeyStroke; +import org.jetbrains.annotations.NotNull; + +@SuppressWarnings({ + "PMD.GodClass", + "PMD.TooManyMethods", + "PMD.ExcessiveImports", + "PMD.AccessorMethodGeneration" +}) +public abstract class EavAttributeDialog extends AbstractDialog { + + protected String moduleName; + protected Project project; + protected String actionName; + protected TableGroupWrapper entityPropertiesTableGroupWrapper; + protected SourceModelData sourceModelData; + + protected abstract EavEntityDataInterface getEavEntityData(); + + protected abstract JPanel getContentPanel(); + + protected abstract JButton getButtonOk(); + + protected abstract JButton getButtonCancel(); + + protected abstract JComboBox getAttributeTypeCompoBox(); + + protected abstract JComboBox getAttributeInputComboBox(); + + protected abstract JTable getOptionsTable(); + + protected abstract JButton getNewOptionButton(); + + protected abstract JComboBox getAttributeSourceComboBox(); + + protected abstract JTextField getAttributeSourceModelNameTexField(); + + protected abstract JTextField getSourceModelDirectoryTextField(); + + protected abstract JPanel getAttributeCustomSourceModelPanel(); + + protected abstract JPanel getAttributeOptionsPanel(); + + protected abstract JTextField getAttributeCodeTextField(); + + protected abstract JTextField getDataPatchNameTextField(); + + protected abstract JTextField getSourceModelNameTextField(); + + protected abstract JTextField getAttributeLabelTexField(); + + protected abstract JTextField getAttributeSortOrderTextField(); + + protected abstract JCheckBox getAttributeRequiredCheckBox(); + + protected abstract JCheckBox getAttributeVisibleBox(); + + protected abstract String getEntityName(); + + /** + * Constructor. + * + * @param project Project + * @param directory PsiDirectory + * @param actionName String + */ + public EavAttributeDialog( + final Project project, + final PsiDirectory directory, + final String actionName + ) { + super(); + + this.project = project; + this.actionName = actionName; + this.moduleName = GetModuleNameByDirectoryUtil.execute(directory, project); + this.sourceModelData = new SourceModelData(); + } + + /** + * Open dialog window. + */ + public void open() { + this.initBaseDialogState(); + pack(); + centerDialog(this); + setTitle(actionName); + setVisible(true); + } + + protected void initBaseDialogState() { + this.setPanelConfiguration(); + this.fillAttributeTypeComboBox(getAttributeTypeCompoBox()); + this.fillAttributeInputComboBox(getAttributeInputComboBox()); + + this.initPropertiesTable( + new LinkedList<>(Arrays.asList( + "Value", + "Sort Order" + )), + getOptionsTable(), + getNewOptionButton(), + getDefaultColumnsValues(), + getColumnsSources() + ); + + this.addActionListenersForOkButton(getButtonOk()); + this.addActionListenersForOkCancel(getButtonCancel()); + + this.addCancelActionForWindow(); + this.addCancelActionForEsc(); + + this.setAttributeInputComboBoxAction( + getAttributeSourceComboBox(), + getAttributeInputComboBox() + ); + this.setSourceComboBoxAction(getAttributeSourceComboBox()); + + this.setSourceModelPanelAction( + getAttributeCustomSourceModelPanel(), + getSourceModelDirectoryTextField() + ); + this.addOptionPanelListener( + getAttributeSourceComboBox(), + getAttributeInputComboBox(), + getAttributeOptionsPanel() + ); + this.setDefaultSources(getAttributeSourceComboBox()); + this.setAutocompleteListenerForAttributeCodeField( + getAttributeLabelTexField(), + getAttributeCodeTextField() + ); + this.setAutocompleteListenerForDataPathNameField( + getAttributeCodeTextField(), + getDataPatchNameTextField() + ); + this.setAutocompleteListenerForSourceModelNameField( + getAttributeCodeTextField(), + getSourceModelNameTextField() + ); + } + + protected void setPanelConfiguration() { + setContentPane(this.getContentPanel()); + setModal(this.isModalWindow()); + getRootPane().setDefaultButton(this.getButtonOk()); + } + + protected boolean isModalWindow() { + return true; + } + + @SuppressWarnings("PMD.AvoidInstantiatingObjectsInLoops") + protected void fillAttributeTypeComboBox(final JComboBox typeComboBox) { + if (typeComboBox == null) { + return; + } + + for (final AttributeType typeValue : AttributeType.values()) { + typeComboBox.addItem( + new ComboBoxItemData(typeValue.getType(), typeValue.getType()) + ); + } + } + + @SuppressWarnings("PMD.AvoidInstantiatingObjectsInLoops") + protected void fillAttributeInputComboBox(final JComboBox inputComboBox) { + if (inputComboBox == null) { + return; + } + + for (final AttributeInput inputValue : AttributeInput.values()) { + inputComboBox.addItem( + new ComboBoxItemData(inputValue.getInput(), inputValue.getInput()) + ); + } + } + + protected void initPropertiesTable( + final List columns, + final JTable optionsTable, + final JButton newOptionButton, + final Map defaultColumnsValues, + final Map> columnsSources + + ) { + // Initialize entity properties Table Group + entityPropertiesTableGroupWrapper = new TableGroupWrapper( + optionsTable, + newOptionButton, + columns, + defaultColumnsValues, + columnsSources + ); + entityPropertiesTableGroupWrapper.initTableGroup(); + } + + protected Map getDefaultColumnsValues() { + return new HashMap<>(); + } + + protected Map> getColumnsSources() { + return new HashMap<>(); + } + + protected void addActionListenersForOkButton(final JButton okButton) { + okButton.addActionListener(e -> onOk()); + } + + protected void addActionListenersForOkCancel(final JButton cancelButton) { + cancelButton.addActionListener(e -> onCancel()); + } + + protected void onOk() { + stopOptionsTableEditing(getOptionsTable()); + + if (!validateFormFields()) { + return; + } + + generateExtraFilesBeforeDataPatchGeneration(); + + final EavEntityDataInterface eavEntityDataInterface = getEavEntityData(); + generateDataPatchFile(eavEntityDataInterface); + generateExtraFilesAfterDataPatchGeneration(eavEntityDataInterface); + + setVisible(false); + } + + protected void generateSourceModelFile() { + final ComboBoxItemData selectedSource = + (ComboBoxItemData) getAttributeSourceComboBox().getSelectedItem(); + + if (selectedSource == null + || !selectedSource.getText().equals( + AttributeSourceModel.GENERATE_SOURCE.getSource() + )) { + return; + } + + sourceModelData.setModuleName(moduleName); + sourceModelData.setClassName(getAttributeSourceModelNameTexField().getText().trim()); + sourceModelData.setDirectory(getSourceModelDirectoryTextField().getText().trim()); + + new SourceModelGenerator(sourceModelData, project, true) + .generate(actionName, false); + } + + protected void generateDataPatchFile(final EavEntityDataInterface eavEntityDataInterface) { + new EavAttributeSetupPatchGenerator( + eavEntityDataInterface, + project, + true + ).generate(actionName, true); + } + + protected void generateExtraFilesBeforeDataPatchGeneration() { + generateSourceModelFile(); + } + + @SuppressWarnings({ + "PMD.EmptyMethodInAbstractClassShouldBeAbstract", + "PMD.UncommentedEmptyMethodBody" + }) + protected void generateExtraFilesAfterDataPatchGeneration( + final EavEntityDataInterface eavEntityDataInterface + ) {} + + protected void addCancelActionForWindow() { + setDefaultCloseOperation(DO_NOTHING_ON_CLOSE); + addWindowListener(new WindowAdapter() { + @Override + public void windowClosing(final WindowEvent event) { + onCancel(); + } + }); + } + + protected void addCancelActionForEsc() { + getContentPanel().registerKeyboardAction( + event -> onCancel(), + KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), + JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT + ); + } + + protected void setAttributeInputComboBoxAction( + final JComboBox sourceComboBox, + final JComboBox inputComboBox + ) { + if (sourceComboBox == null || inputComboBox == null) { + return; + } + + inputComboBox.addItemListener( + new EavAttributeInputItemListener(sourceComboBox) + ); + } + + protected void setSourceComboBoxAction(final JComboBox sourceComboBox) { + if (sourceComboBox == null) { + return; + } + + sourceComboBox.addItemListener( + new AttributeSourceRelationsItemListener(getAttributeCustomSourceModelPanel()) + ); + } + + protected void setSourceModelPanelAction( + final JPanel attributeCustomSourceModelPanel, + final JTextField sourceModelDirectoryTexField + ) { + if (attributeCustomSourceModelPanel == null || sourceModelDirectoryTexField == null) { + return; + } + + attributeCustomSourceModelPanel.addComponentListener( + new AttributeSourcePanelComponentListener(sourceModelDirectoryTexField) + ); + } + + protected void addOptionPanelListener( + final JComboBox attributeSourceComboBox, + final JComboBox attributeInputComboBox, + final JPanel attributeOptionsPanel + ) { + if (attributeSourceComboBox == null + || attributeInputComboBox == null + || attributeOptionsPanel == null + ) { + return; + } + + attributeSourceComboBox.addItemListener( + new OptionsPanelVisibilityChangeListener( + attributeOptionsPanel, + attributeInputComboBox + ) + ); + } + + protected void setDefaultSources(final JComboBox sourceComboBox) { + if (sourceComboBox == null) { + return; + } + + final ComboBoxItemData generateSourceItem = new ComboBoxItemData( + AttributeSourceModel.GENERATE_SOURCE.getSource(), + AttributeSourceModel.GENERATE_SOURCE.getSource() + ); + final ComboBoxItemData defaultSourceItem = new ComboBoxItemData( + AttributeSourceModel.NULLABLE_SOURCE.name(), + AttributeSourceModel.NULLABLE_SOURCE.getSource() + ); + + sourceComboBox.addItem(defaultSourceItem); + sourceComboBox.addItem(generateSourceItem); + + sourceComboBox.setSelectedItem(defaultSourceItem); + } + + protected void setAutocompleteListenerForAttributeCodeField( + @NotNull final JTextField attributeLabelTextField, + @NotNull final JTextField attributeCodeTextField + ) { + attributeLabelTextField.getDocument() + .addDocumentListener(new AttributeCodeAdapter(attributeCodeTextField)); + } + + protected void setAutocompleteListenerForDataPathNameField( + final JTextField mainTextField, + final JTextField dependentTextField + + ) { + if (mainTextField == null || dependentTextField == null) { + return; + } + + mainTextField.getDocument() + .addDocumentListener(new DataPatchNameAdapter(dependentTextField, getEntityName())); + } + + protected void setAutocompleteListenerForSourceModelNameField( + final JTextField mainTextField, + final JTextField dependentTextField + ) { + if (mainTextField == null || dependentTextField == null) { + return; + } + + mainTextField.getDocument() + .addDocumentListener(new SourceModelNameAdapter(dependentTextField)); + } + + protected String getDataPatchName() { + final JTextField dataPatchNameTextField = getDataPatchNameTextField(); + + return dataPatchNameTextField == null + ? "" : dataPatchNameTextField.getText().trim(); + } + + protected String getAttributeCode() { + final JTextField codeTextField = getAttributeCodeTextField(); + + return codeTextField == null + ? "" : codeTextField.getText().trim(); + } + + protected String getAttributeLabel() { + final JTextField labelTextField = getAttributeLabelTexField(); + + return labelTextField == null + ? "" : labelTextField.getText().trim(); + } + + protected int getAttributeSortOrder() { + final JTextField sortOrderTextField = getAttributeSortOrderTextField(); + + return sortOrderTextField == null + ? 0 : Integer.parseInt(sortOrderTextField.getText().trim()); + } + + protected boolean isRequiredAttribute() { + final JCheckBox requiredCheckBox = getAttributeRequiredCheckBox(); + + return requiredCheckBox != null && requiredCheckBox.isSelected(); + } + + protected boolean isVisibleAttribute() { + final JCheckBox visibleCheckBox = getAttributeVisibleBox(); + + return visibleCheckBox != null && visibleCheckBox.isSelected(); + } + + protected String getAttributeBackendType() { + final JComboBox typeComboBox = getAttributeTypeCompoBox(); + + return AttributeUtil.getBackendTypeBySelectedItem( + (ComboBoxItemData) typeComboBox.getSelectedItem() + ); + } + + protected String getAttributeInput() { + final JComboBox inputComboBox = getAttributeInputComboBox(); + + return AttributeUtil.getInputTypeBySelectedItem( + (ComboBoxItemData) inputComboBox.getSelectedItem() + ); + } + + protected String getAttributeSource(final SourceModelData sourceModelData) { + final JComboBox sourceComboBox = getAttributeSourceComboBox(); + + return AttributeUtil.getSourceClassBySelectedItem( + (ComboBoxItemData) sourceComboBox.getSelectedItem(), + sourceModelData + ); + } + + protected Map getAttributeOptions( + final TableGroupWrapper entityPropertiesTableGroupWrapper + ) { + return GetAttributeOptionPropertiesUtil.getValues( + entityPropertiesTableGroupWrapper.getColumnsData() + ); + } + + protected Map getAttributeOptionsSortOrders( + final TableGroupWrapper entityPropertiesTableGroupWrapper + ) { + return GetAttributeOptionPropertiesUtil.getSortOrders( + entityPropertiesTableGroupWrapper.getColumnsData() + ); + } + + private void stopOptionsTableEditing(final JTable optionsTable) { + if (optionsTable != null && optionsTable.isEditing()) { + optionsTable.getCellEditor().stopCellEditing(); + } + } +} diff --git a/src/com/magento/idea/magento2plugin/actions/generation/dialog/event/eavdialog/ApplyToVisibleListener.java b/src/com/magento/idea/magento2plugin/actions/generation/dialog/event/eavdialog/ApplyToVisibleListener.java new file mode 100644 index 000000000..1b9133e07 --- /dev/null +++ b/src/com/magento/idea/magento2plugin/actions/generation/dialog/event/eavdialog/ApplyToVisibleListener.java @@ -0,0 +1,28 @@ +/* + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +package com.magento.idea.magento2plugin.actions.generation.dialog.event.eavdialog; + +import javax.swing.JCheckBox; +import javax.swing.JPanel; +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; +import org.jetbrains.annotations.NotNull; + +public class ApplyToVisibleListener implements ChangeListener { + + private final JPanel applyToPanel; + + public ApplyToVisibleListener(@NotNull final JPanel applyToPanel) { + this.applyToPanel = applyToPanel; + } + + @Override + public void stateChanged(final ChangeEvent changeEvent) { + final JCheckBox checkBox = (JCheckBox) changeEvent.getSource(); + + applyToPanel.setVisible(!checkBox.isSelected()); + } +} diff --git a/src/com/magento/idea/magento2plugin/actions/generation/dialog/event/eavdialog/AttributeCodeAdapter.java b/src/com/magento/idea/magento2plugin/actions/generation/dialog/event/eavdialog/AttributeCodeAdapter.java new file mode 100644 index 000000000..a1143cdd7 --- /dev/null +++ b/src/com/magento/idea/magento2plugin/actions/generation/dialog/event/eavdialog/AttributeCodeAdapter.java @@ -0,0 +1,46 @@ +/* + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +package com.magento.idea.magento2plugin.actions.generation.dialog.event.eavdialog; + +import com.intellij.ui.DocumentAdapter; +import java.util.Locale; +import javax.swing.JTextField; +import javax.swing.event.DocumentEvent; +import javax.swing.text.BadLocationException; +import javax.swing.text.Document; +import org.jetbrains.annotations.NotNull; + +public class AttributeCodeAdapter extends DocumentAdapter { + + private final JTextField attributeCodeTextField; + + public AttributeCodeAdapter(@NotNull final JTextField attributeCodeTextField) { + super(); + this.attributeCodeTextField = attributeCodeTextField; + } + + @Override + protected void textChanged(final @NotNull DocumentEvent event) { + final Document document = event.getDocument(); + + try { + final String attributeLabel = document.getText( + 0, document.getEndPosition().getOffset() + ).trim(); + attributeCodeTextField.setText( + convertLabelToAttributeCode(attributeLabel) + ); + } catch (BadLocationException badLocationException) { + return; + } + } + + private String convertLabelToAttributeCode(final String attributeLabel) { + final String formattedAttributeLabel = attributeLabel.trim().toLowerCase(Locale.ROOT); + + return formattedAttributeLabel.replaceAll("^ +| +$|( )+", "_"); + } +} diff --git a/src/com/magento/idea/magento2plugin/actions/generation/dialog/event/eavdialog/AttributeSourcePanelComponentListener.java b/src/com/magento/idea/magento2plugin/actions/generation/dialog/event/eavdialog/AttributeSourcePanelComponentListener.java new file mode 100644 index 000000000..b7d1eaecd --- /dev/null +++ b/src/com/magento/idea/magento2plugin/actions/generation/dialog/event/eavdialog/AttributeSourcePanelComponentListener.java @@ -0,0 +1,49 @@ +/* + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +package com.magento.idea.magento2plugin.actions.generation.dialog.event.eavdialog; + +import com.magento.idea.magento2plugin.magento.files.SourceModelFile; +import java.awt.event.ComponentEvent; +import java.awt.event.ComponentListener; +import javax.swing.JTextField; + +public class AttributeSourcePanelComponentListener implements ComponentListener { + private final JTextField sourceModelDirectoryTexField; + + public AttributeSourcePanelComponentListener( + final JTextField sourceModelDirectoryTexField + ) { + this.sourceModelDirectoryTexField = sourceModelDirectoryTexField; + } + + @Override + public void componentResized(final ComponentEvent componentEvent) { + // + } + + @Override + public void componentMoved(final ComponentEvent componentEvent) { + // + } + + @Override + public void componentShown(final ComponentEvent componentEvent) { + initSetDirectoryFieldValue(); + } + + @Override + public void componentHidden(final ComponentEvent componentEvent) { + initSetDirectoryFieldValue(); + } + + private void initSetDirectoryFieldValue() { + final String sourceDirectoryValue = sourceModelDirectoryTexField.getText().trim(); + + if (sourceDirectoryValue.isEmpty()) { + sourceModelDirectoryTexField.setText(SourceModelFile.DEFAULT_DIR); + } + } +} diff --git a/src/com/magento/idea/magento2plugin/actions/generation/dialog/event/eavdialog/AttributeSourceRelationsItemListener.java b/src/com/magento/idea/magento2plugin/actions/generation/dialog/event/eavdialog/AttributeSourceRelationsItemListener.java new file mode 100644 index 000000000..ccf84ceb3 --- /dev/null +++ b/src/com/magento/idea/magento2plugin/actions/generation/dialog/event/eavdialog/AttributeSourceRelationsItemListener.java @@ -0,0 +1,28 @@ +/* + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +package com.magento.idea.magento2plugin.actions.generation.dialog.event.eavdialog; + +import com.magento.idea.magento2plugin.magento.packages.eav.AttributeSourceModel; +import java.awt.event.ItemEvent; +import java.awt.event.ItemListener; +import javax.swing.JPanel; + +public class AttributeSourceRelationsItemListener implements ItemListener { + private final JPanel customSourcePanel; + + public AttributeSourceRelationsItemListener(final JPanel customSourcePanel) { + this.customSourcePanel = customSourcePanel; + } + + @Override + public void itemStateChanged(final ItemEvent itemEvent) { + final String selectedSource = itemEvent.getItem().toString(); + + customSourcePanel.setVisible( + selectedSource.equals(AttributeSourceModel.GENERATE_SOURCE.getSource()) + ); + } +} diff --git a/src/com/magento/idea/magento2plugin/actions/generation/dialog/event/eavdialog/DataPatchNameAdapter.java b/src/com/magento/idea/magento2plugin/actions/generation/dialog/event/eavdialog/DataPatchNameAdapter.java new file mode 100644 index 000000000..536b1a487 --- /dev/null +++ b/src/com/magento/idea/magento2plugin/actions/generation/dialog/event/eavdialog/DataPatchNameAdapter.java @@ -0,0 +1,88 @@ +/* + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +package com.magento.idea.magento2plugin.actions.generation.dialog.event.eavdialog; + +import com.intellij.ui.DocumentAdapter; +import com.magento.idea.magento2plugin.actions.generation.dialog.util.SplitEavAttributeCodeUtil; +import javax.swing.JTextField; +import javax.swing.event.DocumentEvent; +import javax.swing.text.BadLocationException; +import javax.swing.text.Document; +import org.codehaus.plexus.util.StringUtils; +import org.jetbrains.annotations.NotNull; + +public class DataPatchNameAdapter extends DocumentAdapter { + + private static final String NAME_PREFIX = "Add"; + private static final String NAME_SUFFIX = "Attribute"; + private final String entityType; + private final JTextField dataPatchNameTextField; + + /** + * Constructor. + * + * @param dataPatchNameTextField JTextField + */ + public DataPatchNameAdapter(final JTextField dataPatchNameTextField) { + super(); + + this.dataPatchNameTextField = dataPatchNameTextField; + entityType = ""; + } + + /** + * Constructor. + * + * @param dataPatchNameTextField JTextField + * @param entityType String + */ + public DataPatchNameAdapter( + final JTextField dataPatchNameTextField, + final String entityType + ) { + super(); + + this.dataPatchNameTextField = dataPatchNameTextField; + this.entityType = entityType; + } + + @Override + protected void textChanged(@NotNull final DocumentEvent event) { + final Document document = event.getDocument(); + + try { + final String attributeCode = document.getText( + 0, document.getEndPosition().getOffset() + ).trim(); + updateDataPatchFileName(attributeCode); + } catch (BadLocationException badLocationException) { + return; + } + } + + private void updateDataPatchFileName(final String attributeCode) { + if (attributeCode.isEmpty()) { + dataPatchNameTextField.setText(""); + + return; + } + + String fileName = ""; + + for (final String fileNamePart : SplitEavAttributeCodeUtil.execute(attributeCode)) { + fileName = String.join("", fileName, StringUtils.capitalise(fileNamePart)); + } + + dataPatchNameTextField.setText( + String.join( + "", + NAME_PREFIX, + fileName, + StringUtils.capitalise(entityType), NAME_SUFFIX + ) + ); + } +} diff --git a/src/com/magento/idea/magento2plugin/actions/generation/dialog/event/eavdialog/EavAttributeInputItemListener.java b/src/com/magento/idea/magento2plugin/actions/generation/dialog/event/eavdialog/EavAttributeInputItemListener.java new file mode 100644 index 000000000..fbe835fec --- /dev/null +++ b/src/com/magento/idea/magento2plugin/actions/generation/dialog/event/eavdialog/EavAttributeInputItemListener.java @@ -0,0 +1,47 @@ +/* + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +package com.magento.idea.magento2plugin.actions.generation.dialog.event.eavdialog; + +import com.magento.idea.magento2plugin.actions.generation.data.ui.ComboBoxItemData; +import com.magento.idea.magento2plugin.magento.packages.eav.AttributeSourceModel; +import com.magento.idea.magento2plugin.magento.packages.uicomponent.AvailableSourcesByInput; +import java.awt.event.ItemEvent; +import java.awt.event.ItemListener; +import java.util.List; +import javax.swing.JComboBox; + +public class EavAttributeInputItemListener implements ItemListener { + private final JComboBox sourceComboBox; + + public EavAttributeInputItemListener(final JComboBox sourceComboBox) { + this.sourceComboBox = sourceComboBox; + } + + @Override + public void itemStateChanged(final ItemEvent itemEvent) { + final String selectedInput = itemEvent.getItem().toString(); + + final List availableSources = + new AvailableSourcesByInput(selectedInput).getItems(); + sourceComboBox.removeAllItems(); + + final ComboBoxItemData defaultSourceItem = new ComboBoxItemData( + AttributeSourceModel.NULLABLE_SOURCE.name(), + AttributeSourceModel.NULLABLE_SOURCE.getSource() + ); + + sourceComboBox.addItem(defaultSourceItem); + sourceComboBox.setSelectedItem(defaultSourceItem); + + if (availableSources.isEmpty()) { + return; + } + + for (final ComboBoxItemData comboBoxItemData : availableSources) { + sourceComboBox.addItem(comboBoxItemData); + } + } +} diff --git a/src/com/magento/idea/magento2plugin/actions/generation/dialog/event/eavdialog/OptionsPanelVisibilityChangeListener.java b/src/com/magento/idea/magento2plugin/actions/generation/dialog/event/eavdialog/OptionsPanelVisibilityChangeListener.java new file mode 100644 index 000000000..6bc0cab76 --- /dev/null +++ b/src/com/magento/idea/magento2plugin/actions/generation/dialog/event/eavdialog/OptionsPanelVisibilityChangeListener.java @@ -0,0 +1,45 @@ +/* + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +package com.magento.idea.magento2plugin.actions.generation.dialog.event.eavdialog; + +import com.magento.idea.magento2plugin.actions.generation.data.ui.ComboBoxItemData; +import com.magento.idea.magento2plugin.magento.packages.eav.AttributeInput; +import com.magento.idea.magento2plugin.magento.packages.eav.AttributeSourceModel; +import java.awt.event.ItemEvent; +import java.awt.event.ItemListener; +import javax.swing.JComboBox; +import javax.swing.JPanel; +import org.jetbrains.annotations.NotNull; + +public class OptionsPanelVisibilityChangeListener implements ItemListener { + private final JPanel optionsPanel; + private final JComboBox inputComboBox; + + public OptionsPanelVisibilityChangeListener( + @NotNull final JPanel optionsPanel, + @NotNull final JComboBox inputComboBox + ) { + this.optionsPanel = optionsPanel; + this.inputComboBox = inputComboBox; + } + + @Override + public void itemStateChanged(final ItemEvent itemEvent) { + final String selectedSource = itemEvent.getItem().toString(); + + final ComboBoxItemData selectedInputItem = + (ComboBoxItemData) inputComboBox.getSelectedItem(); + final String selectedInput = selectedInputItem == null ? "" : selectedInputItem.toString(); + + final boolean isAttributeWithoutSource = + AttributeSourceModel.NULLABLE_SOURCE.getSource().equals(selectedSource); + final boolean isAllowedInput = + AttributeInput.SELECT.getInput().equals(selectedInput) + || AttributeInput.MULTISELECT.getInput().equals(selectedInput); + + optionsPanel.setVisible(isAllowedInput && isAttributeWithoutSource); + } +} diff --git a/src/com/magento/idea/magento2plugin/actions/generation/dialog/event/eavdialog/SourceModelNameAdapter.java b/src/com/magento/idea/magento2plugin/actions/generation/dialog/event/eavdialog/SourceModelNameAdapter.java new file mode 100644 index 000000000..1128e2ef1 --- /dev/null +++ b/src/com/magento/idea/magento2plugin/actions/generation/dialog/event/eavdialog/SourceModelNameAdapter.java @@ -0,0 +1,54 @@ +/* + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +package com.magento.idea.magento2plugin.actions.generation.dialog.event.eavdialog; + +import com.intellij.ui.DocumentAdapter; +import com.magento.idea.magento2plugin.actions.generation.dialog.util.SplitEavAttributeCodeUtil; +import javax.swing.JTextField; +import javax.swing.event.DocumentEvent; +import javax.swing.text.BadLocationException; +import javax.swing.text.Document; +import org.codehaus.plexus.util.StringUtils; +import org.jetbrains.annotations.NotNull; + +public class SourceModelNameAdapter extends DocumentAdapter { + + private final JTextField sourceModelNameTexField; + + public SourceModelNameAdapter(final JTextField sourceModelNameTexField) { + super(); + this.sourceModelNameTexField = sourceModelNameTexField; + } + + @Override + protected void textChanged(@NotNull final DocumentEvent event) { + final Document document = event.getDocument(); + try { + final String attributeCode = document.getText( + 0, document.getEndPosition().getOffset() + ).trim(); + updateSourceModelName(attributeCode); + } catch (BadLocationException badLocationException) { + return; + } + } + + private void updateSourceModelName(final String attributeCode) { + if (attributeCode.isEmpty()) { + sourceModelNameTexField.setText(""); + + return; + } + + final StringBuilder sourceModelClassName = new StringBuilder(); + + for (final String codePart : SplitEavAttributeCodeUtil.execute(attributeCode)) { + sourceModelClassName.append(StringUtils.capitalise(codePart)); + } + + sourceModelNameTexField.setText(sourceModelClassName.toString()); + } +} diff --git a/src/com/magento/idea/magento2plugin/actions/generation/dialog/util/SplitEavAttributeCodeUtil.java b/src/com/magento/idea/magento2plugin/actions/generation/dialog/util/SplitEavAttributeCodeUtil.java new file mode 100644 index 000000000..3f70f962c --- /dev/null +++ b/src/com/magento/idea/magento2plugin/actions/generation/dialog/util/SplitEavAttributeCodeUtil.java @@ -0,0 +1,27 @@ +/* + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + * + */ + +package com.magento.idea.magento2plugin.actions.generation.dialog.util; + +import org.jetbrains.annotations.NotNull; + +public final class SplitEavAttributeCodeUtil { + + public static final String ATTRIBUTE_SEPARATOR = "_"; + + private SplitEavAttributeCodeUtil(){} + + /** + * Return separated attribute code. + * + * @param attributeCode String + * @return String[] + */ + @NotNull + public static String[] execute(final String attributeCode) { + return attributeCode.split(ATTRIBUTE_SEPARATOR); + } +} diff --git a/src/com/magento/idea/magento2plugin/actions/generation/dialog/util/eavdialog/AttributeUtil.java b/src/com/magento/idea/magento2plugin/actions/generation/dialog/util/eavdialog/AttributeUtil.java new file mode 100644 index 000000000..1199fff64 --- /dev/null +++ b/src/com/magento/idea/magento2plugin/actions/generation/dialog/util/eavdialog/AttributeUtil.java @@ -0,0 +1,90 @@ +/* + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +package com.magento.idea.magento2plugin.actions.generation.dialog.util.eavdialog; + +import com.magento.idea.magento2plugin.actions.generation.data.SourceModelData; +import com.magento.idea.magento2plugin.actions.generation.data.ui.ComboBoxItemData; +import com.magento.idea.magento2plugin.magento.files.SourceModelFile; +import com.magento.idea.magento2plugin.magento.packages.eav.AttributeScope; +import com.magento.idea.magento2plugin.magento.packages.eav.AttributeSourceModel; + +public final class AttributeUtil { + + private AttributeUtil() {} + + /** + * Return actual source class by selected item. + * + * @param selectedSourceItem ComboBoxItemData + * @param sourceModelData SourceModelData + * @return String + */ + public static String getSourceClassBySelectedItem( + final ComboBoxItemData selectedSourceItem, + final SourceModelData sourceModelData + ) { + if (selectedSourceItem == null + || selectedSourceItem.getText().equals( + AttributeSourceModel.NULLABLE_SOURCE.getSource() + )) { + return null; + } + + if (selectedSourceItem.getText().equals(AttributeSourceModel.GENERATE_SOURCE.getSource()) + && sourceModelData != null) { + + return "\\" + new SourceModelFile( + sourceModelData.getModuleName(), + sourceModelData.getClassName(), + sourceModelData.getDirectory() + ).getClassFqn(); + } + + return selectedSourceItem.toString(); + } + + /** + * Return actual scope class by selected item. + * + * @param selectedScopeItem ComboBoxItemData + * @return String + */ + public static String getScopeClassBySelectedItem(final ComboBoxItemData selectedScopeItem) { + if (selectedScopeItem != null) { + return selectedScopeItem.getKey().trim(); + } + + return AttributeScope.GLOBAL.getScope(); + } + + /** + * Return actual input type by selected item. + * + * @param selectedInputItem ComboBoxItemData + * @return String + */ + public static String getInputTypeBySelectedItem(final ComboBoxItemData selectedInputItem) { + if (selectedInputItem != null) { + return selectedInputItem.getText().trim(); + } + + return ""; + } + + /** + * Return actual backend type by selected item. + * + * @param selectedTypeItem ComboBoxItemData + * @return String + */ + public static String getBackendTypeBySelectedItem(final ComboBoxItemData selectedTypeItem) { + if (selectedTypeItem != null) { + return selectedTypeItem.getText(); + } + + return ""; + } +} diff --git a/src/com/magento/idea/magento2plugin/actions/generation/dialog/validator/annotation/RuleRegistry.java b/src/com/magento/idea/magento2plugin/actions/generation/dialog/validator/annotation/RuleRegistry.java index 14a5ee1de..cf479956b 100644 --- a/src/com/magento/idea/magento2plugin/actions/generation/dialog/validator/annotation/RuleRegistry.java +++ b/src/com/magento/idea/magento2plugin/actions/generation/dialog/validator/annotation/RuleRegistry.java @@ -12,6 +12,7 @@ import com.magento.idea.magento2plugin.actions.generation.dialog.validator.rule.AlphanumericWithUnderscoreRule; import com.magento.idea.magento2plugin.actions.generation.dialog.validator.rule.BoxNotEmptyRule; import com.magento.idea.magento2plugin.actions.generation.dialog.validator.rule.CliCommandRule; +import com.magento.idea.magento2plugin.actions.generation.dialog.validator.rule.CommaSeparatedStringRule; import com.magento.idea.magento2plugin.actions.generation.dialog.validator.rule.ConfigPathRule; import com.magento.idea.magento2plugin.actions.generation.dialog.validator.rule.CronScheduleRule; import com.magento.idea.magento2plugin.actions.generation.dialog.validator.rule.DirectoryRule; @@ -59,7 +60,8 @@ public enum RuleRegistry { EXTENDED_NUMERIC(ExtendedNumericRule.class), TABLE_NAME_LENGTH(TableNameLength.class), MENU_IDENTIFIER(MenuIdentifierRule.class), - LAYOUT_NAME(LayoutNameRule.class); + LAYOUT_NAME(LayoutNameRule.class), + COMMA_SEPARATED_STRING(CommaSeparatedStringRule.class); private Class rule; diff --git a/src/com/magento/idea/magento2plugin/actions/generation/dialog/validator/rule/CommaSeparatedStringRule.java b/src/com/magento/idea/magento2plugin/actions/generation/dialog/validator/rule/CommaSeparatedStringRule.java new file mode 100644 index 000000000..a61a6a2d7 --- /dev/null +++ b/src/com/magento/idea/magento2plugin/actions/generation/dialog/validator/rule/CommaSeparatedStringRule.java @@ -0,0 +1,22 @@ +/* + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +package com.magento.idea.magento2plugin.actions.generation.dialog.validator.rule; + +import com.magento.idea.magento2plugin.util.RegExUtil; + +public class CommaSeparatedStringRule implements ValidationRule { + public static final String MESSAGE = "validator.commaSeparatedString.isNotValid"; + private static final ValidationRule INSTANCE = new CommaSeparatedStringRule(); + + @Override + public boolean check(final String value) { + return value.isEmpty() || value.matches(RegExUtil.Magento.COMMA_SEPARATED_STRING); + } + + public static ValidationRule getInstance() { + return INSTANCE; + } +} diff --git a/src/com/magento/idea/magento2plugin/actions/generation/eavattribute/NewCategoryEavAttributeAction.java b/src/com/magento/idea/magento2plugin/actions/generation/eavattribute/NewCategoryEavAttributeAction.java new file mode 100644 index 000000000..446247f02 --- /dev/null +++ b/src/com/magento/idea/magento2plugin/actions/generation/eavattribute/NewCategoryEavAttributeAction.java @@ -0,0 +1,30 @@ +/* + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +package com.magento.idea.magento2plugin.actions.generation.eavattribute; + +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiDirectory; +import com.magento.idea.magento2plugin.MagentoIcons; +import com.magento.idea.magento2plugin.actions.generation.dialog.NewCategoryEavAttributeDialog; +import com.magento.idea.magento2plugin.actions.generation.dialog.eavattribute.EavAttributeDialog; + +public class NewCategoryEavAttributeAction extends NewEavAttributeAction { + + public static final String ACTION_NAME = "Category Attribute"; + public static final String ACTION_DESCRIPTION = "Create a new Magento 2 EAV Catalog Attribute"; + + public NewCategoryEavAttributeAction() { + super(ACTION_NAME, ACTION_DESCRIPTION, MagentoIcons.MODULE); + } + + @Override + protected EavAttributeDialog getDialogWindow( + final Project project, + final PsiDirectory directory + ) { + return new NewCategoryEavAttributeDialog(project, directory, ACTION_NAME); + } +} diff --git a/src/com/magento/idea/magento2plugin/actions/generation/eavattribute/NewEavAttributeAction.java b/src/com/magento/idea/magento2plugin/actions/generation/eavattribute/NewEavAttributeAction.java new file mode 100644 index 000000000..698917073 --- /dev/null +++ b/src/com/magento/idea/magento2plugin/actions/generation/eavattribute/NewEavAttributeAction.java @@ -0,0 +1,60 @@ +/* + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +package com.magento.idea.magento2plugin.actions.generation.eavattribute; + +import com.intellij.ide.IdeView; +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.CommonDataKeys; +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.actionSystem.LangDataKeys; +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiDirectory; +import com.magento.idea.magento2plugin.actions.generation.dialog.eavattribute.EavAttributeDialog; +import javax.swing.Icon; +import org.jetbrains.annotations.NotNull; + +public abstract class NewEavAttributeAction extends AnAction { + public NewEavAttributeAction( + final String actionName, + final String actionDescription, + final Icon icon + ) { + super(actionName, actionDescription, icon); + } + + @Override + public void actionPerformed(final @NotNull AnActionEvent event) { + final DataContext dataContext = event.getDataContext(); + final IdeView view = LangDataKeys.IDE_VIEW.getData(dataContext); + if (view == null) { + return; + } + + final Project project = CommonDataKeys.PROJECT.getData(dataContext); + if (project == null) { + return; + } + + final PsiDirectory directory = view.getOrChooseDirectory(); + if (directory == null) { + return; + } + + final EavAttributeDialog eavAttributeDialog = getDialogWindow(project, directory); + eavAttributeDialog.open(); + } + + @Override + public boolean isDumbAware() { + return false; + } + + protected abstract EavAttributeDialog getDialogWindow( + Project project, + PsiDirectory directory + ); +} diff --git a/src/com/magento/idea/magento2plugin/actions/generation/eavattribute/NewProductEavAttributeAction.java b/src/com/magento/idea/magento2plugin/actions/generation/eavattribute/NewProductEavAttributeAction.java new file mode 100644 index 000000000..1fa44915c --- /dev/null +++ b/src/com/magento/idea/magento2plugin/actions/generation/eavattribute/NewProductEavAttributeAction.java @@ -0,0 +1,30 @@ +/* + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +package com.magento.idea.magento2plugin.actions.generation.eavattribute; + +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiDirectory; +import com.magento.idea.magento2plugin.MagentoIcons; +import com.magento.idea.magento2plugin.actions.generation.dialog.NewProductEavAttributeDialog; +import com.magento.idea.magento2plugin.actions.generation.dialog.eavattribute.EavAttributeDialog; + +public class NewProductEavAttributeAction extends NewEavAttributeAction { + + public static final String ACTION_NAME = "Product Attribute"; + public static final String ACTION_DESCRIPTION = "Create a new Magento 2 EAV Product Attribute"; + + public NewProductEavAttributeAction() { + super(ACTION_NAME, ACTION_DESCRIPTION, MagentoIcons.MODULE); + } + + @Override + protected EavAttributeDialog getDialogWindow( + final Project project, + final PsiDirectory directory + ) { + return new NewProductEavAttributeDialog(project, directory, ACTION_NAME); + } +} diff --git a/src/com/magento/idea/magento2plugin/actions/generation/generator/CategoryFormXmlGenerator.java b/src/com/magento/idea/magento2plugin/actions/generation/generator/CategoryFormXmlGenerator.java new file mode 100644 index 000000000..bc71ab122 --- /dev/null +++ b/src/com/magento/idea/magento2plugin/actions/generation/generator/CategoryFormXmlGenerator.java @@ -0,0 +1,232 @@ +/* + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + * + */ + +package com.magento.idea.magento2plugin.actions.generation.generator; + +import com.intellij.openapi.command.WriteCommandAction; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiDirectory; +import com.intellij.psi.PsiDocumentManager; +import com.intellij.psi.PsiFile; +import com.intellij.psi.codeStyle.CodeStyleManager; +import com.intellij.psi.xml.XmlFile; +import com.intellij.psi.xml.XmlTag; +import com.magento.idea.magento2plugin.actions.generation.data.CategoryFormXmlData; +import com.magento.idea.magento2plugin.actions.generation.generator.util.DirectoryGenerator; +import com.magento.idea.magento2plugin.actions.generation.generator.util.FileFromTemplateGenerator; +import com.magento.idea.magento2plugin.actions.generation.generator.util.GetCodeTemplateUtil; +import com.magento.idea.magento2plugin.actions.generation.generator.util.XmlFilePositionUtil; +import com.magento.idea.magento2plugin.bundles.CommonBundle; +import com.magento.idea.magento2plugin.bundles.ValidatorBundle; +import com.magento.idea.magento2plugin.indexes.ModuleIndex; +import com.magento.idea.magento2plugin.magento.files.CategoryFormXmlFile; +import com.magento.idea.magento2plugin.magento.packages.Areas; +import com.magento.idea.magento2plugin.magento.packages.File; +import com.magento.idea.magento2plugin.magento.packages.eav.AttributeInput; +import com.magento.idea.magento2plugin.util.magento.FileBasedIndexUtil; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Properties; +import javax.swing.JOptionPane; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +public class CategoryFormXmlGenerator extends FileGenerator { + + private final CategoryFormXmlData categoryFormXmlData; + private final String moduleName; + private final DirectoryGenerator directoryGenerator; + private final FileFromTemplateGenerator fileFromTemplateGenerator; + private final GetCodeTemplateUtil getCodeTemplateUtil; + private final XmlFilePositionUtil xmlFilePositionUtil; + private final ValidatorBundle validatorBundle; + private final CommonBundle commonBundle; + private boolean allowedFieldsetNodeInclude = true; + + /** + * Category form XML Generator. + * + * @param categoryFormXmlData Category form data class + * @param project Project + * @param moduleName module name + */ + public CategoryFormXmlGenerator( + final @NotNull CategoryFormXmlData categoryFormXmlData, + final @NotNull Project project, + final @NotNull String moduleName + ) { + super(project); + + this.categoryFormXmlData = categoryFormXmlData; + this.moduleName = moduleName; + this.directoryGenerator = DirectoryGenerator.getInstance(); + this.xmlFilePositionUtil = new XmlFilePositionUtil(); + this.fileFromTemplateGenerator = new FileFromTemplateGenerator(project); + this.getCodeTemplateUtil = new GetCodeTemplateUtil(project); + this.validatorBundle = new ValidatorBundle(); + this.commonBundle = new CommonBundle(); + } + + @Override + public PsiFile generate(final String actionName) { + final PsiDirectory directory = getFileDirectory(); + + PsiFile categoryAdminFormXmlFile = FileBasedIndexUtil.findModuleViewFile( + CategoryFormXmlFile.FILE_NAME, + Areas.getAreaByString(Areas.adminhtml.name()), + moduleName, + project, + CategoryFormXmlFile.SUB_DIRECTORY + ); + + if (categoryAdminFormXmlFile == null) { + categoryAdminFormXmlFile = fileFromTemplateGenerator.generate( + new CategoryFormXmlFile(), + new Properties(), + directory, + actionName + ); + } + + if (categoryAdminFormXmlFile == null) { + showDeclarationCannotBeCreatedDialog(); + return null; + } + + final XmlTag rootTag = ((XmlFile) categoryAdminFormXmlFile).getRootTag(); + + if (rootTag == null) { + showDeclarationCannotBeCreatedDialog(); + return null; + } + + final PsiDocumentManager psiDocumentManager = PsiDocumentManager.getInstance(project); + final Document document = psiDocumentManager.getDocument(categoryAdminFormXmlFile); + + + if (document == null) { + showDeclarationCannotBeCreatedDialog(); + return null; + } + + try { + final XmlTag matchedFieldsetByName = findMatchedFieldsetByName( + findFieldsetTagsInRoot(rootTag), + categoryFormXmlData.getFieldSetName() + ); + + allowedFieldsetNodeInclude = matchedFieldsetByName == null; + + writeInFile( + matchedFieldsetByName == null ? rootTag : matchedFieldsetByName, + psiDocumentManager, + document + ); + } catch (IOException e) { + showDeclarationCannotBeCreatedDialog(); + } + + return reformatFile(categoryAdminFormXmlFile); + } + + private void showDeclarationCannotBeCreatedDialog() { + JOptionPane.showMessageDialog( + null, + validatorBundle.message( + "validator.file.cantBeCreated", + "Category Admin Form XML file" + ), + commonBundle.message("common.error"), + JOptionPane.ERROR_MESSAGE + ); + } + + private PsiDirectory getFileDirectory() { + PsiDirectory directory = + new ModuleIndex(project).getModuleDirectoryByModuleName(moduleName); + + for (final String handlerDirectory: CategoryFormXmlFile.DIRECTORY.split(File.separator)) { + directory = directoryGenerator.findOrCreateSubdirectory( + directory, + handlerDirectory + ); + } + return directory; + } + + private void writeInFile( + final XmlTag targetTag, + final PsiDocumentManager psiDocumentManager, + final Document document + ) throws IOException { + final int insertPosition = xmlFilePositionUtil.getEndPositionOfTag(targetTag); + + final String declarationXml = + getCodeTemplateUtil.execute( + CategoryFormXmlFile.DECLARATION_TEMPLATE, + getAttributes() + ); + + WriteCommandAction.runWriteCommandAction(project, () -> { + document.insertString(insertPosition, declarationXml); + psiDocumentManager.commitDocument(document); + }); + } + + private PsiFile reformatFile(final PsiFile categoryAdminFormXmlFile) { + WriteCommandAction.runWriteCommandAction(project, () -> { + CodeStyleManager.getInstance(project).reformat(categoryAdminFormXmlFile); + }); + + return categoryAdminFormXmlFile; + } + + @NotNull + private List findFieldsetTagsInRoot(final XmlTag rootTag) { + final XmlTag[] subTags = rootTag.getSubTags(); + final List fieldsetList = new ArrayList<>(); + + for (final XmlTag subTag: subTags) { + if (subTag.getName().equals(CategoryFormXmlFile.XML_TAG_FIELDSET)) { + fieldsetList.add(subTag); + } + } + return fieldsetList; + } + + @Nullable + private XmlTag findMatchedFieldsetByName( + final List fieldsetList, + final String fieldsetName + ) { + for (final XmlTag fieldset: fieldsetList) { + final String attributeValue = fieldset.getAttributeValue( + CategoryFormXmlFile.XML_ATTR_FIELDSET_NAME + ); + if (attributeValue != null && attributeValue.equals(fieldsetName)) { + return fieldset; + } + } + + return null; + } + + @Override + protected void fillAttributes(final Properties attributes) { + attributes.setProperty("FIELDSET_NAME", categoryFormXmlData.getFieldSetName()); + attributes.setProperty("FIELD_NAME", categoryFormXmlData.getFieldName()); + attributes.setProperty("SORT_ORDER", Integer.toString(categoryFormXmlData.getSortOrder())); + attributes.setProperty("FORM_ELEMENT", GetFormElementByAttributeInputUtil.execute( + AttributeInput.getAttributeInputByCode(categoryFormXmlData.getAttributeInput()) + )); + + if (allowedFieldsetNodeInclude) { + attributes.setProperty("INCLUDE_FIELDSET", "include"); + } + } +} diff --git a/src/com/magento/idea/magento2plugin/actions/generation/generator/CustomerEavAttributePatchGenerator.java b/src/com/magento/idea/magento2plugin/actions/generation/generator/CustomerEavAttributePatchGenerator.java new file mode 100644 index 000000000..890be334d --- /dev/null +++ b/src/com/magento/idea/magento2plugin/actions/generation/generator/CustomerEavAttributePatchGenerator.java @@ -0,0 +1,114 @@ +/* + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +package com.magento.idea.magento2plugin.actions.generation.generator; + +import com.intellij.openapi.project.Project; +import com.magento.idea.magento2plugin.actions.generation.data.CustomerEntityData; +import com.magento.idea.magento2plugin.actions.generation.data.EavEntityDataInterface; +import com.magento.idea.magento2plugin.actions.generation.generator.util.PhpClassGeneratorUtil; +import com.magento.idea.magento2plugin.magento.files.AbstractPhpFile; +import com.magento.idea.magento2plugin.magento.files.CustomerEavAttributeDataPatchFile; +import com.magento.idea.magento2plugin.magento.packages.eav.CustomerForm; +import com.magento.idea.magento2plugin.magento.packages.eav.DataPatchDependency; +import java.util.ArrayList; +import java.util.List; +import java.util.Properties; +import org.jetbrains.annotations.NotNull; + +public class CustomerEavAttributePatchGenerator extends EavAttributeSetupPatchGenerator { + + private final EavEntityDataInterface data; + + public CustomerEavAttributePatchGenerator( + final @NotNull EavEntityDataInterface data, + final Project project + ) { + this(data, project, true); + } + + /** + * Php file generator constructor. + * + * @param project Project + * @param checkFileAlreadyExists boolean + */ + public CustomerEavAttributePatchGenerator( + final @NotNull EavEntityDataInterface data, + final @NotNull Project project, + final boolean checkFileAlreadyExists + ) { + super(data, project, checkFileAlreadyExists); + this.data = data; + } + + @Override + protected AbstractPhpFile initFile() { + return new CustomerEavAttributeDataPatchFile(data.getModuleName(), data.getDataPatchName()); + } + + @Override + protected void fillAttributes(final Properties attributes) { + super.fillAttributes(attributes); + phpClassTypesBuilder + .append( + "EAV_CONFIG_CLASS", + DataPatchDependency.EAV_CONFIG.getClassPatch() + ).append( + "ATTRIBUTE_RESOURCE", + DataPatchDependency.ATTRIBUTE_RESOURCE.getClassPatch() + ).append( + "CUSTOMER_METADATA_INTERFACE", + DataPatchDependency.CUSTOMER_METADATA_INTERFACE.getClassPatch() + ); + + final String selectedCustomerForms = getFormsForAttribute((CustomerEntityData) data); + + if (!selectedCustomerForms.isEmpty()) { + phpClassTypesBuilder.appendProperty("CUSTOMER_FORMS", selectedCustomerForms); + } + + phpClassTypesBuilder.mergeProperties(attributes); + + attributes.setProperty( + "USES", + PhpClassGeneratorUtil.formatUses(phpClassTypesBuilder.getUses()) + ); + } + + private String getFormsForAttribute(final CustomerEntityData customerEntityData) { + final List usedInForms = new ArrayList<>(); + + if (customerEntityData.isUseInAdminhtmlCustomerForm()) { + usedInForms.add( + "'" + CustomerForm.ADMINHTML_CUSTOMER.getFormCode() + "'" + ); + } + + if (customerEntityData.isUseInAdminhtmlCheckoutForm()) { + usedInForms.add( + "'" + CustomerForm.ADMINHTML_CHECKOUT.getFormCode() + "'" + ); + } + + if (customerEntityData.isUseInCustomerAccountCreateForm()) { + usedInForms.add( + "'" + CustomerForm.CUSTOMER_ACCOUNT_CREATE.getFormCode() + "'" + ); + } + + if (customerEntityData.isUseInCustomerAccountEditForm()) { + usedInForms.add( + "'" + CustomerForm.CUSTOMER_ACCOUNT_EDIT.getFormCode() + "'" + ); + } + + if (usedInForms.isEmpty()) { + return ""; + } + + return String.join(",", usedInForms); + } +} diff --git a/src/com/magento/idea/magento2plugin/actions/generation/generator/EavAttributeSetupPatchGenerator.java b/src/com/magento/idea/magento2plugin/actions/generation/generator/EavAttributeSetupPatchGenerator.java new file mode 100644 index 000000000..3339abf99 --- /dev/null +++ b/src/com/magento/idea/magento2plugin/actions/generation/generator/EavAttributeSetupPatchGenerator.java @@ -0,0 +1,103 @@ +/* + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +package com.magento.idea.magento2plugin.actions.generation.generator; + +import com.intellij.openapi.project.Project; +import com.magento.idea.magento2plugin.actions.generation.data.EavEntityDataInterface; +import com.magento.idea.magento2plugin.actions.generation.generator.util.PhpClassGeneratorUtil; +import com.magento.idea.magento2plugin.actions.generation.generator.util.PhpClassTypesBuilder; +import com.magento.idea.magento2plugin.actions.generation.generator.util.eav.AttributeMapperFactory; +import com.magento.idea.magento2plugin.actions.generation.generator.util.eav.AttributeMapperInterface; +import com.magento.idea.magento2plugin.magento.files.AbstractPhpFile; +import com.magento.idea.magento2plugin.magento.files.EavAttributeDataPatchFile; +import com.magento.idea.magento2plugin.magento.packages.eav.DataPatchDependency; +import java.util.List; +import java.util.Properties; +import org.jetbrains.annotations.NotNull; + +public class EavAttributeSetupPatchGenerator extends PhpFileGenerator { + + private final EavEntityDataInterface data; + protected final PhpClassTypesBuilder phpClassTypesBuilder; + + /** + * Constructor. + * + * @param data EavEntityDataInterface + * @param project Project + */ + public EavAttributeSetupPatchGenerator( + final @NotNull EavEntityDataInterface data, + final Project project + ) { + this(data, project, true); + } + + /** + * Php file generator constructor. + * + * @param project Project + * @param checkFileAlreadyExists boolean + */ + public EavAttributeSetupPatchGenerator( + final @NotNull EavEntityDataInterface data, + final @NotNull Project project, + final boolean checkFileAlreadyExists + ) { + super(project, checkFileAlreadyExists); + this.data = data; + this.phpClassTypesBuilder = new PhpClassTypesBuilder(); + } + + @Override + protected AbstractPhpFile initFile() { + return new EavAttributeDataPatchFile(data.getModuleName(), data.getDataPatchName()); + } + + @Override + protected void fillAttributes(final Properties attributes) { + phpClassTypesBuilder + .appendProperty("CLASS_NAME", data.getDataPatchName()) + .appendProperty("NAMESPACE", this.getFile().getNamespace()) + .appendProperty("ENTITY_CLASS", data.getEntityClass()) + .appendProperty("ATTRIBUTE_CODE", data.getCode()) + .appendProperty("ATTRIBUTE_SET", String.join("->", getAttributesList(data))) + .append( + "IMPLEMENTS", + DataPatchDependency.DATA_PATCH_INTERFACE.getClassPatch() + ) + .append( + "ENTITY_CLASS", + data.getEntityClass() + ) + .append( + "MODULE_DATA_SETUP_INTERFACE", + DataPatchDependency.MODULE_DATA_SETUP_INTERFACE.getClassPatch() + ) + .append( + "EAV_SETUP_FACTORY", + DataPatchDependency.EAV_SETUP_FACTORY.getClassPatch() + ) + .append( + "EAV_SETUP", + DataPatchDependency.ENV_SETUP.getClassPatch() + ) + .mergeProperties(attributes); + attributes.setProperty( + "USES", + PhpClassGeneratorUtil.formatUses(phpClassTypesBuilder.getUses()) + ); + } + + private List getAttributesList(final EavEntityDataInterface eavEntityData) { + final AttributeMapperFactory attributeMapperFactory = new AttributeMapperFactory(); + final AttributeMapperInterface attributeMapper = attributeMapperFactory.createByEntityClass( + eavEntityData.getEntityClass() + ); + + return attributeMapper.mapAttributesByEntityData(eavEntityData); + } +} diff --git a/src/com/magento/idea/magento2plugin/actions/generation/generator/GetFormElementByAttributeInputUtil.java b/src/com/magento/idea/magento2plugin/actions/generation/generator/GetFormElementByAttributeInputUtil.java new file mode 100644 index 000000000..078ab883f --- /dev/null +++ b/src/com/magento/idea/magento2plugin/actions/generation/generator/GetFormElementByAttributeInputUtil.java @@ -0,0 +1,43 @@ +/* + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + * + */ + +package com.magento.idea.magento2plugin.actions.generation.generator; + +import com.magento.idea.magento2plugin.magento.packages.eav.AttributeInput; +import com.magento.idea.magento2plugin.magento.packages.uicomponent.FormElementType; + +public final class GetFormElementByAttributeInputUtil { + + private GetFormElementByAttributeInputUtil(){} + + /** + * Returns for available form element by attribute input type. + * + * @param inputType AttributeInput + * @return String + */ + public static String execute(final AttributeInput inputType) { + switch (inputType) { + case TEXT: + return FormElementType.INPUT.getType(); + case TEXTAREA: + return FormElementType.TEXTAREA.getType(); + case BOOLEAN: + case SELECT: + return FormElementType.SELECT.getType(); + case MULTISELECT: + return FormElementType.MULTISELECT.getType(); + case DATE: + return FormElementType.DATE.getType(); + case PRICE: + return FormElementType.PRICE.getType(); + case HIDDEN: + return FormElementType.HIDDEN.getType(); + default: + return ""; + } + } +} diff --git a/src/com/magento/idea/magento2plugin/actions/generation/generator/SourceModelGenerator.java b/src/com/magento/idea/magento2plugin/actions/generation/generator/SourceModelGenerator.java new file mode 100644 index 000000000..23dc558e6 --- /dev/null +++ b/src/com/magento/idea/magento2plugin/actions/generation/generator/SourceModelGenerator.java @@ -0,0 +1,74 @@ +/* + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +package com.magento.idea.magento2plugin.actions.generation.generator; + +import com.intellij.openapi.project.Project; +import com.magento.idea.magento2plugin.actions.generation.data.SourceModelData; +import com.magento.idea.magento2plugin.actions.generation.generator.util.PhpClassGeneratorUtil; +import com.magento.idea.magento2plugin.magento.files.AbstractPhpFile; +import com.magento.idea.magento2plugin.magento.files.SourceModelFile; +import java.util.ArrayList; +import java.util.List; +import java.util.Properties; +import org.jetbrains.annotations.NotNull; + +public class SourceModelGenerator extends PhpFileGenerator { + private final SourceModelData data; + + /** + * Constructor. + * + * @param project Project + * @param data SourceModelData + */ + public SourceModelGenerator( + @NotNull final SourceModelData data, + @NotNull final Project project + ) { + this(data, project, true); + } + + /** + * Constructor. + * + * @param project Project + * @param data SourceModelData + * @param checkFileAlreadyExists boolean + */ + public SourceModelGenerator( + @NotNull final SourceModelData data, + @NotNull final Project project, + final boolean checkFileAlreadyExists + ) { + super(project, checkFileAlreadyExists); + this.data = data; + } + + @Override + protected AbstractPhpFile initFile() { + return new SourceModelFile( + data.getModuleName(), + data.getClassName(), + data.getDirectory() + ); + } + + @Override + protected void fillAttributes(final Properties attributes) { + final String abstractSourceClass = + "Magento\\Eav\\Model\\Entity\\Attribute\\Source\\AbstractSource"; + final List uses = new ArrayList<>(); + uses.add(abstractSourceClass); + + attributes.setProperty("NAME", data.getClassName()); + attributes.setProperty("NAMESPACE", this.getFile().getNamespace()); + attributes.setProperty( + "EXTENDS", + PhpClassGeneratorUtil.getNameFromFqn(abstractSourceClass) + ); + attributes.setProperty("USES", PhpClassGeneratorUtil.formatUses(uses)); + } +} diff --git a/src/com/magento/idea/magento2plugin/actions/generation/generator/util/GetAttributeOptionPropertiesUtil.java b/src/com/magento/idea/magento2plugin/actions/generation/generator/util/GetAttributeOptionPropertiesUtil.java new file mode 100644 index 000000000..97620041b --- /dev/null +++ b/src/com/magento/idea/magento2plugin/actions/generation/generator/util/GetAttributeOptionPropertiesUtil.java @@ -0,0 +1,55 @@ +/* + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +package com.magento.idea.magento2plugin.actions.generation.generator.util; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import org.jetbrains.annotations.NotNull; + +public final class GetAttributeOptionPropertiesUtil { + public static final String OPTION_VALUE = "Value"; + public static final String OPTION_SORT_ORDER = "Sort Order"; + + private GetAttributeOptionPropertiesUtil() {} + + /** + * Returns sort orders for options. + * + * @param columnsData List + */ + public static Map getSortOrders( + @NotNull final List> columnsData + ) { + final Map sortOrders = new HashMap<>(); + + for (int i = 0; i < columnsData.size(); i++) { + final String sortOrder = columnsData.get(i).get(OPTION_SORT_ORDER); + if (!sortOrder.isEmpty()) { + sortOrders.put(i, sortOrder); + } + } + + return sortOrders; + } + + /** + * Returns options values. + * + * @param columnsData List + */ + public static Map getValues( + @NotNull final List> columnsData + ) { + final Map options = new HashMap<>(); + + for (int i = 0; i < columnsData.size(); i++) { + options.put(i, columnsData.get(i).get(OPTION_VALUE)); + } + + return options; + } +} diff --git a/src/com/magento/idea/magento2plugin/actions/generation/generator/util/eav/AttributeMapperFactory.java b/src/com/magento/idea/magento2plugin/actions/generation/generator/util/eav/AttributeMapperFactory.java new file mode 100644 index 000000000..1d9bf01d5 --- /dev/null +++ b/src/com/magento/idea/magento2plugin/actions/generation/generator/util/eav/AttributeMapperFactory.java @@ -0,0 +1,28 @@ +/* + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +package com.magento.idea.magento2plugin.actions.generation.generator.util.eav; + +import com.magento.idea.magento2plugin.magento.packages.eav.EavEntity; +import com.sun.istack.NotNull; + +public class AttributeMapperFactory { + /** + * Create entity mapper by entity class. + * + * @param entityClass String + */ + public AttributeMapperInterface createByEntityClass(@NotNull final String entityClass) { + if (entityClass.equals(EavEntity.PRODUCT.getEntityClass())) { + return new ProductAttributeMapper(); + } else if (entityClass.equals(EavEntity.CATEGORY.getEntityClass())) { + return new CategoryAttributeMapper(); + } else if (entityClass.equals(EavEntity.CUSTOMER.getEntityClass())) { + return new CustomerAttributeMapper(); + } + + return null; + } +} diff --git a/src/com/magento/idea/magento2plugin/actions/generation/generator/util/eav/AttributeMapperInterface.java b/src/com/magento/idea/magento2plugin/actions/generation/generator/util/eav/AttributeMapperInterface.java new file mode 100644 index 000000000..f6ccb2b4c --- /dev/null +++ b/src/com/magento/idea/magento2plugin/actions/generation/generator/util/eav/AttributeMapperInterface.java @@ -0,0 +1,14 @@ +/* + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +package com.magento.idea.magento2plugin.actions.generation.generator.util.eav; + +import com.magento.idea.magento2plugin.actions.generation.data.EavEntityDataInterface; +import com.sun.istack.NotNull; +import java.util.List; + +public interface AttributeMapperInterface { + List mapAttributesByEntityData(@NotNull EavEntityDataInterface entityData); +} diff --git a/src/com/magento/idea/magento2plugin/actions/generation/generator/util/eav/CategoryAttributeMapper.java b/src/com/magento/idea/magento2plugin/actions/generation/generator/util/eav/CategoryAttributeMapper.java new file mode 100644 index 000000000..b291e3e06 --- /dev/null +++ b/src/com/magento/idea/magento2plugin/actions/generation/generator/util/eav/CategoryAttributeMapper.java @@ -0,0 +1,35 @@ +/* + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + * + */ + +package com.magento.idea.magento2plugin.actions.generation.generator.util.eav; + +import com.magento.idea.magento2plugin.actions.generation.data.CategoryEntityData; +import com.magento.idea.magento2plugin.actions.generation.data.EavEntityDataInterface; +import com.magento.idea.magento2plugin.magento.packages.eav.AttributeProperty; +import java.util.Map; + +public class CategoryAttributeMapper extends DefaultAttributeMapper { + @Override + protected Map getMappedAttributes(final EavEntityDataInterface eavEntityData) { + final Map mappedAttributes = super.getMappedAttributes(eavEntityData); + final CategoryEntityData categoryEavEntityData = (CategoryEntityData) eavEntityData; + + mappedAttributes.put( + AttributeProperty.SORT_ORDER.getProperty(), + Integer.toString(categoryEavEntityData.getSortOrder()) + ); + mappedAttributes.put( + AttributeProperty.GLOBAL.getProperty(), + categoryEavEntityData.getScope() + ); + mappedAttributes.put( + AttributeProperty.GROUP.getProperty(), + wrapStringValueForTemplate(categoryEavEntityData.getGroup()) + ); + + return mappedAttributes; + } +} diff --git a/src/com/magento/idea/magento2plugin/actions/generation/generator/util/eav/CustomerAttributeMapper.java b/src/com/magento/idea/magento2plugin/actions/generation/generator/util/eav/CustomerAttributeMapper.java new file mode 100644 index 000000000..fa74a6052 --- /dev/null +++ b/src/com/magento/idea/magento2plugin/actions/generation/generator/util/eav/CustomerAttributeMapper.java @@ -0,0 +1,47 @@ +/* + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +package com.magento.idea.magento2plugin.actions.generation.generator.util.eav; + +import com.magento.idea.magento2plugin.actions.generation.data.CustomerEntityData; +import com.magento.idea.magento2plugin.actions.generation.data.EavEntityDataInterface; +import com.magento.idea.magento2plugin.magento.packages.eav.AttributeProperty; +import java.util.Map; + +public class CustomerAttributeMapper extends DefaultAttributeMapper { + + @Override + protected Map getMappedAttributes(final EavEntityDataInterface eavEntityData) { + final Map mappedAttributes = super.getMappedAttributes(eavEntityData); + final CustomerEntityData customerEntityData = (CustomerEntityData) eavEntityData; + + mappedAttributes.put( + AttributeProperty.POSITION.getProperty(), + Integer.toString(customerEntityData.getSortOrder()) + ); + mappedAttributes.put( + AttributeProperty.USER_DEFINED.getProperty(), + Boolean.toString(customerEntityData.isUserDefined()) + ); + mappedAttributes.put( + AttributeProperty.IS_USED_IN_GRID.getProperty(), + Boolean.toString(customerEntityData.isUsedInGrid()) + ); + mappedAttributes.put( + AttributeProperty.IS_VISIBLE_IN_GRID.getProperty(), + Boolean.toString(customerEntityData.isVisibleInGrid()) + ); + mappedAttributes.put( + AttributeProperty.IS_FILTERABLE_IN_GRID.getProperty(), + Boolean.toString(customerEntityData.isFilterableInGrid()) + ); + mappedAttributes.put( + AttributeProperty.SYSTEM.getProperty(), + Boolean.toString(customerEntityData.isSystem()) + ); + + return mappedAttributes; + } +} diff --git a/src/com/magento/idea/magento2plugin/actions/generation/generator/util/eav/DefaultAttributeMapper.java b/src/com/magento/idea/magento2plugin/actions/generation/generator/util/eav/DefaultAttributeMapper.java new file mode 100644 index 000000000..f209305c0 --- /dev/null +++ b/src/com/magento/idea/magento2plugin/actions/generation/generator/util/eav/DefaultAttributeMapper.java @@ -0,0 +1,167 @@ +/* + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +package com.magento.idea.magento2plugin.actions.generation.generator.util.eav; + +import com.magento.idea.magento2plugin.actions.generation.data.EavEntityDataInterface; +import com.magento.idea.magento2plugin.magento.packages.eav.AttributeBackendModel; +import com.magento.idea.magento2plugin.magento.packages.eav.AttributeInput; +import com.magento.idea.magento2plugin.magento.packages.eav.AttributeProperty; +import com.magento.idea.magento2plugin.magento.packages.eav.AttributeSourceModel; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class DefaultAttributeMapper implements AttributeMapperInterface { + private static final String PHP_DOUBLE_ARROW_OPERATOR = " => "; + + @Override + public List mapAttributesByEntityData(final EavEntityDataInterface entityData) { + final List attributesWithValues = new ArrayList<>(); + + final Map mappedAttributes = getMappedAttributes(entityData); + + for (final Map.Entry attributePair : mappedAttributes.entrySet()) { + final String attributeKey = "'" + attributePair.getKey() + "'"; + final String attributeValue = attributePair.getValue(); + + attributesWithValues.add( + String.join("=>", attributeKey, attributeValue + ",") + ); + } + + return attributesWithValues; + } + + @SuppressWarnings({"PMD.NullAssignment"}) + protected Map getMappedAttributes(final EavEntityDataInterface eavEntityData) { + final Map mappedAttributes = new HashMap<>(); + mappedAttributes.put( + AttributeProperty.TYPE.getProperty(), + wrapStringValueForTemplate(eavEntityData.getType()) + ); + mappedAttributes.put( + AttributeProperty.LABEL.getProperty(), + wrapStringValueForTemplate(eavEntityData.getLabel()) + ); + mappedAttributes.put( + AttributeProperty.INPUT.getProperty(), + wrapStringValueForTemplate(eavEntityData.getInput()) + ); + mappedAttributes.put( + AttributeProperty.SOURCE.getProperty(), + getEntitySource(eavEntityData) + ); + mappedAttributes.put( + AttributeProperty.REQUIRED.getProperty(), + Boolean.toString(eavEntityData.isRequired()) + ); + mappedAttributes.put( + AttributeProperty.VISIBLE.getProperty(), + Boolean.toString(eavEntityData.isVisible()) + ); + + final String attributeOptions = getMappedOptions( + eavEntityData.getOptions(), + eavEntityData.getOptionsSortOrder() + ); + + if (!attributeOptions.isEmpty()) { + mappedAttributes.put( + AttributeProperty.OPTION.getProperty(), + getMappedOptions( + eavEntityData.getOptions(), + eavEntityData.getOptionsSortOrder() + ) + ); + } + + if (eavEntityData.getInput().equals(AttributeInput.MULTISELECT.getInput())) { + mappedAttributes.put( + AttributeProperty.BACKEND_MODEL.getProperty(), + wrapClassValueForTemplate(AttributeBackendModel.ARRAY.getModel()) + ); + } + + return mappedAttributes; + } + + protected String wrapStringValueForTemplate(final String value) { + return "'" + value + "'"; + } + + protected String wrapClassValueForTemplate(final String value) { + return value + "::class"; + } + + protected String getEntitySource(final EavEntityDataInterface eavEntityData) { + final String eavSource = eavEntityData.getSource(); + + return eavSource == null + || eavSource.equals(AttributeSourceModel.NULLABLE_SOURCE.getSource()) + ? null : wrapClassValueForTemplate(eavSource); + } + + protected String getMappedOptions( + final Map optionValues, + final Map optionSortOrders + ) { + if (optionValues == null || optionValues.isEmpty()) { + return ""; + } + + return "[" + getParsedOptions(optionValues) + + (optionSortOrders == null || optionSortOrders.isEmpty() + ? "->" : "," + getParsedOptionSortOrders(optionSortOrders)) + "]"; + } + + protected String getParsedOptions(final Map optionValues) { + final String valueNode = "->" + wrapStringValueForTemplate("value") + + PHP_DOUBLE_ARROW_OPERATOR; + final StringBuilder optionsContent = new StringBuilder(); + + for (final Integer optionKey : optionValues.keySet()) { + final String optionValue = optionValues.get(optionKey); + + if (optionValue.isEmpty()) { + continue; + } + + optionsContent + .append("->") + .append(wrapStringValueForTemplate("option_" + optionKey)) + .append(PHP_DOUBLE_ARROW_OPERATOR) + .append('[') + .append(wrapStringValueForTemplate(optionValue)) + .append("], "); + } + + return valueNode + "[" + optionsContent + "->]"; + } + + protected String getParsedOptionSortOrders(final Map optionSortOrders) { + final String orderNode = "->" + wrapStringValueForTemplate("order") + + PHP_DOUBLE_ARROW_OPERATOR; + final StringBuilder ordersContent = new StringBuilder(); + + for (final Integer optionKey : optionSortOrders.keySet()) { + final String orderValue = optionSortOrders.get(optionKey); + + if (orderValue.isEmpty()) { + continue; + } + + ordersContent + .append("->") + .append(wrapStringValueForTemplate("option_" + optionKey)) + .append(PHP_DOUBLE_ARROW_OPERATOR) + .append(orderValue) + .append(','); + } + + return orderNode + "[" + ordersContent + "->]->"; + } +} diff --git a/src/com/magento/idea/magento2plugin/actions/generation/generator/util/eav/ProductAttributeMapper.java b/src/com/magento/idea/magento2plugin/actions/generation/generator/util/eav/ProductAttributeMapper.java new file mode 100644 index 000000000..4dd4c7265 --- /dev/null +++ b/src/com/magento/idea/magento2plugin/actions/generation/generator/util/eav/ProductAttributeMapper.java @@ -0,0 +1,64 @@ +/* + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +package com.magento.idea.magento2plugin.actions.generation.generator.util.eav; + +import com.magento.idea.magento2plugin.actions.generation.data.EavEntityDataInterface; +import com.magento.idea.magento2plugin.actions.generation.data.ProductEntityData; +import com.magento.idea.magento2plugin.magento.packages.eav.AttributeProperty; +import java.util.Map; + +public class ProductAttributeMapper extends DefaultAttributeMapper { + + @SuppressWarnings({"PMD.NullAssignment"}) + @Override + protected Map getMappedAttributes(final EavEntityDataInterface eavEntityData) { + final Map mappedAttributes = super.getMappedAttributes(eavEntityData); + + final ProductEntityData productEavEntityData = (ProductEntityData) eavEntityData; + mappedAttributes.put( + AttributeProperty.SORT_ORDER.getProperty(), + Integer.toString(productEavEntityData.getSortOrder()) + ); + mappedAttributes.put( + AttributeProperty.GROUP.getProperty(), + wrapStringValueForTemplate(productEavEntityData.getGroup()) + ); + mappedAttributes.put( + AttributeProperty.GLOBAL.getProperty(), + productEavEntityData.getScope() + ); + mappedAttributes.put( + AttributeProperty.IS_USED_IN_GRID.getProperty(), + Boolean.toString(productEavEntityData.isUsedInGrid()) + ); + mappedAttributes.put( + AttributeProperty.IS_VISIBLE_IN_GRID.getProperty(), + Boolean.toString(productEavEntityData.isVisibleInGrid()) + ); + mappedAttributes.put( + AttributeProperty.IS_FILTERABLE_IN_GRID.getProperty(), + Boolean.toString(productEavEntityData.isFilterableInGrid()) + ); + mappedAttributes.put( + AttributeProperty.IS_HTML_ALLOWED_ON_FRONT.getProperty(), + Boolean.toString(productEavEntityData.isHtmlAllowedOnFront()) + ); + mappedAttributes.put( + AttributeProperty.VISIBLE_ON_FRONT.getProperty(), + Boolean.toString(productEavEntityData.isVisibleOnFront()) + ); + + if (productEavEntityData.getApplyTo() != null + && !productEavEntityData.getApplyTo().isEmpty()) { + mappedAttributes.put( + AttributeProperty.APPLY_TO.getProperty(), + wrapStringValueForTemplate(productEavEntityData.getApplyTo()) + ); + } + + return mappedAttributes; + } +} diff --git a/src/com/magento/idea/magento2plugin/actions/groups/NewEavAttributeGroup.java b/src/com/magento/idea/magento2plugin/actions/groups/NewEavAttributeGroup.java new file mode 100644 index 000000000..c057e6c22 --- /dev/null +++ b/src/com/magento/idea/magento2plugin/actions/groups/NewEavAttributeGroup.java @@ -0,0 +1,30 @@ +/* + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +package com.magento.idea.magento2plugin.actions.groups; + +import com.intellij.ide.actions.NonTrivialActionGroup; +import com.intellij.openapi.util.IconLoader; +import com.magento.idea.magento2plugin.MagentoIcons; +import javax.swing.Icon; +import org.jetbrains.annotations.NotNull; + +public class NewEavAttributeGroup extends NonTrivialActionGroup { + + /** + * Group for Eav attribute generation actions. + */ + public NewEavAttributeGroup() { + super(); + + this.getTemplatePresentation().setIcon(new IconLoader.LazyIcon() { + @NotNull + @Override + protected Icon compute() { + return MagentoIcons.MODULE; + } + }); + } +} diff --git a/src/com/magento/idea/magento2plugin/indexes/IndexManager.java b/src/com/magento/idea/magento2plugin/indexes/IndexManager.java index 56aaad711..61c05fca5 100644 --- a/src/com/magento/idea/magento2plugin/indexes/IndexManager.java +++ b/src/com/magento/idea/magento2plugin/indexes/IndexManager.java @@ -29,6 +29,7 @@ import com.magento.idea.magento2plugin.stubs.indexes.xml.DeclarativeSchemaElementsIndex; import com.magento.idea.magento2plugin.stubs.indexes.xml.MenuIndex; import com.magento.idea.magento2plugin.stubs.indexes.xml.PhpClassNameIndex; +import com.magento.idea.magento2plugin.stubs.indexes.xml.ProductTypeIndex; import com.magento.idea.magento2plugin.stubs.indexes.xml.UIComponentIndex; @SuppressWarnings({"PMD.ClassNamingConventions", "PMD.UseUtilityClass"}) @@ -71,7 +72,9 @@ public static void manualReindex() { TestNameIndex.KEY, TestExtendsIndex.KEY, //graphql - GraphQlResolverIndex.KEY + GraphQlResolverIndex.KEY, + //product types + ProductTypeIndex.KEY }; for (final ID id: indexIds) { diff --git a/src/com/magento/idea/magento2plugin/inspections/xml/ObserverDeclarationInspection.java b/src/com/magento/idea/magento2plugin/inspections/xml/ObserverDeclarationInspection.java index b38a80a9c..762c5e14d 100644 --- a/src/com/magento/idea/magento2plugin/inspections/xml/ObserverDeclarationInspection.java +++ b/src/com/magento/idea/magento2plugin/inspections/xml/ObserverDeclarationInspection.java @@ -3,7 +3,7 @@ * See COPYING.txt for license details. */ -package com.magento.idea.magento2plugin.inspections.xml;//NOPMD +package com.magento.idea.magento2plugin.inspections.xml; import com.intellij.codeInspection.ProblemHighlightType; import com.intellij.codeInspection.ProblemsHolder; @@ -39,7 +39,11 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -@SuppressWarnings({"PMD.ExcessiveMethodLength", "PMD.NPathComplexity"}) +@SuppressWarnings({ + "PMD.ExcessiveMethodLength", + "PMD.NPathComplexity", + "PMD.ExcessiveImports", +}) public class ObserverDeclarationInspection extends PhpInspection { @NotNull diff --git a/src/com/magento/idea/magento2plugin/magento/files/CategoryFormXmlFile.java b/src/com/magento/idea/magento2plugin/magento/files/CategoryFormXmlFile.java new file mode 100644 index 000000000..ae71b6e58 --- /dev/null +++ b/src/com/magento/idea/magento2plugin/magento/files/CategoryFormXmlFile.java @@ -0,0 +1,44 @@ +/* + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + * + */ + +package com.magento.idea.magento2plugin.magento.files; + +import com.intellij.lang.Language; +import com.intellij.lang.xml.XMLLanguage; + +public class CategoryFormXmlFile implements ModuleFileInterface { + + public static final String FILE_NAME = "category_form.xml"; + public static final String TEMPLATE = "Magento Category Admin Form XML"; + public static final String DECLARATION_TEMPLATE = "Magento Category Admin Form XML Decoration"; + public static final String DIRECTORY = "view/adminhtml/ui_component"; + public static final String SUB_DIRECTORY = "ui_component"; + + //attributes + public static final String XML_ATTR_FIELDSET_NAME = "name"; + public static final String XML_ATTR_FIELD_NAME = "name"; + public static final String XML_ATTR_FIELD_SORT_ORDER = "sortOrder"; + public static final String XML_ATTR_FIELD_FORM_ELEMENT = "formElement"; + + //tags + public static final String XML_TAG_FIELDSET = "fieldset"; + public static final String XML_TAG_FIELD = "field"; + + @Override + public String getFileName() { + return FILE_NAME; + } + + @Override + public String getTemplate() { + return TEMPLATE; + } + + @Override + public Language getLanguage() { + return XMLLanguage.INSTANCE; + } +} diff --git a/src/com/magento/idea/magento2plugin/magento/files/CustomerEavAttributeDataPatchFile.java b/src/com/magento/idea/magento2plugin/magento/files/CustomerEavAttributeDataPatchFile.java new file mode 100644 index 000000000..02a90c03b --- /dev/null +++ b/src/com/magento/idea/magento2plugin/magento/files/CustomerEavAttributeDataPatchFile.java @@ -0,0 +1,42 @@ +/* + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +package com.magento.idea.magento2plugin.magento.files; + +import org.jetbrains.annotations.NotNull; + +public class CustomerEavAttributeDataPatchFile extends AbstractPhpFile { + public static final String HUMAN_READABLE_NAME = "Customer Eav Attribute Data Patch Class"; + public static final String TEMPLATE = "Magento Customer Eav Attribute Data Patch Class"; + public static final String DEFAULT_DIR = "Setup/Patch/Data"; + + /** + * Abstract php file constructor. + * + * @param moduleName String + * @param className String + */ + public CustomerEavAttributeDataPatchFile( + final @NotNull String moduleName, + final @NotNull String className + ) { + super(moduleName, className); + } + + @Override + public String getDirectory() { + return DEFAULT_DIR; + } + + @Override + public String getHumanReadableName() { + return HUMAN_READABLE_NAME; + } + + @Override + public String getTemplate() { + return TEMPLATE; + } +} diff --git a/src/com/magento/idea/magento2plugin/magento/files/EavAttributeDataPatchFile.java b/src/com/magento/idea/magento2plugin/magento/files/EavAttributeDataPatchFile.java new file mode 100644 index 000000000..7c6a5fb52 --- /dev/null +++ b/src/com/magento/idea/magento2plugin/magento/files/EavAttributeDataPatchFile.java @@ -0,0 +1,36 @@ +/* + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +package com.magento.idea.magento2plugin.magento.files; + +public class EavAttributeDataPatchFile extends AbstractPhpFile { + public static final String HUMAN_READABLE_NAME = "Eav Attribute Data Patch Class"; + public static final String TEMPLATE = "Magento Eav Attribute Data Patch Class"; + public static final String DEFAULT_DIR = "Setup/Patch/Data"; + + /** + * Constructor. + * + * @param className String + */ + public EavAttributeDataPatchFile(final String moduleName, final String className) { + super(moduleName, className); + } + + @Override + public String getDirectory() { + return DEFAULT_DIR; + } + + @Override + public String getHumanReadableName() { + return HUMAN_READABLE_NAME; + } + + @Override + public String getTemplate() { + return TEMPLATE; + } +} diff --git a/src/com/magento/idea/magento2plugin/magento/files/ProductTypeXml.java b/src/com/magento/idea/magento2plugin/magento/files/ProductTypeXml.java new file mode 100644 index 000000000..ea5c6a3ca --- /dev/null +++ b/src/com/magento/idea/magento2plugin/magento/files/ProductTypeXml.java @@ -0,0 +1,33 @@ +/* + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +package com.magento.idea.magento2plugin.magento.files; + +import com.intellij.lang.Language; +import com.intellij.lang.xml.XMLLanguage; + +public class ProductTypeXml implements ModuleFileInterface { + public static final String FILE_NAME = "product_types.xml"; + public static final String TEMPLATE = "Magento Product Types"; + + //attributes + public static final String XML_TAG_TYPE = "type"; + public static final String XML_ATTRIBUTE_NAME = "name"; + + @Override + public String getFileName() { + return FILE_NAME; + } + + @Override + public String getTemplate() { + return TEMPLATE; + } + + @Override + public Language getLanguage() { + return XMLLanguage.INSTANCE; + } +} diff --git a/src/com/magento/idea/magento2plugin/magento/files/SourceModelFile.java b/src/com/magento/idea/magento2plugin/magento/files/SourceModelFile.java new file mode 100644 index 000000000..13a47c9d6 --- /dev/null +++ b/src/com/magento/idea/magento2plugin/magento/files/SourceModelFile.java @@ -0,0 +1,60 @@ +/* + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +package com.magento.idea.magento2plugin.magento.files; + +import org.jetbrains.annotations.NotNull; + +public class SourceModelFile extends AbstractPhpFile { + public static final String HUMAN_READABLE_NAME = "Source model class"; + public static final String TEMPLATE = "Magento Source Model Class"; + public static final String DEFAULT_DIR = "Model/Source"; + private String directory; + + /** + * Constructor. + * + * @param className String + */ + public SourceModelFile( + @NotNull final String moduleName, + @NotNull final String className + ) { + super(moduleName, className); + } + + /** + * Constructor. + * + * @param className String + */ + public SourceModelFile( + @NotNull final String moduleName, + @NotNull final String className, + final String directory + ) { + this(moduleName, className); + this.directory = directory; + } + + @Override + public String getDirectory() { + if (directory == null) { + return DEFAULT_DIR; + } + + return directory; + } + + @Override + public String getHumanReadableName() { + return HUMAN_READABLE_NAME; + } + + @Override + public String getTemplate() { + return TEMPLATE; + } +} diff --git a/src/com/magento/idea/magento2plugin/magento/packages/eav/AttributeBackendModel.java b/src/com/magento/idea/magento2plugin/magento/packages/eav/AttributeBackendModel.java new file mode 100644 index 000000000..2e9524912 --- /dev/null +++ b/src/com/magento/idea/magento2plugin/magento/packages/eav/AttributeBackendModel.java @@ -0,0 +1,21 @@ +/* + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + * + */ + +package com.magento.idea.magento2plugin.magento.packages.eav; + +public enum AttributeBackendModel { + ARRAY("\\Magento\\Eav\\Model\\Entity\\Attribute\\Backend\\ArrayBackend"); + + private String model; + + AttributeBackendModel(final String model) { + this.model = model; + } + + public String getModel() { + return model; + } +} diff --git a/src/com/magento/idea/magento2plugin/magento/packages/eav/AttributeInput.java b/src/com/magento/idea/magento2plugin/magento/packages/eav/AttributeInput.java new file mode 100644 index 000000000..773b18516 --- /dev/null +++ b/src/com/magento/idea/magento2plugin/magento/packages/eav/AttributeInput.java @@ -0,0 +1,48 @@ +/* + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +package com.magento.idea.magento2plugin.magento.packages.eav; + +public enum AttributeInput { + TEXT("text"), + TEXTAREA("textarea"), + BOOLEAN("boolean"), + SELECT("select"), + MULTISELECT("multiselect"), + DATE("date"), + PRICE("price"), + HIDDEN("hidden"); + + private String input; + + AttributeInput(final String input) { + this.input = input; + } + + /** + * Return attribute input. + * + * @return String + */ + public String getInput() { + return this.input; + } + + /** + * Return attribute input item by input code. + * + * @param code String + * @return AttributeInput + */ + public static AttributeInput getAttributeInputByCode(final String code) { + for (final AttributeInput attributeInput: values()) { + if (attributeInput.getInput().equals(code)) { + return attributeInput; + } + } + + return null; + } +} diff --git a/src/com/magento/idea/magento2plugin/magento/packages/eav/AttributeProperty.java b/src/com/magento/idea/magento2plugin/magento/packages/eav/AttributeProperty.java new file mode 100644 index 000000000..3a2b47200 --- /dev/null +++ b/src/com/magento/idea/magento2plugin/magento/packages/eav/AttributeProperty.java @@ -0,0 +1,39 @@ +/* + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +package com.magento.idea.magento2plugin.magento.packages.eav; + +public enum AttributeProperty { + GROUP("group"), + TYPE("type"), + LABEL("label"), + INPUT("input"), + SOURCE("source"), + REQUIRED("required"), + SORT_ORDER("sort_order"), + GLOBAL("global"), + IS_USED_IN_GRID("is_used_in_grid"), + IS_VISIBLE_IN_GRID("is_visible_in_grid"), + IS_FILTERABLE_IN_GRID("is_filterable_in_grid"), + VISIBLE("visible"), + IS_HTML_ALLOWED_ON_FRONT("is_html_allowed_on_front"), + VISIBLE_ON_FRONT("visible_on_front"), + APPLY_TO("apply_to"), + OPTION("option"), + BACKEND_MODEL("backend"), + USER_DEFINED("user_defined"), + POSITION("position"), + SYSTEM("system"); + + private String attribute; + + AttributeProperty(final String attribute) { + this.attribute = attribute; + } + + public String getProperty() { + return attribute; + } +} diff --git a/src/com/magento/idea/magento2plugin/magento/packages/eav/AttributeScope.java b/src/com/magento/idea/magento2plugin/magento/packages/eav/AttributeScope.java new file mode 100644 index 000000000..e0738bc37 --- /dev/null +++ b/src/com/magento/idea/magento2plugin/magento/packages/eav/AttributeScope.java @@ -0,0 +1,22 @@ +/* + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +package com.magento.idea.magento2plugin.magento.packages.eav; + +public enum AttributeScope { + GLOBAL("\\Magento\\Eav\\Model\\Entity\\Attribute\\ScopedAttributeInterface::SCOPE_GLOBAL"), + STORE("\\Magento\\Eav\\Model\\Entity\\Attribute\\ScopedAttributeInterface::SCOPE_STORE"), + WEBSITE("\\Magento\\Eav\\Model\\Entity\\Attribute\\ScopedAttributeInterface::SCOPE_WEBSITE"); + + private String scope; + + AttributeScope(final String scope) { + this.scope = scope; + } + + public String getScope() { + return scope; + } +} diff --git a/src/com/magento/idea/magento2plugin/magento/packages/eav/AttributeSourceModel.java b/src/com/magento/idea/magento2plugin/magento/packages/eav/AttributeSourceModel.java new file mode 100644 index 000000000..a19075813 --- /dev/null +++ b/src/com/magento/idea/magento2plugin/magento/packages/eav/AttributeSourceModel.java @@ -0,0 +1,25 @@ +/* + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +package com.magento.idea.magento2plugin.magento.packages.eav; + +public enum AttributeSourceModel { + BOOLEAN("\\Magento\\Eav\\Model\\Entity\\Attribute\\Source\\Boolean"), + TABLE("\\Magento\\Eav\\Model\\Entity\\Attribute\\Source\\Table"), + CONFIG("\\Magento\\Eav\\Model\\Entity\\Attribute\\Source\\Config"), + STORE("\\Magento\\Eav\\Model\\Entity\\Attribute\\Source\\Store"), + GENERATE_SOURCE("Custom Source"), + NULLABLE_SOURCE("Without Source Model"); + + private String source; + + AttributeSourceModel(final String source) { + this.source = source; + } + + public String getSource() { + return source; + } +} diff --git a/src/com/magento/idea/magento2plugin/magento/packages/eav/AttributeType.java b/src/com/magento/idea/magento2plugin/magento/packages/eav/AttributeType.java new file mode 100644 index 000000000..988fa865a --- /dev/null +++ b/src/com/magento/idea/magento2plugin/magento/packages/eav/AttributeType.java @@ -0,0 +1,25 @@ +/* + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +package com.magento.idea.magento2plugin.magento.packages.eav; + +public enum AttributeType { + STATIC("static"), + VARCHAR("varchar"), + INT("int"), + TEXT("text"), + DATETIME("datetime"), + DECIMAL("decimal"); + + private String type; + + AttributeType(final String type) { + this.type = type; + } + + public String getType() { + return this.type; + } +} diff --git a/src/com/magento/idea/magento2plugin/magento/packages/eav/CustomerForm.java b/src/com/magento/idea/magento2plugin/magento/packages/eav/CustomerForm.java new file mode 100644 index 000000000..40c7733ff --- /dev/null +++ b/src/com/magento/idea/magento2plugin/magento/packages/eav/CustomerForm.java @@ -0,0 +1,27 @@ +/* + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +package com.magento.idea.magento2plugin.magento.packages.eav; + +public enum CustomerForm { + + ADMINHTML_CHECKOUT("adminhtml_checkout"), + ADMINHTML_CUSTOMER("adminhtml_customer"), + ADMINHTML_CUSTOMER_ADDRESS("adminhtml_customer_address"), + CUSTOMER_ACCOUNT_CREATE("customer_account_create"), + CUSTOMER_ACCOUNT_EDIT("customer_account_edit"), + CUSTOMER_ADDRESS_EDIT("customer_address_edit"), + CUSTOMER_REGISTER_ADDRESS("customer_register_address"); + + private final String formCode; + + CustomerForm(final String formCode) { + this.formCode = formCode; + } + + public String getFormCode() { + return this.formCode; + } +} diff --git a/src/com/magento/idea/magento2plugin/magento/packages/eav/DataPatchDependency.java b/src/com/magento/idea/magento2plugin/magento/packages/eav/DataPatchDependency.java new file mode 100644 index 000000000..aee63c3d9 --- /dev/null +++ b/src/com/magento/idea/magento2plugin/magento/packages/eav/DataPatchDependency.java @@ -0,0 +1,26 @@ +/* + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +package com.magento.idea.magento2plugin.magento.packages.eav; + +public enum DataPatchDependency { + CUSTOMER_METADATA_INTERFACE("Magento\\Customer\\Api\\CustomerMetadataInterface"), + DATA_PATCH_INTERFACE("Magento\\Framework\\Setup\\Patch\\DataPatchInterface"), + EAV_CONFIG("Magento\\Eav\\Model\\Config"), + EAV_SETUP_FACTORY("Magento\\Eav\\Setup\\EavSetupFactory"), + ENV_SETUP("Magento\\Eav\\Setup\\EavSetup"), + MODULE_DATA_SETUP_INTERFACE("Magento\\Framework\\Setup\\ModuleDataSetupInterface"), + ATTRIBUTE_RESOURCE("Magento\\Customer\\Model\\ResourceModel\\Attribute"); + + private String classPatch; + + DataPatchDependency(final String classPatch) { + this.classPatch = classPatch; + } + + public String getClassPatch() { + return classPatch; + } +} diff --git a/src/com/magento/idea/magento2plugin/magento/packages/eav/EavEntity.java b/src/com/magento/idea/magento2plugin/magento/packages/eav/EavEntity.java new file mode 100644 index 000000000..ee3e770ea --- /dev/null +++ b/src/com/magento/idea/magento2plugin/magento/packages/eav/EavEntity.java @@ -0,0 +1,22 @@ +/* + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +package com.magento.idea.magento2plugin.magento.packages.eav; + +public enum EavEntity { + PRODUCT("Magento\\Catalog\\Model\\Product"), + CATEGORY("Magento\\Catalog\\Model\\Category"), + CUSTOMER("Magento\\Customer\\Model\\Customer"); + + private String entityClass; + + EavEntity(final String entityClass) { + this.entityClass = entityClass; + } + + public String getEntityClass() { + return entityClass; + } +} diff --git a/src/com/magento/idea/magento2plugin/magento/packages/uicomponent/AvailableSourcesByInput.java b/src/com/magento/idea/magento2plugin/magento/packages/uicomponent/AvailableSourcesByInput.java new file mode 100644 index 000000000..f587e0d98 --- /dev/null +++ b/src/com/magento/idea/magento2plugin/magento/packages/uicomponent/AvailableSourcesByInput.java @@ -0,0 +1,62 @@ +/* + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +package com.magento.idea.magento2plugin.magento.packages.uicomponent; + +import com.magento.idea.magento2plugin.actions.generation.data.ui.ComboBoxItemData; +import com.magento.idea.magento2plugin.magento.packages.eav.AttributeInput; +import com.magento.idea.magento2plugin.magento.packages.eav.AttributeSourceModel; +import com.sun.istack.NotNull; +import java.util.ArrayList; +import java.util.List; + +public class AvailableSourcesByInput { + private final String input; + + public AvailableSourcesByInput(@NotNull final String input) { + this.input = input; + } + + /** + * Source items getter. + * + * @return List + */ + public List getItems() { + final List items = new ArrayList<>(); + final ComboBoxItemData generateSourceItem = new ComboBoxItemData( + AttributeSourceModel.GENERATE_SOURCE.getSource(), + AttributeSourceModel.GENERATE_SOURCE.getSource() + ); + items.add(generateSourceItem); + + if (input.equals(AttributeInput.BOOLEAN.getInput())) { + items.add(new ComboBoxItemData( + AttributeSourceModel.BOOLEAN.getSource(), + AttributeSourceModel.BOOLEAN.getSource()) + ); + } else if (input.equals(AttributeInput.SELECT.getInput()) + || input.equals(AttributeInput.MULTISELECT.getInput())) { + items.add(new ComboBoxItemData( + AttributeSourceModel.BOOLEAN.getSource(), + AttributeSourceModel.BOOLEAN.getSource()) + ); + items.add(new ComboBoxItemData( + AttributeSourceModel.TABLE.getSource(), + AttributeSourceModel.TABLE.getSource() + )); + items.add(new ComboBoxItemData( + AttributeSourceModel.STORE.getSource(), + AttributeSourceModel.STORE.getSource() + )); + items.add(new ComboBoxItemData( + AttributeSourceModel.CONFIG.getSource(), + AttributeSourceModel.CONFIG.getSource() + )); + } + + return items; + } +} diff --git a/src/com/magento/idea/magento2plugin/stubs/indexes/xml/ProductTypeIndex.java b/src/com/magento/idea/magento2plugin/stubs/indexes/xml/ProductTypeIndex.java new file mode 100644 index 000000000..e95cfb414 --- /dev/null +++ b/src/com/magento/idea/magento2plugin/stubs/indexes/xml/ProductTypeIndex.java @@ -0,0 +1,106 @@ +/* + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +package com.magento.idea.magento2plugin.stubs.indexes.xml; + +import com.intellij.ide.highlighter.XmlFileType; +import com.intellij.psi.PsiFile; +import com.intellij.psi.xml.XmlDocument; +import com.intellij.psi.xml.XmlFile; +import com.intellij.psi.xml.XmlTag; +import com.intellij.util.indexing.DataIndexer; +import com.intellij.util.indexing.FileBasedIndex; +import com.intellij.util.indexing.FileContent; +import com.intellij.util.indexing.ID; +import com.intellij.util.indexing.ScalarIndexExtension; +import com.intellij.util.io.EnumeratorStringDescriptor; +import com.intellij.util.io.KeyDescriptor; +import com.magento.idea.magento2plugin.magento.files.ProductTypeXml; +import com.magento.idea.magento2plugin.project.Settings; +import gnu.trove.THashMap; +import java.util.Map; +import org.jetbrains.annotations.NotNull; + +public class ProductTypeIndex extends ScalarIndexExtension { + private static final String TEST_DIRECTORY_PATTERN = ".*\\/[Tt]ests?\\/?.*"; + private final KeyDescriptor myKeyDescriptor = new EnumeratorStringDescriptor(); + public static final ID KEY = ID.create( + "com.magento.idea.magento2plugin.stubs.indexes.product_types"); + + @Override + public @NotNull + ID getName() { + return KEY; + } + + @Override + public @NotNull + DataIndexer getIndexer() { + return inputData -> { + final Map map = new THashMap<>(); + final String filePath = inputData.getFile().getPath(); + + if (filePath.matches(TEST_DIRECTORY_PATTERN)) { + return map; + } + + final PsiFile psiFile = inputData.getPsiFile(); + if (!Settings.isEnabled(psiFile.getProject())) { + return map; + } + + if (!(psiFile instanceof XmlFile)) { + return map; + } + + final XmlDocument xmlDocument = ((XmlFile) psiFile).getDocument(); + + if (xmlDocument == null) { + return map; + } + + final XmlTag xmlRootTag = xmlDocument.getRootTag(); + + if (xmlRootTag != null) { + parseRootTag(map, xmlRootTag); + } + + return map; + }; + } + + private void parseRootTag(final Map map, final XmlTag xmlRootTag) { + for (final XmlTag productTypeTag : xmlRootTag.findSubTags(ProductTypeXml.XML_TAG_TYPE)) { + final String productTypeName = productTypeTag.getAttributeValue( + ProductTypeXml.XML_ATTRIBUTE_NAME + ); + map.put(productTypeName, null); + } + } + + @Override + public @NotNull + KeyDescriptor getKeyDescriptor() { + return this.myKeyDescriptor; + } + + @Override + public int getVersion() { + return 0; + } + + @Override + @SuppressWarnings({"PMD.LiteralsFirstInComparisons"}) + public FileBasedIndex.InputFilter getInputFilter() { + return file -> + file.getFileType() == XmlFileType.INSTANCE + && file.getName().equalsIgnoreCase(ProductTypeXml.FILE_NAME); + } + + @Override + public boolean dependsOnFileContent() { + return true; + } +} diff --git a/src/com/magento/idea/magento2plugin/util/RegExUtil.java b/src/com/magento/idea/magento2plugin/util/RegExUtil.java index 17dd76d9d..632f5a8f4 100644 --- a/src/com/magento/idea/magento2plugin/util/RegExUtil.java +++ b/src/com/magento/idea/magento2plugin/util/RegExUtil.java @@ -83,6 +83,9 @@ public static class Magento { public static final String TEST_CLASS_FQN = "^(\\\\)?(\\w+\\\\){1}(\\w+\\\\){1}Test(\\\\\\w+)+$"; + + public static final String COMMA_SEPARATED_STRING = + "^[^\\s,]+(?:,\\s*[^\\s,]+)*$"; } public static class PhpRegex { diff --git a/src/com/magento/idea/magento2plugin/util/magento/GetProductTypesListUtil.java b/src/com/magento/idea/magento2plugin/util/magento/GetProductTypesListUtil.java new file mode 100644 index 000000000..527759024 --- /dev/null +++ b/src/com/magento/idea/magento2plugin/util/magento/GetProductTypesListUtil.java @@ -0,0 +1,31 @@ +/* + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +package com.magento.idea.magento2plugin.util.magento; + +import com.intellij.openapi.project.Project; +import com.intellij.util.indexing.FileBasedIndex; +import com.magento.idea.magento2plugin.stubs.indexes.xml.ProductTypeIndex; +import java.util.Collection; +import java.util.List; +import java.util.stream.Collectors; + +public final class GetProductTypesListUtil { + + private GetProductTypesListUtil() {} + + /** + * Product types util. + * + * @param project Project + * @return List + */ + public static List execute(final Project project) { + final Collection productTypesList = + FileBasedIndex.getInstance().getAllKeys(ProductTypeIndex.KEY, project); + + return productTypesList.stream().sorted().collect(Collectors.toList()); + } +} diff --git a/testData/actions/generation/generator/CategoryAttributePropertySetupPatchGenerator/generateFile/AddTestAttributeCategoryAttribute.php b/testData/actions/generation/generator/CategoryAttributePropertySetupPatchGenerator/generateFile/AddTestAttributeCategoryAttribute.php new file mode 100644 index 000000000..0c43f12d0 --- /dev/null +++ b/testData/actions/generation/generator/CategoryAttributePropertySetupPatchGenerator/generateFile/AddTestAttributeCategoryAttribute.php @@ -0,0 +1,92 @@ +moduleDataSetup = $moduleDataSetup; + $this->eavSetupFactory = $eavSetupFactory; + } + + /** + * Run code inside patch + * If code fails, patch must be reverted, in case when we are speaking about schema - then under revert + * means run PatchInterface::revert() + * + * If we speak about data, under revert means: $transaction->rollback() + */ + public function apply() + { + /** @var EavSetup $eavSetup */ + $eavSetup = $this->eavSetupFactory->create(['setup' => $this->moduleDataSetup]); + + $eavSetup->addAttribute( + Category::ENTITY, + 'test_attribute', + [ + 'input' => 'text', + 'visible' => true, + 'global' => \Magento\Eav\Model\Entity\Attribute\ScopedAttributeInterface::SCOPE_GLOBAL, + 'label' => 'Test Attribute', + 'source' => null, + 'type' => 'static', + 'sort_order' => 10, + 'required' => false, + 'group' => 'Content', + ] + ); + } + + /** + * Get array of patches that have to be executed prior to this. + * + * Example of implementation: + * + * [ + * \Vendor_Name\Module_Name\Setup\Patch\Patch1::class, + * \Vendor_Name\Module_Name\Setup\Patch\Patch2::class + * ] + * + * @return string[] + */ + public static function getDependencies() + { + return []; + } + + /** + * Get aliases (previous names) for the patch. + * + * @return string[] + */ + public function getAliases() + { + return []; + } +} diff --git a/testData/actions/generation/generator/CategoryAttributePropertySetupPatchGenerator/generateFormFile/category_form.xml b/testData/actions/generation/generator/CategoryAttributePropertySetupPatchGenerator/generateFormFile/category_form.xml new file mode 100644 index 000000000..58c560cfa --- /dev/null +++ b/testData/actions/generation/generator/CategoryAttributePropertySetupPatchGenerator/generateFormFile/category_form.xml @@ -0,0 +1,7 @@ + +
+
+ +
+
diff --git a/testData/actions/generation/generator/CustomerAttributeSetupPatchGenerator/generateMultiselectAttributeDataPatch/AddMultiselectTestCustomerAttribute.php b/testData/actions/generation/generator/CustomerAttributeSetupPatchGenerator/generateMultiselectAttributeDataPatch/AddMultiselectTestCustomerAttribute.php new file mode 100644 index 000000000..4757629dd --- /dev/null +++ b/testData/actions/generation/generator/CustomerAttributeSetupPatchGenerator/generateMultiselectAttributeDataPatch/AddMultiselectTestCustomerAttribute.php @@ -0,0 +1,139 @@ +moduleDataSetup = $moduleDataSetup; + $this->eavSetupFactory = $eavSetupFactory; + $this->eavConfig = $eavConfig; + $this->attributeResource = $attributeResource; + } + + /** + * Run code inside patch + * If code fails, patch must be reverted, in case when we are speaking about schema - then under revert + * means run PatchInterface::revert() + * + * If we speak about data, under revert means: $transaction->rollback() + * + * @return $this + */ + public function apply() + { + /** @var EavSetup $eavSetup */ + $eavSetup = $this->eavSetupFactory->create(['setup' => $this->moduleDataSetup]); + + $eavSetup->addAttribute( + Customer::ENTITY, + 'multiselect_test', + [ + 'is_visible_in_grid' => false, + 'visible' => true, + 'label' => 'Multiselect Test', + 'source' => \Magento\Eav\Model\Entity\Attribute\Source\Table::class, + 'type' => 'varchar', + 'is_used_in_grid' => false, + 'required' => false, + 'input' => 'multiselect', + 'user_defined' => true, + 'is_filterable_in_grid' => false, + 'system' => false, + 'backend' => \Magento\Eav\Model\Entity\Attribute\Backend\ArrayBackend::class, + 'position' => 10, + 'option' => [ + 'value' => [ + 'option_0' => ['option1'], + 'option_1' => ['option2'], + 'option_2' => ['option3'], + ] + ], + ] + ); + + $eavSetup->addAttributeToSet( + CustomerMetadataInterface::ENTITY_TYPE_CUSTOMER, + CustomerMetadataInterface::ATTRIBUTE_SET_ID_CUSTOMER, + null, + 'multiselect_test' + ); + + $attribute = $this->eavConfig->getAttribute(Customer::ENTITY, 'multiselect_test'); + $attribute->setData( + 'used_in_forms', + ['adminhtml_customer'] + ); + $this->attributeResource->save($attribute); + + return $this; + } + + /** + * Get array of patches that have to be executed prior to this. + * + * Example of implementation: + * + * [ + * \Vendor_Name\Module_Name\Setup\Patch\Patch1::class, + * \Vendor_Name\Module_Name\Setup\Patch\Patch2::class + * ] + * + * @return string[] + */ + public static function getDependencies() + { + return []; + } + + /** + * Get aliases (previous names) for the patch. + * + * @return string[] + */ + public function getAliases() + { + return []; + } +} diff --git a/testData/actions/generation/generator/ProductAttributePropertySetupPatchGenerator/generateFile/AddTestAttribute.php b/testData/actions/generation/generator/ProductAttributePropertySetupPatchGenerator/generateFile/AddTestAttribute.php new file mode 100644 index 000000000..129a8f068 --- /dev/null +++ b/testData/actions/generation/generator/ProductAttributePropertySetupPatchGenerator/generateFile/AddTestAttribute.php @@ -0,0 +1,97 @@ +moduleDataSetup = $moduleDataSetup; + $this->eavSetupFactory = $eavSetupFactory; + } + + /** + * Run code inside patch + * If code fails, patch must be reverted, in case when we are speaking about schema - then under revert + * means run PatchInterface::revert() + * + * If we speak about data, under revert means: $transaction->rollback() + */ + public function apply() + { + /** @var EavSetup $eavSetup */ + $eavSetup = $this->eavSetupFactory->create(['setup' => $this->moduleDataSetup]); + + $eavSetup->addAttribute( + Product::ENTITY, + 'test', + [ + 'is_visible_in_grid' => false, + 'is_html_allowed_on_front' => false, + 'visible_on_front' => false, + 'visible' => true, + 'global' => \Magento\Eav\Model\Entity\Attribute\ScopedAttributeInterface::SCOPE_GLOBAL, + 'label' => 'Test Label', + 'source' => null, + 'type' => 'static', + 'is_used_in_grid' => false, + 'required' => false, + 'input' => 'text', + 'is_filterable_in_grid' => false, + 'sort_order' => 10, + 'group' => 'General', + ] + ); + } + + /** + * Get array of patches that have to be executed prior to this. + * + * Example of implementation: + * + * [ + * \Vendor_Name\Module_Name\Setup\Patch\Patch1::class, + * \Vendor_Name\Module_Name\Setup\Patch\Patch2::class + * ] + * + * @return string[] + */ + public static function getDependencies() + { + return []; + } + + /** + * Get aliases (previous names) for the patch. + * + * @return string[] + */ + public function getAliases() + { + return []; + } +} diff --git a/testData/actions/generation/generator/ProductAttributePropertySetupPatchGenerator/generateFileWithApplyToAttribute/AddAppliedToAttribute.php b/testData/actions/generation/generator/ProductAttributePropertySetupPatchGenerator/generateFileWithApplyToAttribute/AddAppliedToAttribute.php new file mode 100644 index 000000000..90be38a37 --- /dev/null +++ b/testData/actions/generation/generator/ProductAttributePropertySetupPatchGenerator/generateFileWithApplyToAttribute/AddAppliedToAttribute.php @@ -0,0 +1,98 @@ +moduleDataSetup = $moduleDataSetup; + $this->eavSetupFactory = $eavSetupFactory; + } + + /** + * Run code inside patch + * If code fails, patch must be reverted, in case when we are speaking about schema - then under revert + * means run PatchInterface::revert() + * + * If we speak about data, under revert means: $transaction->rollback() + */ + public function apply() + { + /** @var EavSetup $eavSetup */ + $eavSetup = $this->eavSetupFactory->create(['setup' => $this->moduleDataSetup]); + + $eavSetup->addAttribute( + Product::ENTITY, + 'applied_to_attribute', + [ + 'is_visible_in_grid' => false, + 'is_html_allowed_on_front' => false, + 'visible_on_front' => false, + 'visible' => true, + 'global' => \Magento\Eav\Model\Entity\Attribute\ScopedAttributeInterface::SCOPE_GLOBAL, + 'label' => 'Test Label', + 'source' => null, + 'type' => 'static', + 'is_used_in_grid' => false, + 'required' => false, + 'input' => 'text', + 'is_filterable_in_grid' => false, + 'apply_to' => 'configurable,simple', + 'sort_order' => 10, + 'group' => 'General', + ] + ); + } + + /** + * Get array of patches that have to be executed prior to this. + * + * Example of implementation: + * + * [ + * \Vendor_Name\Module_Name\Setup\Patch\Patch1::class, + * \Vendor_Name\Module_Name\Setup\Patch\Patch2::class + * ] + * + * @return string[] + */ + public static function getDependencies() + { + return []; + } + + /** + * Get aliases (previous names) for the patch. + * + * @return string[] + */ + public function getAliases() + { + return []; + } +} diff --git a/testData/actions/generation/generator/ProductAttributePropertySetupPatchGenerator/generateFileWithBooleanSourceModel/AddBooleanInputAttributeAttribute.php b/testData/actions/generation/generator/ProductAttributePropertySetupPatchGenerator/generateFileWithBooleanSourceModel/AddBooleanInputAttributeAttribute.php new file mode 100644 index 000000000..574350b72 --- /dev/null +++ b/testData/actions/generation/generator/ProductAttributePropertySetupPatchGenerator/generateFileWithBooleanSourceModel/AddBooleanInputAttributeAttribute.php @@ -0,0 +1,97 @@ +moduleDataSetup = $moduleDataSetup; + $this->eavSetupFactory = $eavSetupFactory; + } + + /** + * Run code inside patch + * If code fails, patch must be reverted, in case when we are speaking about schema - then under revert + * means run PatchInterface::revert() + * + * If we speak about data, under revert means: $transaction->rollback() + */ + public function apply() + { + /** @var EavSetup $eavSetup */ + $eavSetup = $this->eavSetupFactory->create(['setup' => $this->moduleDataSetup]); + + $eavSetup->addAttribute( + Product::ENTITY, + 'boolean_input_attribute', + [ + 'is_visible_in_grid' => false, + 'is_html_allowed_on_front' => false, + 'visible_on_front' => false, + 'visible' => true, + 'global' => \Magento\Eav\Model\Entity\Attribute\ScopedAttributeInterface::SCOPE_GLOBAL, + 'label' => 'Test Label', + 'source' => \Magento\Eav\Model\Entity\Attribute\Source\Boolean::class, + 'type' => 'static', + 'is_used_in_grid' => false, + 'required' => false, + 'input' => 'boolean', + 'is_filterable_in_grid' => false, + 'sort_order' => 10, + 'group' => 'General', + ] + ); + } + + /** + * Get array of patches that have to be executed prior to this. + * + * Example of implementation: + * + * [ + * \Vendor_Name\Module_Name\Setup\Patch\Patch1::class, + * \Vendor_Name\Module_Name\Setup\Patch\Patch2::class + * ] + * + * @return string[] + */ + public static function getDependencies() + { + return []; + } + + /** + * Get aliases (previous names) for the patch. + * + * @return string[] + */ + public function getAliases() + { + return []; + } +} diff --git a/testData/actions/generation/generator/ProductAttributePropertySetupPatchGenerator/generateFileWithGeneratedSourceModel/AddAttributeWithCustomSourceAttribute.php b/testData/actions/generation/generator/ProductAttributePropertySetupPatchGenerator/generateFileWithGeneratedSourceModel/AddAttributeWithCustomSourceAttribute.php new file mode 100644 index 000000000..2dc15f408 --- /dev/null +++ b/testData/actions/generation/generator/ProductAttributePropertySetupPatchGenerator/generateFileWithGeneratedSourceModel/AddAttributeWithCustomSourceAttribute.php @@ -0,0 +1,97 @@ +moduleDataSetup = $moduleDataSetup; + $this->eavSetupFactory = $eavSetupFactory; + } + + /** + * Run code inside patch + * If code fails, patch must be reverted, in case when we are speaking about schema - then under revert + * means run PatchInterface::revert() + * + * If we speak about data, under revert means: $transaction->rollback() + */ + public function apply() + { + /** @var EavSetup $eavSetup */ + $eavSetup = $this->eavSetupFactory->create(['setup' => $this->moduleDataSetup]); + + $eavSetup->addAttribute( + Product::ENTITY, + 'attribute_with_custom_source', + [ + 'is_visible_in_grid' => false, + 'is_html_allowed_on_front' => false, + 'visible_on_front' => false, + 'visible' => true, + 'global' => \Magento\Eav\Model\Entity\Attribute\ScopedAttributeInterface::SCOPE_GLOBAL, + 'label' => 'Test Label', + 'source' => \Foo\Bar\Model\Source\AttributeWithCustomSource::class, + 'type' => 'static', + 'is_used_in_grid' => false, + 'required' => false, + 'input' => 'text', + 'is_filterable_in_grid' => false, + 'sort_order' => 10, + 'group' => 'General', + ] + ); + } + + /** + * Get array of patches that have to be executed prior to this. + * + * Example of implementation: + * + * [ + * \Vendor_Name\Module_Name\Setup\Patch\Patch1::class, + * \Vendor_Name\Module_Name\Setup\Patch\Patch2::class + * ] + * + * @return string[] + */ + public static function getDependencies() + { + return []; + } + + /** + * Get aliases (previous names) for the patch. + * + * @return string[] + */ + public function getAliases() + { + return []; + } +} diff --git a/testData/actions/generation/generator/ProductAttributePropertySetupPatchGenerator/generateFileWithOptions/AddAttributeWithOptionsAttribute.php b/testData/actions/generation/generator/ProductAttributePropertySetupPatchGenerator/generateFileWithOptions/AddAttributeWithOptionsAttribute.php new file mode 100644 index 000000000..2a1a353ca --- /dev/null +++ b/testData/actions/generation/generator/ProductAttributePropertySetupPatchGenerator/generateFileWithOptions/AddAttributeWithOptionsAttribute.php @@ -0,0 +1,105 @@ +moduleDataSetup = $moduleDataSetup; + $this->eavSetupFactory = $eavSetupFactory; + } + + /** + * Run code inside patch + * If code fails, patch must be reverted, in case when we are speaking about schema - then under revert + * means run PatchInterface::revert() + * + * If we speak about data, under revert means: $transaction->rollback() + */ + public function apply() + { + /** @var EavSetup $eavSetup */ + $eavSetup = $this->eavSetupFactory->create(['setup' => $this->moduleDataSetup]); + + $eavSetup->addAttribute( + Product::ENTITY, + 'attribute_with_options', + [ + 'is_visible_in_grid' => false, + 'is_html_allowed_on_front' => false, + 'visible_on_front' => false, + 'visible' => true, + 'global' => \Magento\Eav\Model\Entity\Attribute\ScopedAttributeInterface::SCOPE_GLOBAL, + 'label' => 'Attribute With Options', + 'source' => null, + 'type' => 'varchar', + 'is_used_in_grid' => false, + 'required' => false, + 'input' => 'multiselect', + 'is_filterable_in_grid' => false, + 'backend' => \Magento\Eav\Model\Entity\Attribute\Backend\ArrayBackend::class, + 'sort_order' => 10, + 'option' => [ + 'value' => [ + 'option_0' => ['option1'], + 'option_1' => ['option2'], + 'option_2' => ['option3'], + ] + ], + 'group' => 'General', + ] + ); + } + + /** + * Get array of patches that have to be executed prior to this. + * + * Example of implementation: + * + * [ + * \Vendor_Name\Module_Name\Setup\Patch\Patch1::class, + * \Vendor_Name\Module_Name\Setup\Patch\Patch2::class + * ] + * + * @return string[] + */ + public static function getDependencies() + { + return []; + } + + /** + * Get aliases (previous names) for the patch. + * + * @return string[] + */ + public function getAliases() + { + return []; + } +} diff --git a/testData/actions/generation/generator/SourceModelGenerator/generateFile/CustomSourceModel.php b/testData/actions/generation/generator/SourceModelGenerator/generateFile/CustomSourceModel.php new file mode 100644 index 000000000..891b5d153 --- /dev/null +++ b/testData/actions/generation/generator/SourceModelGenerator/generateFile/CustomSourceModel.php @@ -0,0 +1,18 @@ + options = new HashMap<>(); + options.put(0, "option1"); + options.put(1, "option2"); + options.put(2, "option3"); + customerEntityData.setOptions(options); + + customerEntityData.setDataPatchName("AddMultiselectTestCustomerAttribute"); + customerEntityData.setModuleName(MODULE_NAME); + + + final CustomerEavAttributePatchGenerator setupPatchGenerator = + new CustomerEavAttributePatchGenerator(customerEntityData, project); + final PsiFile dataPatchFile = setupPatchGenerator.generate( + "testGenerateMultiselectAttributeDataPatch" + ); + + final String filePatch = this.getFixturePath("AddMultiselectTestCustomerAttribute.php"); + final PsiFile expectedFile = myFixture.configureByFile(filePatch); + + assertGeneratedFileIsCorrect( + expectedFile, + "src/app/code/Foo/Bar/Setup/Patch/Data", + dataPatchFile + ); + } +} diff --git a/tests/com/magento/idea/magento2plugin/actions/generation/generator/ProductAttributePropertySetupPatchGeneratorTest.java b/tests/com/magento/idea/magento2plugin/actions/generation/generator/ProductAttributePropertySetupPatchGeneratorTest.java new file mode 100644 index 000000000..8e05991c2 --- /dev/null +++ b/tests/com/magento/idea/magento2plugin/actions/generation/generator/ProductAttributePropertySetupPatchGeneratorTest.java @@ -0,0 +1,215 @@ +/* + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +package com.magento.idea.magento2plugin.actions.generation.generator; + +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiFile; +import com.magento.idea.magento2plugin.actions.generation.data.ProductEntityData; +import com.magento.idea.magento2plugin.magento.packages.eav.AttributeScope; +import com.magento.idea.magento2plugin.magento.packages.eav.AttributeSourceModel; +import java.util.HashMap; +import java.util.Map; + +public class ProductAttributePropertySetupPatchGeneratorTest extends BaseGeneratorTestCase { + private static final String MODULE_NAME = "Foo_Bar"; + private static final String LABEL = "Test Label"; + private static final String TYPE = "static"; + private static final int SORT_ORDER = 10; + private static final String GROUP = "General"; + private static final String FILE_PATH = "src/app/code/Foo/Bar/Setup/Patch/Data"; + + /** + * Test Data patch for product's eav attribute generator. + */ + public void testGenerateFile() { + final Project project = myFixture.getProject(); + + final ProductEntityData productEntityData = new ProductEntityData(); + productEntityData.setCode("test"); + productEntityData.setVisibleInGrid(false); + productEntityData.setHtmlAllowedOnFront(false); + productEntityData.setVisibleOnFront(false); + productEntityData.setVisible(true); + productEntityData.setScope(AttributeScope.GLOBAL.getScope()); + productEntityData.setLabel(LABEL); + productEntityData.setType(TYPE); + productEntityData.setUsedInGrid(false); + productEntityData.setRequired(false); + productEntityData.setInput("text"); + productEntityData.setFilterableInGrid(false); + productEntityData.setSortOrder(SORT_ORDER); + productEntityData.setGroup(GROUP); + + productEntityData.setDataPatchName("AddTestAttribute"); + productEntityData.setModuleName(MODULE_NAME); + + final EavAttributeSetupPatchGenerator setupPatchGenerator = + new EavAttributeSetupPatchGenerator(productEntityData, project); + final PsiFile dataPatchFile = setupPatchGenerator.generate("testGenerateFile"); + + final String filePatch = this.getFixturePath("AddTestAttribute.php"); + final PsiFile expectedFile = myFixture.configureByFile(filePatch); + + assertGeneratedFileIsCorrect(expectedFile, FILE_PATH, dataPatchFile); + } + + /** + * Tests the generated file with the boolean source model. + */ + public void testGenerateFileWithBooleanSourceModel() { + final Project project = myFixture.getProject(); + + final ProductEntityData productEntityData = new ProductEntityData(); + productEntityData.setCode("boolean_input_attribute"); + productEntityData.setVisibleInGrid(false); + productEntityData.setHtmlAllowedOnFront(false); + productEntityData.setVisibleOnFront(false); + productEntityData.setVisible(true); + productEntityData.setScope(AttributeScope.GLOBAL.getScope()); + productEntityData.setLabel(LABEL); + productEntityData.setType(TYPE); + productEntityData.setUsedInGrid(false); + productEntityData.setRequired(false); + productEntityData.setInput("boolean"); + productEntityData.setSource(AttributeSourceModel.BOOLEAN.getSource()); + productEntityData.setFilterableInGrid(false); + productEntityData.setSortOrder(SORT_ORDER); + productEntityData.setGroup(GROUP); + + productEntityData.setDataPatchName("AddBooleanInputAttributeAttribute"); + productEntityData.setModuleName(MODULE_NAME); + + final EavAttributeSetupPatchGenerator setupPatchGenerator = + new EavAttributeSetupPatchGenerator(productEntityData, project); + final PsiFile dataPatchFile = setupPatchGenerator.generate( + "testGenerateFileWithBooleanSourceModel" + ); + + final String filePatch = this.getFixturePath("AddBooleanInputAttributeAttribute.php"); + final PsiFile expectedFile = myFixture.configureByFile(filePatch); + + assertGeneratedFileIsCorrect(expectedFile, FILE_PATH, dataPatchFile); + } + + /** + * Tests the generated file with the source model. + */ + public void testGenerateFileWithGeneratedSourceModel() { + final Project project = myFixture.getProject(); + + final ProductEntityData productEntityData = new ProductEntityData(); + productEntityData.setCode("attribute_with_custom_source"); + productEntityData.setVisibleInGrid(false); + productEntityData.setHtmlAllowedOnFront(false); + productEntityData.setVisibleOnFront(false); + productEntityData.setVisible(true); + productEntityData.setScope(AttributeScope.GLOBAL.getScope()); + productEntityData.setLabel("Test Label"); + productEntityData.setType("static"); + productEntityData.setUsedInGrid(false); + productEntityData.setRequired(false); + productEntityData.setInput("text"); + productEntityData.setSource("\\Foo\\Bar\\Model\\Source\\AttributeWithCustomSource"); + productEntityData.setFilterableInGrid(false); + productEntityData.setSortOrder(10); + productEntityData.setGroup(GROUP); + + productEntityData.setDataPatchName("AddAttributeWithCustomSourceAttribute"); + productEntityData.setModuleName(MODULE_NAME); + + final EavAttributeSetupPatchGenerator setupPatchGenerator = + new EavAttributeSetupPatchGenerator(productEntityData, project); + final PsiFile dataPatchFile = setupPatchGenerator.generate( + "testGenerateFileWithBooleanSourceModel" + ); + + final String filePatch = this.getFixturePath("AddAttributeWithCustomSourceAttribute.php"); + final PsiFile expectedFile = myFixture.configureByFile(filePatch); + + assertGeneratedFileIsCorrect(expectedFile, FILE_PATH, dataPatchFile); + } + + /** + * Tests file with the `apply to` attribute. + */ + public void testGenerateFileWithApplyToAttribute() { + final Project project = myFixture.getProject(); + + final ProductEntityData productEntityData = new ProductEntityData(); + productEntityData.setCode("applied_to_attribute"); + productEntityData.setVisibleInGrid(false); + productEntityData.setHtmlAllowedOnFront(false); + productEntityData.setVisibleOnFront(false); + productEntityData.setVisible(true); + productEntityData.setScope(AttributeScope.GLOBAL.getScope()); + productEntityData.setLabel("Test Label"); + productEntityData.setType("static"); + productEntityData.setUsedInGrid(false); + productEntityData.setRequired(false); + productEntityData.setInput("text"); + productEntityData.setFilterableInGrid(false); + productEntityData.setSortOrder(10); + productEntityData.setGroup(GROUP); + productEntityData.setApplyTo("configurable,simple"); + + productEntityData.setDataPatchName("AddAppliedToAttribute"); + productEntityData.setModuleName(MODULE_NAME); + + final EavAttributeSetupPatchGenerator setupPatchGenerator = + new EavAttributeSetupPatchGenerator(productEntityData, project); + final PsiFile dataPatchFile = setupPatchGenerator.generate( + "testGenerateFileWithApplyToAttribute" + ); + + final String filePatch = this.getFixturePath("AddAppliedToAttribute.php"); + final PsiFile expectedFile = myFixture.configureByFile(filePatch); + + assertGeneratedFileIsCorrect(expectedFile, FILE_PATH, dataPatchFile); + } + + /** + * Tests file with options. + */ + public void testGenerateFileWithOptions() { + final Project project = myFixture.getProject(); + + final ProductEntityData productEntityData = new ProductEntityData(); + productEntityData.setVisibleInGrid(false); + productEntityData.setHtmlAllowedOnFront(false); + productEntityData.setVisibleOnFront(false); + productEntityData.setVisible(true); + productEntityData.setScope(AttributeScope.GLOBAL.getScope()); + productEntityData.setCode("attribute_with_options"); + productEntityData.setLabel("Attribute With Options"); + productEntityData.setType("varchar"); + productEntityData.setUsedInGrid(false); + productEntityData.setRequired(false); + productEntityData.setInput("multiselect"); + productEntityData.setSource(AttributeSourceModel.NULLABLE_SOURCE.getSource()); + productEntityData.setFilterableInGrid(false); + productEntityData.setSortOrder(10); + productEntityData.setGroup(GROUP); + + final Map options = new HashMap<>(); + options.put(0, "option1"); + options.put(1, "option2"); + options.put(2, "option3"); + + productEntityData.setOptions(options); + + productEntityData.setDataPatchName("AddAttributeWithOptionsAttribute"); + productEntityData.setModuleName(MODULE_NAME); + + final EavAttributeSetupPatchGenerator setupPatchGenerator = + new EavAttributeSetupPatchGenerator(productEntityData, project); + final PsiFile dataPatchFile = setupPatchGenerator.generate("testGenerateFileWithOptions"); + + final String filePatch = this.getFixturePath("AddAttributeWithOptionsAttribute.php"); + final PsiFile expectedFile = myFixture.configureByFile(filePatch); + + assertGeneratedFileIsCorrect(expectedFile, FILE_PATH, dataPatchFile); + } +} diff --git a/tests/com/magento/idea/magento2plugin/actions/generation/generator/SourceModelGeneratorTest.java b/tests/com/magento/idea/magento2plugin/actions/generation/generator/SourceModelGeneratorTest.java new file mode 100644 index 000000000..76c059190 --- /dev/null +++ b/tests/com/magento/idea/magento2plugin/actions/generation/generator/SourceModelGeneratorTest.java @@ -0,0 +1,61 @@ +/* + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +package com.magento.idea.magento2plugin.actions.generation.generator; + +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiFile; +import com.magento.idea.magento2plugin.actions.generation.data.SourceModelData; + +public class SourceModelGeneratorTest extends BaseGeneratorTestCase { + private static final String MODULE_NAME = "Foo_Bar"; + + /** + * Test source model generation. + */ + public void testGenerateFile() { + final Project project = myFixture.getProject(); + + final SourceModelData sourceModelData = new SourceModelData(); + sourceModelData.setClassName("CustomSourceModel"); + sourceModelData.setModuleName(MODULE_NAME); + + final SourceModelGenerator sourceModelGeneratorGenerator = + new SourceModelGenerator(sourceModelData, project); + final PsiFile dataPatchFile = sourceModelGeneratorGenerator.generate("test"); + final String filePatch = this.getFixturePath("CustomSourceModel.php"); + final PsiFile expectedFile = myFixture.configureByFile(filePatch); + + assertGeneratedFileIsCorrect( + expectedFile, + "src/app/code/Foo/Bar/Model/Source", + dataPatchFile + ); + } + + /** + * Test source model in custom directory generation. + */ + public void testGenerateFileInCustomDirectory() { + final Project project = myFixture.getProject(); + + final SourceModelData sourceModelData = new SourceModelData(); + sourceModelData.setClassName("CustomSourceModel"); + sourceModelData.setModuleName(MODULE_NAME); + sourceModelData.setDirectory("Custom/Source/Directory"); + + final SourceModelGenerator sourceModelGeneratorGenerator = + new SourceModelGenerator(sourceModelData, project); + final PsiFile dataPatchFile = sourceModelGeneratorGenerator.generate("test custom dir"); + final String filePatch = this.getFixturePath("CustomSourceModel.php"); + final PsiFile expectedFile = myFixture.configureByFile(filePatch); + + assertGeneratedFileIsCorrect( + expectedFile, + "src/app/code/Foo/Bar/Custom/Source/Directory", + dataPatchFile + ); + } +}