diff --git a/resources/META-INF/plugin.xml b/resources/META-INF/plugin.xml
index f2537aa10..76e4e9329 100644
--- a/resources/META-INF/plugin.xml
+++ b/resources/META-INF/plugin.xml
@@ -229,6 +229,7 @@
+
diff --git a/resources/fileTemplates/internal/Magento Entity Save Controller Class.php.ft b/resources/fileTemplates/internal/Magento Entity Save Controller Class.php.ft
new file mode 100644
index 000000000..64de350af
--- /dev/null
+++ b/resources/fileTemplates/internal/Magento Entity Save Controller Class.php.ft
@@ -0,0 +1,86 @@
+dataPersistor = $dataPersistor;
+ $this->saveCommand = $saveCommand;
+ $this->entityDataFactory = $entityDataFactory;
+ }
+
+ /**
+ * Save ${ENTITY_NAME} Action.
+ *
+ * @return ResponseInterface|ResultInterface
+ */
+ public function execute()
+ {
+ $resultRedirect = $this->resultRedirectFactory->create();
+ $params = $this->getRequest()->getParams();
+
+ try {
+ /** @var ${ENTITY_DTO}|${DATA_OBJECT} $entityModel */
+ $entityModel = $this->entityDataFactory->create();
+ $entityModel->addData($params);
+ $this->saveCommand->execute($entityModel);
+ $this->messageManager->addSuccessMessage(
+ __('The ${ENTITY_NAME} data was saved successfully')
+ );
+ $this->dataPersistor->clear('entity');
+ } catch (${COULD_NOT_SAVE} $exception) {
+ $this->messageManager->addErrorMessage($exception->getMessage());
+ $this->dataPersistor->set('entity', $params);
+
+ return $resultRedirect->setPath('*/*/edit', [
+ '${ENTITY_ID}'=> $this->getRequest()->getParam('${ENTITY_ID}')
+ ]);
+ }
+
+ return $resultRedirect->setPath('*/*/');
+ }
+}
diff --git a/resources/fileTemplates/internal/Magento Entity Save Controller Class.php.html b/resources/fileTemplates/internal/Magento Entity Save Controller Class.php.html
new file mode 100644
index 000000000..f36b52820
--- /dev/null
+++ b/resources/fileTemplates/internal/Magento Entity Save Controller Class.php.html
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
+ Template's predefined variables: |
+
+
+ ${NAMESPACE} |
+ |
+ |
+
+
+
+
diff --git a/src/com/magento/idea/magento2plugin/actions/generation/data/SaveEntityControllerFileData.java b/src/com/magento/idea/magento2plugin/actions/generation/data/SaveEntityControllerFileData.java
new file mode 100644
index 000000000..f43ad3da6
--- /dev/null
+++ b/src/com/magento/idea/magento2plugin/actions/generation/data/SaveEntityControllerFileData.java
@@ -0,0 +1,111 @@
+/*
+ * 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 SaveEntityControllerFileData {
+
+ private final String entityName;
+ private final String moduleName;
+ private final String namespace;
+ private final String saveCommandFqn;
+ private final String dtoType;
+ private final String acl;
+ private final String entityId;
+
+ /**
+ * Controller save file constructor.
+ *
+ * @param entityName String
+ * @param moduleName String
+ * @param namespace String
+ * @param saveCommandFqn String
+ * @param acl String
+ * @param dtoType String
+ * @param entityId String
+ */
+ public SaveEntityControllerFileData(
+ final @NotNull String entityName,
+ final @NotNull String moduleName,
+ final @NotNull String namespace,
+ final @NotNull String saveCommandFqn,
+ final @NotNull String dtoType,
+ final @NotNull String acl,
+ final @NotNull String entityId
+ ) {
+ this.entityName = entityName;
+ this.moduleName = moduleName;
+ this.namespace = namespace;
+ this.saveCommandFqn = saveCommandFqn;
+ this.dtoType = dtoType;
+ this.acl = acl;
+ this.entityId = entityId;
+ }
+
+ /**
+ * Get entity id.
+ *
+ * @return String
+ */
+ public String getEntityId() {
+ return entityId;
+ }
+
+ /**
+ * Get acl.
+ *
+ * @return String
+ */
+ public String getAcl() {
+ return acl;
+ }
+
+ /**
+ * Get dto type.
+ *
+ * @return String
+ */
+ public String getDtoType() {
+ return dtoType;
+ }
+
+ /**
+ * Get save command Fqn.
+ *
+ * @return String
+ */
+ public String getSaveCommandFqn() {
+ return saveCommandFqn;
+ }
+
+ /**
+ * Get entity name.
+ *
+ * @return String
+ */
+ public String getEntityName() {
+ return entityName;
+ }
+
+ /**
+ * Get module name.
+ *
+ * @return String
+ */
+ public String getModuleName() {
+ return moduleName;
+ }
+
+ /**
+ * Get namespace.
+ *
+ * @return String
+ */
+ public String getNamespace() {
+ return namespace;
+ }
+}
diff --git a/src/com/magento/idea/magento2plugin/actions/generation/dialog/NewEntityDialog.java b/src/com/magento/idea/magento2plugin/actions/generation/dialog/NewEntityDialog.java
index fd16ec207..d40a716be 100644
--- a/src/com/magento/idea/magento2plugin/actions/generation/dialog/NewEntityDialog.java
+++ b/src/com/magento/idea/magento2plugin/actions/generation/dialog/NewEntityDialog.java
@@ -18,13 +18,14 @@
import com.magento.idea.magento2plugin.actions.generation.data.DataModelData;
import com.magento.idea.magento2plugin.actions.generation.data.DataModelInterfaceData;
import com.magento.idea.magento2plugin.actions.generation.data.DbSchemaXmlData;
+import com.magento.idea.magento2plugin.actions.generation.data.GetListQueryModelData;
import com.magento.idea.magento2plugin.actions.generation.data.LayoutXmlData;
import com.magento.idea.magento2plugin.actions.generation.data.MenuXmlData;
import com.magento.idea.magento2plugin.actions.generation.data.ModelData;
-import com.magento.idea.magento2plugin.actions.generation.data.GetListQueryModelData;
import com.magento.idea.magento2plugin.actions.generation.data.PreferenceDiXmFileData;
import com.magento.idea.magento2plugin.actions.generation.data.ResourceModelData;
import com.magento.idea.magento2plugin.actions.generation.data.RoutesXmlData;
+import com.magento.idea.magento2plugin.actions.generation.data.SaveEntityControllerFileData;
import com.magento.idea.magento2plugin.actions.generation.data.UiComponentDataProviderData;
import com.magento.idea.magento2plugin.actions.generation.data.UiComponentFormButtonData;
import com.magento.idea.magento2plugin.actions.generation.data.UiComponentFormFieldData;
@@ -39,15 +40,16 @@
import com.magento.idea.magento2plugin.actions.generation.generator.DataModelInterfaceGenerator;
import com.magento.idea.magento2plugin.actions.generation.generator.DbSchemaWhitelistJsonGenerator;
import com.magento.idea.magento2plugin.actions.generation.generator.DbSchemaXmlGenerator;
+import com.magento.idea.magento2plugin.actions.generation.generator.GetListQueryModelGenerator;
import com.magento.idea.magento2plugin.actions.generation.generator.LayoutXmlGenerator;
import com.magento.idea.magento2plugin.actions.generation.generator.MenuXmlGenerator;
import com.magento.idea.magento2plugin.actions.generation.generator.ModuleCollectionGenerator;
import com.magento.idea.magento2plugin.actions.generation.generator.ModuleControllerClassGenerator;
import com.magento.idea.magento2plugin.actions.generation.generator.ModuleModelGenerator;
import com.magento.idea.magento2plugin.actions.generation.generator.ModuleResourceModelGenerator;
-import com.magento.idea.magento2plugin.actions.generation.generator.GetListQueryModelGenerator;
import com.magento.idea.magento2plugin.actions.generation.generator.PreferenceDiXmlGenerator;
import com.magento.idea.magento2plugin.actions.generation.generator.RoutesXmlGenerator;
+import com.magento.idea.magento2plugin.actions.generation.generator.SaveEntityControllerFileGenerator;
import com.magento.idea.magento2plugin.actions.generation.generator.UiComponentDataProviderGenerator;
import com.magento.idea.magento2plugin.actions.generation.generator.UiComponentFormGenerator;
import com.magento.idea.magento2plugin.actions.generation.generator.UiComponentGridXmlGenerator;
@@ -60,6 +62,7 @@
import com.magento.idea.magento2plugin.magento.files.ModuleMenuXml;
import com.magento.idea.magento2plugin.magento.files.ResourceModelPhp;
import com.magento.idea.magento2plugin.magento.files.UiComponentDataProviderPhp;
+import com.magento.idea.magento2plugin.magento.files.actions.SaveActionFile;
import com.magento.idea.magento2plugin.magento.packages.Areas;
import com.magento.idea.magento2plugin.magento.packages.File;
import com.magento.idea.magento2plugin.magento.packages.HttpMethod;
@@ -107,7 +110,8 @@
"PMD.ExcessiveImports",
"PMD.GodClass",
"PMD.TooManyMethods",
- "PMD.CyclomaticComplexity"
+ "PMD.CyclomaticComplexity",
+ "PMD.ExcessiveClassLength"
})
public class NewEntityDialog extends AbstractDialog {
@NotNull
@@ -279,7 +283,7 @@ private void onOK() {
generateRoutesXmlFile();
generateViewControllerFile();
- generateSubmitControllerFile();
+ generateSaveControllerFile();
generateModelGetListQueryFile();
generateDataProviderFile();
generateLayoutFile();
@@ -303,6 +307,49 @@ private void onOK() {
this.setVisible(false);
}
+ /**
+ * Generate Save Controller file.
+ */
+ private void generateSaveControllerFile() {
+ final NamespaceBuilder dtoModelNamespace = getDataModelNamespace();
+ final NamespaceBuilder dtoInterfaceModelNamespace = getDataModelInterfaceNamespace();
+ final NamespaceBuilder namespace = new NamespaceBuilder(
+ getModuleName(),
+ SaveActionFile.CLASS_NAME,
+ SaveActionFile.getDirectory(getEntityName())
+ );
+ final String dtoType;
+
+ if (createInterface.isSelected()) {
+ dtoType = dtoInterfaceModelNamespace.getClassFqn();
+ } else {
+ dtoType = dtoModelNamespace.getClassFqn();
+ }
+
+ new SaveEntityControllerFileGenerator(new SaveEntityControllerFileData(
+ getEntityName(),
+ getModuleName(),
+ namespace.getNamespace(),
+ getSaveEntityCommandClassFqn(),
+ dtoType,
+ getAcl(),
+ getEntityIdColumn()
+ ), project).generate(ACTION_NAME, false);
+ }
+
+ /**
+ * Get save entity command class Fqn.
+ *
+ * @return String
+ */
+ private String getSaveEntityCommandClassFqn() {
+ //TODO: change this stub after the save command generated will be implemented.
+ final NamespaceBuilder namespaceBuilder =
+ new NamespaceBuilder(getModuleName(), "SaveCommand", "Command/" + getEntityName());
+
+ return namespaceBuilder.getClassFqn();
+ }
+
private PsiFile generateModelFile() {
final NamespaceBuilder modelNamespace = getModelNamespace();
final NamespaceBuilder resourceModelNamespace = getResourceModelNamespace();
@@ -574,24 +621,11 @@ private String getControllerDirectory() {
return ControllerBackendPhp.DEFAULT_DIR + File.separator;
}
- private PsiFile generateSubmitControllerFile() {
- final NamespaceBuilder namespace = new NamespaceBuilder(
- getModuleName(),
- getSubmitActionName(),
- getViewControllerDirectory()
- );
- return new ModuleControllerClassGenerator(new ControllerFileData(
- getViewControllerDirectory(),
- getSubmitActionName(),
- getModuleName(),
- Areas.adminhtml.toString(),
- HttpMethod.POST.toString(),
- getAcl(),
- true,
- namespace.getNamespace()
- ), project).generate(ACTION_NAME, false);
- }
-
+ /**
+ * Get Acl id.
+ *
+ * @return String
+ */
public String getAcl() {
return acl.getText().trim();
}
diff --git a/src/com/magento/idea/magento2plugin/actions/generation/generator/SaveEntityControllerFileGenerator.java b/src/com/magento/idea/magento2plugin/actions/generation/generator/SaveEntityControllerFileGenerator.java
new file mode 100644
index 000000000..5bb8c710b
--- /dev/null
+++ b/src/com/magento/idea/magento2plugin/actions/generation/generator/SaveEntityControllerFileGenerator.java
@@ -0,0 +1,146 @@
+package com.magento.idea.magento2plugin.actions.generation.generator;
+
+import com.intellij.openapi.project.Project;
+import com.intellij.psi.PsiDirectory;
+import com.intellij.psi.PsiFile;
+import com.jetbrains.php.lang.psi.elements.PhpClass;
+import com.magento.idea.magento2plugin.actions.generation.data.SaveEntityControllerFileData;
+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.PhpClassGeneratorUtil;
+import com.magento.idea.magento2plugin.indexes.ModuleIndex;
+import com.magento.idea.magento2plugin.magento.files.actions.SaveActionFile;
+import com.magento.idea.magento2plugin.magento.packages.HttpMethod;
+import com.magento.idea.magento2plugin.magento.packages.Package;
+import com.magento.idea.magento2plugin.magento.packages.code.BackendModuleType;
+import com.magento.idea.magento2plugin.magento.packages.code.FrameworkLibraryType;
+import com.magento.idea.magento2plugin.util.GetPhpClassByFQN;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Properties;
+import org.jetbrains.annotations.NotNull;
+
+public class SaveEntityControllerFileGenerator extends FileGenerator {
+
+ private final SaveEntityControllerFileData fileData;
+ private final FileFromTemplateGenerator fileFromTemplateGenerator;
+ private final DirectoryGenerator directoryGenerator;
+ private final ModuleIndex moduleIndex;
+ private final Project project;
+ private final boolean checkFileAlreadyExists;
+ private final List uses;
+
+ /**
+ * Save Entity Controller File Generator.
+ *
+ * @param fileData SaveEntityControllerFileData
+ * @param project Project
+ */
+ public SaveEntityControllerFileGenerator(
+ final @NotNull SaveEntityControllerFileData fileData,
+ final @NotNull Project project
+ ) {
+ this(fileData, project, true);
+ }
+
+ /**
+ * Save Entity Controller File Generator.
+ *
+ * @param fileData SaveEntityControllerFileData
+ * @param project Project
+ * @param checkFileAlreadyExists boolean
+ */
+ public SaveEntityControllerFileGenerator(
+ final @NotNull SaveEntityControllerFileData fileData,
+ final @NotNull Project project,
+ final boolean checkFileAlreadyExists
+ ) {
+ super(project);
+ this.fileData = fileData;
+ this.project = project;
+ this.checkFileAlreadyExists = checkFileAlreadyExists;
+ fileFromTemplateGenerator = FileFromTemplateGenerator.getInstance(project);
+ moduleIndex = ModuleIndex.getInstance(project);
+ directoryGenerator = DirectoryGenerator.getInstance();
+ uses = new ArrayList<>();
+ }
+
+ /**
+ * Generate Save action controller for entity.
+ *
+ * @param actionName String
+ *
+ * @return PsiFile
+ */
+ @Override
+ public PsiFile generate(final @NotNull String actionName) {
+ final PhpClass saveActionClass = GetPhpClassByFQN.getInstance(project).execute(
+ String.format(
+ "%s%s%s",
+ fileData.getNamespace(),
+ Package.fqnSeparator,
+ SaveActionFile.CLASS_NAME
+ )
+ );
+
+ if (this.checkFileAlreadyExists && saveActionClass != null) {
+ return saveActionClass.getContainingFile();
+ }
+ final PsiDirectory moduleBaseDir = moduleIndex.getModuleDirectoryByModuleName(
+ fileData.getModuleName()
+ );
+ final PsiDirectory baseDirectory = directoryGenerator.findOrCreateSubdirectories(
+ moduleBaseDir,
+ SaveActionFile.getDirectory(fileData.getEntityName())
+ );
+
+ return fileFromTemplateGenerator.generate(
+ SaveActionFile.getInstance(),
+ getAttributes(),
+ baseDirectory,
+ actionName
+ );
+ }
+
+ @Override
+ protected void fillAttributes(final @NotNull Properties attributes) {
+ uses.add(BackendModuleType.CONTEXT.getType());
+ uses.add(FrameworkLibraryType.RESPONSE_INTERFACE.getType());
+ uses.add(FrameworkLibraryType.RESULT_INTERFACE.getType());
+ attributes.setProperty("NAMESPACE", fileData.getNamespace());
+ attributes.setProperty("ENTITY_NAME", fileData.getEntityName());
+ attributes.setProperty("CLASS_NAME", SaveActionFile.CLASS_NAME);
+ attributes.setProperty("ENTITY_ID", fileData.getEntityId());
+ attributes.setProperty("ADMIN_RESOURCE", SaveActionFile.getAdminResource(
+ fileData.getModuleName(),
+ fileData.getAcl()
+ )
+ );
+ addProperty(attributes, "IMPLEMENTS", HttpMethod.POST.getInterfaceFqn());
+ addProperty(attributes, "DATA_PERSISTOR", FrameworkLibraryType.DATA_PERSISTOR.getType());
+ addProperty(attributes, "ENTITY_DTO", fileData.getDtoType());
+ addProperty(attributes, "ENTITY_DTO_FACTORY", fileData.getDtoType().concat("Factory"));
+ addProperty(attributes, "EXTENDS", BackendModuleType.EXTENDS.getType());
+ addProperty(attributes, "SAVE_COMMAND", fileData.getSaveCommandFqn());
+ addProperty(attributes, "DATA_OBJECT", FrameworkLibraryType.DATA_OBJECT.getType());
+ addProperty(attributes, "COULD_NOT_SAVE", SaveActionFile.COULD_NOT_SAVE);
+
+ attributes.setProperty("USES", PhpClassGeneratorUtil.formatUses(uses));
+ }
+
+ /**
+ * Add type to properties.
+ *
+ * @param properties Properties
+ * @param propertyName String
+ * @param type String
+ */
+ protected void addProperty(
+ final @NotNull Properties properties,
+ final String propertyName,
+ final String type
+ ) {
+ uses.add(type);
+ properties.setProperty(propertyName, PhpClassGeneratorUtil.getNameFromFqn(type));
+ }
+}
diff --git a/src/com/magento/idea/magento2plugin/actions/generation/generator/util/DirectoryGenerator.java b/src/com/magento/idea/magento2plugin/actions/generation/generator/util/DirectoryGenerator.java
index 64f5a83d2..b59adb67d 100644
--- a/src/com/magento/idea/magento2plugin/actions/generation/generator/util/DirectoryGenerator.java
+++ b/src/com/magento/idea/magento2plugin/actions/generation/generator/util/DirectoryGenerator.java
@@ -9,6 +9,8 @@
import com.intellij.psi.PsiDirectory;
import com.magento.idea.magento2plugin.actions.generation.generator.data.ModuleDirectoriesData;
import com.magento.idea.magento2plugin.magento.packages.Package;
+import java.io.File;
+import java.util.Arrays;
import org.jetbrains.annotations.NotNull;
public class DirectoryGenerator {
@@ -62,4 +64,44 @@ public PsiDirectory findOrCreateSubdirectory(
final PsiDirectory sub = parent.findSubdirectory(subdirName);
return sub == null ? WriteAction.compute(() -> parent.createSubdirectory(subdirName)) : sub;
}
+
+ /**
+ * Find or create subdirectories.
+ *
+ * @param parent PsiDirectory
+ * @param subdirPath String
+ *
+ * @return PsiDirectory
+ */
+ public PsiDirectory findOrCreateSubdirectories(
+ final @NotNull PsiDirectory parent,
+ final @NotNull String subdirPath
+ ) {
+ PsiDirectory lastDirectory = null;
+ final String[] directories = subdirPath.split(File.separator);
+
+ for (final String directory : Arrays.asList(directories)) {
+ if (lastDirectory == null) {
+ final PsiDirectory subDir = parent.findSubdirectory(directory);
+
+ if (subDir == null) {
+ lastDirectory = WriteAction.compute(() -> parent.createSubdirectory(directory));
+ } else {
+ lastDirectory = subDir;
+ }
+ } else {
+ final PsiDirectory subDir = lastDirectory.findSubdirectory(directory);
+
+ if (subDir == null) {
+ final PsiDirectory finalLastDirectory = lastDirectory;
+ lastDirectory = WriteAction.compute(() ->
+ finalLastDirectory.createSubdirectory(directory));
+ } else {
+ lastDirectory = subDir;
+ }
+ }
+ }
+
+ return lastDirectory;
+ }
}
diff --git a/src/com/magento/idea/magento2plugin/magento/files/actions/SaveActionFile.java b/src/com/magento/idea/magento2plugin/magento/files/actions/SaveActionFile.java
new file mode 100644
index 000000000..3f8eb4cf7
--- /dev/null
+++ b/src/com/magento/idea/magento2plugin/magento/files/actions/SaveActionFile.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright © Magento, Inc. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+package com.magento.idea.magento2plugin.magento.files.actions;
+
+import com.intellij.lang.Language;
+import com.jetbrains.php.lang.PhpLanguage;
+import com.magento.idea.magento2plugin.magento.files.ModuleFileInterface;
+import org.jetbrains.annotations.NotNull;
+
+
+public final class SaveActionFile implements ModuleFileInterface {
+ public static final String CLASS_NAME = "Save";
+ public static final String FILE_EXTENSION = "php";
+ public static final String TEMPLATE = "Magento Entity Save Controller Class";
+ private static final String DIRECTORY = "Controller/Adminhtml";
+ private static final SaveActionFile INSTANCE = new SaveActionFile();
+ public static final String COULD_NOT_SAVE =
+ "Magento\\Framework\\Exception\\CouldNotSaveException";
+
+ /**
+ * Get singleton instance of the class.
+ *
+ * @return SaveAction
+ */
+ public static SaveActionFile getInstance() {
+ return INSTANCE;
+ }
+
+ /**
+ * Get Directory path from the module root.
+ *
+ * @param entityName String
+ *
+ * @return String
+ */
+ public static String getDirectory(final @NotNull String entityName) {
+ return DIRECTORY.concat("/" + entityName.concat("Model"));
+ }
+
+ /**
+ * Get admin resource.
+ *
+ * @param moduleName String
+ * @param acl String
+ *
+ * @return String
+ */
+ public static String getAdminResource(
+ final @NotNull String moduleName,
+ final @NotNull String acl
+ ) {
+ return moduleName + "::" + acl;
+ }
+
+ @Override
+ public String getFileName() {
+ return CLASS_NAME.concat("." + FILE_EXTENSION);
+ }
+
+ @Override
+ public String getTemplate() {
+ return TEMPLATE;
+ }
+
+ @Override
+ public Language getLanguage() {
+ return PhpLanguage.INSTANCE;
+ }
+}
diff --git a/src/com/magento/idea/magento2plugin/magento/packages/HttpMethod.java b/src/com/magento/idea/magento2plugin/magento/packages/HttpMethod.java
index d8c0a8c43..327f84fce 100644
--- a/src/com/magento/idea/magento2plugin/magento/packages/HttpMethod.java
+++ b/src/com/magento/idea/magento2plugin/magento/packages/HttpMethod.java
@@ -5,8 +5,10 @@
package com.magento.idea.magento2plugin.magento.packages;
+import com.magento.idea.magento2plugin.actions.generation.generator.util.PhpClassGeneratorUtil;
import java.util.ArrayList;
import java.util.List;
+import org.jetbrains.annotations.NotNull;
public enum HttpMethod {
GET("Magento\\Framework\\App\\Action\\HttpGetActionInterface"),
@@ -58,4 +60,13 @@ public static List getHttpMethodList() {
return methodNameList;
}
+
+ /**
+ * Get name from type FQN.
+ *
+ * @return String
+ */
+ public @NotNull String getTypeName() {
+ return PhpClassGeneratorUtil.getNameFromFqn(getInterfaceFqn());
+ }
}
diff --git a/src/com/magento/idea/magento2plugin/magento/packages/code/BackendModuleType.java b/src/com/magento/idea/magento2plugin/magento/packages/code/BackendModuleType.java
new file mode 100644
index 000000000..1036a4413
--- /dev/null
+++ b/src/com/magento/idea/magento2plugin/magento/packages/code/BackendModuleType.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright © Magento, Inc. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+package com.magento.idea.magento2plugin.magento.packages.code;
+
+import com.magento.idea.magento2plugin.actions.generation.generator.util.PhpClassGeneratorUtil;
+import org.jetbrains.annotations.NotNull;
+
+public enum BackendModuleType {
+ CONTEXT("Magento\\Backend\\App\\Action\\Context"),
+ EXTENDS("Magento\\Backend\\App\\Action");
+
+ /**
+ * Backend module type.
+ */
+ private final String type;
+
+ /**
+ * Backend module type ENUM constructor.
+ *
+ * @param type String
+ */
+ BackendModuleType(final @NotNull String type) {
+ this.type = type;
+ }
+
+ /**
+ * Get type.
+ *
+ * @return String
+ */
+ public @NotNull String getType() {
+ return type;
+ }
+
+ /**
+ * Get name from type FQN.
+ *
+ * @return String
+ */
+ public @NotNull String getTypeName() {
+ return PhpClassGeneratorUtil.getNameFromFqn(getType());
+ }
+}
diff --git a/src/com/magento/idea/magento2plugin/magento/packages/code/FrameworkLibraryType.java b/src/com/magento/idea/magento2plugin/magento/packages/code/FrameworkLibraryType.java
index 924554396..4e00a3d80 100644
--- a/src/com/magento/idea/magento2plugin/magento/packages/code/FrameworkLibraryType.java
+++ b/src/com/magento/idea/magento2plugin/magento/packages/code/FrameworkLibraryType.java
@@ -9,13 +9,17 @@
import org.jetbrains.annotations.NotNull;
public enum FrameworkLibraryType {
+ API_SEARCH_CRITERIA_BUILDER("Magento\\Framework\\Api\\Search\\SearchCriteriaBuilder"),
COLLECTION_PROCESSOR("Magento\\Framework\\Api\\SearchCriteria\\CollectionProcessorInterface"),
+ DATA_PERSISTOR("Magento\\Framework\\App\\Request\\DataPersistorInterface"),
+ DATA_OBJECT("Magento\\Framework\\DataObject"),
FILTER_BUILDER("Magento\\Framework\\Api\\FilterBuilder"),
+ RESULT_INTERFACE("Magento\\Framework\\Controller\\ResultInterface"),
+ RESPONSE_INTERFACE("Magento\\Framework\\App\\ResponseInterface"),
REPORTING("Magento\\Framework\\Api\\Search\\ReportingInterface"),
REQUEST("Magento\\Framework\\App\\RequestInterface"),
SEARCH_CRITERIA("Magento\\Framework\\Api\\SearchCriteriaInterface"),
SEARCH_CRITERIA_BUILDER("Magento\\Framework\\Api\\SearchCriteriaBuilder"),
- API_SEARCH_CRITERIA_BUILDER("Magento\\Framework\\Api\\Search\\SearchCriteriaBuilder"),
SEARCH_RESULT("Magento\\Framework\\Api\\SearchResultsInterface");
/**
diff --git a/testData/actions/generation/generator/SaveEntityActionGenerator/generateSaveEntityActionWithInterfaceFile/Save.php b/testData/actions/generation/generator/SaveEntityActionGenerator/generateSaveEntityActionWithInterfaceFile/Save.php
new file mode 100644
index 000000000..7a6b9f49f
--- /dev/null
+++ b/testData/actions/generation/generator/SaveEntityActionGenerator/generateSaveEntityActionWithInterfaceFile/Save.php
@@ -0,0 +1,93 @@
+dataPersistor = $dataPersistor;
+ $this->saveCommand = $saveCommand;
+ $this->entityDataFactory = $entityDataFactory;
+ }
+
+ /**
+ * Save Company Action.
+ *
+ * @return ResponseInterface|ResultInterface
+ */
+ public function execute()
+ {
+ $resultRedirect = $this->resultRedirectFactory->create();
+ $params = $this->getRequest()->getParams();
+
+ try {
+ /** @var CompanyInterface|DataObject $entityModel */
+ $entityModel = $this->entityDataFactory->create();
+ $entityModel->addData($params);
+ $this->saveCommand->execute($entityModel);
+ $this->messageManager->addSuccessMessage(
+ __('The Company data was saved successfully')
+ );
+ $this->dataPersistor->clear('entity');
+ } catch (CouldNotSaveException $exception) {
+ $this->messageManager->addErrorMessage($exception->getMessage());
+ $this->dataPersistor->set('entity', $params);
+
+ return $resultRedirect->setPath('*/*/edit', [
+ 'entity_id' => $this->getRequest()->getParam('entity_id')
+ ]);
+ }
+
+ return $resultRedirect->setPath('*/*/');
+ }
+}
diff --git a/testData/actions/generation/generator/SaveEntityActionGenerator/generateSaveEntityActionWithoutInterfaceFile/Save.php b/testData/actions/generation/generator/SaveEntityActionGenerator/generateSaveEntityActionWithoutInterfaceFile/Save.php
new file mode 100644
index 000000000..6bb2ad413
--- /dev/null
+++ b/testData/actions/generation/generator/SaveEntityActionGenerator/generateSaveEntityActionWithoutInterfaceFile/Save.php
@@ -0,0 +1,93 @@
+dataPersistor = $dataPersistor;
+ $this->saveCommand = $saveCommand;
+ $this->entityDataFactory = $entityDataFactory;
+ }
+
+ /**
+ * Save Company Action.
+ *
+ * @return ResponseInterface|ResultInterface
+ */
+ public function execute()
+ {
+ $resultRedirect = $this->resultRedirectFactory->create();
+ $params = $this->getRequest()->getParams();
+
+ try {
+ /** @var CompanyModel|DataObject $entityModel */
+ $entityModel = $this->entityDataFactory->create();
+ $entityModel->addData($params);
+ $this->saveCommand->execute($entityModel);
+ $this->messageManager->addSuccessMessage(
+ __('The Company data was saved successfully')
+ );
+ $this->dataPersistor->clear('entity');
+ } catch (CouldNotSaveException $exception) {
+ $this->messageManager->addErrorMessage($exception->getMessage());
+ $this->dataPersistor->set('entity', $params);
+
+ return $resultRedirect->setPath('*/*/edit', [
+ 'entity_id' => $this->getRequest()->getParam('entity_id')
+ ]);
+ }
+
+ return $resultRedirect->setPath('*/*/');
+ }
+}
diff --git a/tests/com/magento/idea/magento2plugin/actions/generation/generator/SaveEntityActionGeneratorTest.java b/tests/com/magento/idea/magento2plugin/actions/generation/generator/SaveEntityActionGeneratorTest.java
new file mode 100644
index 000000000..7b0b92484
--- /dev/null
+++ b/tests/com/magento/idea/magento2plugin/actions/generation/generator/SaveEntityActionGeneratorTest.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright © Magento, Inc. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+package com.magento.idea.magento2plugin.actions.generation.generator;
+
+import com.intellij.psi.PsiFile;
+import com.magento.idea.magento2plugin.actions.generation.data.SaveEntityControllerFileData;
+import com.magento.idea.magento2plugin.magento.files.actions.SaveActionFile;
+
+public class SaveEntityActionGeneratorTest extends BaseGeneratorTestCase {
+ private static final String MODULE_NAME = "Foo_Bar";
+ private static final String ENTITY_NAME = "Company";
+ private static final String EXPECTED_DIRECTORY =
+ "/src/app/code/Foo/Bar/Controller/Adminhtml/" + ENTITY_NAME + "Model";
+ private static final String NAMESPACE =
+ "Foo\\Bar\\Controller\\Adminhtml\\" + ENTITY_NAME + "Model";
+ private static final String SAVE_COMMAND =
+ "Foo\\Bar\\Command\\" + ENTITY_NAME + "\\SaveCommand";
+ private static final String DTO_TYPE =
+ "Foo\\Bar\\Model\\" + ENTITY_NAME + "Model" + "\\CompanyModel";
+ private static final String DTO_TYPE_INTERFACE =
+ "Foo\\Bar\\Api\\Data\\" + ENTITY_NAME + "Interface";
+ private static final String ACL = "company_id";
+ private static final String ENTITY_ID = "entity_id";
+
+ /**
+ * Test generation of Save controller for entity without interface.
+ */
+ public void testGenerateSaveEntityActionWithoutInterfaceFile() {
+ final SaveEntityControllerFileData saveEntityControllerFileData =
+ new SaveEntityControllerFileData(
+ ENTITY_NAME,
+ MODULE_NAME,
+ NAMESPACE,
+ SAVE_COMMAND,
+ DTO_TYPE,
+ ACL,
+ ENTITY_ID
+ );
+ final SaveEntityControllerFileGenerator saveEntityControllerFileGenerator =
+ new SaveEntityControllerFileGenerator(
+ saveEntityControllerFileData,
+ myFixture.getProject(),
+ false
+ );
+ final PsiFile saveEntityActionFile = saveEntityControllerFileGenerator.generate("test");
+ final String filePath = this.getFixturePath(SaveActionFile.getInstance().getFileName());
+ final PsiFile expectedFile = myFixture.configureByFile(filePath);
+
+ assertGeneratedFileIsCorrect(
+ expectedFile,
+ EXPECTED_DIRECTORY,
+ saveEntityActionFile
+ );
+ }
+
+ /**
+ * Test generation of Save controller for entity with interface.
+ */
+ public void testGenerateSaveEntityActionWithInterfaceFile() {
+ final SaveEntityControllerFileData saveEntityControllerFileData =
+ new SaveEntityControllerFileData(
+ ENTITY_NAME,
+ MODULE_NAME,
+ NAMESPACE,
+ SAVE_COMMAND,
+ DTO_TYPE_INTERFACE,
+ ACL,
+ ENTITY_ID
+ );
+ final SaveEntityControllerFileGenerator saveEntityControllerFileGenerator =
+ new SaveEntityControllerFileGenerator(
+ saveEntityControllerFileData,
+ myFixture.getProject(),
+ true
+ );
+ final PsiFile saveEntityActionFile = saveEntityControllerFileGenerator.generate("test");
+ final String filePath = this.getFixturePath(SaveActionFile.getInstance().getFileName());
+ final PsiFile expectedFile = myFixture.configureByFile(filePath);
+
+ assertGeneratedFileIsCorrect(
+ expectedFile,
+ EXPECTED_DIRECTORY,
+ saveEntityActionFile
+ );
+ }
+}