diff --git a/resources/fileTemplates/internal/Magento Module DI Xml.xml.ft b/resources/fileTemplates/internal/Magento Module DI Xml.xml.ft
new file mode 100644
index 000000000..5de0638f6
--- /dev/null
+++ b/resources/fileTemplates/internal/Magento Module DI Xml.xml.ft
@@ -0,0 +1,3 @@
+
+
+
diff --git a/resources/inspectionDescriptions/PluginInspection.html b/resources/inspectionDescriptions/PluginInspection.html
index e51e3d4fd..e4ec88c5a 100644
--- a/resources/inspectionDescriptions/PluginInspection.html
+++ b/resources/inspectionDescriptions/PluginInspection.html
@@ -1,3 +1,9 @@
+
Plugins can not be used with the following:
diff --git a/src/com/magento/idea/magento2plugin/actions/generation/CreateAPluginAction.java b/src/com/magento/idea/magento2plugin/actions/generation/CreateAPluginAction.java
new file mode 100644
index 000000000..380ef26f9
--- /dev/null
+++ b/src/com/magento/idea/magento2plugin/actions/generation/CreateAPluginAction.java
@@ -0,0 +1,105 @@
+/*
+ * Copyright © Magento, Inc. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+package com.magento.idea.magento2plugin.actions.generation;
+
+import com.intellij.openapi.actionSystem.AnActionEvent;
+import com.intellij.openapi.actionSystem.PlatformDataKeys;
+import com.intellij.openapi.editor.Caret;
+import com.intellij.openapi.project.DumbAwareAction;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.Pair;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiFile;
+import com.jetbrains.php.lang.psi.PhpFile;
+import com.jetbrains.php.lang.psi.elements.Method;
+import com.jetbrains.php.lang.psi.elements.PhpClass;
+import com.magento.idea.magento2plugin.MagentoIcons;
+import com.magento.idea.magento2plugin.actions.generation.dialog.CreateAPluginDialog;
+import com.magento.idea.magento2plugin.util.GetFirstClassOfFile;
+import com.magento.idea.magento2plugin.util.magento.plugin.IsPluginAllowedForMethod;
+import org.jetbrains.annotations.NotNull;
+import com.magento.idea.magento2plugin.project.Settings;
+
+public class CreateAPluginAction extends DumbAwareAction {
+ public static String ACTION_NAME = "Create A Plugin...";
+ public static String ACTION_DESCRIPTION = "Create a new Magento 2 plugin for the class";
+ private final IsPluginAllowedForMethod isPluginAllowed;
+ private final GetFirstClassOfFile getFirstClassOfFile;
+ private Method targetMethod;
+ private PhpClass targetClass;
+
+ public CreateAPluginAction() {
+ super(ACTION_NAME, ACTION_DESCRIPTION, MagentoIcons.MODULE);
+ this.isPluginAllowed = IsPluginAllowedForMethod.getInstance();
+ this.getFirstClassOfFile = GetFirstClassOfFile.getInstance();
+ }
+
+ public void update(AnActionEvent event) {
+ targetClass = null;
+ targetMethod = null;
+ Project project = event.getData(PlatformDataKeys.PROJECT);
+ if (Settings.isEnabled(project)) {
+ Pair pair = this.findPhpClass(event);
+ PsiFile psiFile = pair.getFirst();
+ PhpClass phpClass = pair.getSecond();
+ targetClass = phpClass;
+ if (!(psiFile instanceof PhpFile) || phpClass.isFinal() || this.targetMethod == null) {
+ this.setStatus(event, false);
+ return;
+ }
+ } else {
+ this.setStatus(event, false);
+ return;
+ }
+ this.setStatus(event, true);
+ }
+
+ private void setStatus(AnActionEvent event, boolean status) {
+ event.getPresentation().setVisible(status);
+ event.getPresentation().setEnabled(status);
+ }
+
+ @Override
+ public void actionPerformed(@NotNull AnActionEvent e) {
+ CreateAPluginDialog.open(e.getProject(), this.targetMethod, this.targetClass);
+ }
+
+ @Override
+ public boolean isDumbAware() {
+ return false;
+ }
+
+ private Pair findPhpClass(@NotNull AnActionEvent event) {
+ PsiFile psiFile = event.getData(PlatformDataKeys.PSI_FILE);
+
+ PhpClass phpClass = null;
+ if (psiFile instanceof PhpFile) {
+ phpClass = getFirstClassOfFile.execute((PhpFile) psiFile);
+ fetchTargetMethod(event, psiFile, phpClass);
+ }
+
+ return Pair.create(psiFile, phpClass);
+ }
+
+ private void fetchTargetMethod(@NotNull AnActionEvent event, PsiFile psiFile, PhpClass phpClass) {
+ Caret caret = event.getData(PlatformDataKeys.CARET);
+ if (caret == null) {
+ return;
+ }
+ int offset = caret.getOffset();
+ PsiElement element = psiFile.findElementAt(offset);
+ if (element == null) {
+ return;
+ }
+ if (element instanceof Method && element.getParent() == phpClass && isPluginAllowed.check((Method)element)) {
+ this.targetMethod = (Method)element;
+ return;
+ }
+ PsiElement parent = element.getParent();
+ if (parent instanceof Method && parent.getParent() == phpClass && isPluginAllowed.check((Method)parent)) {
+ this.targetMethod = (Method)parent;
+ }
+ }
+}
diff --git a/src/com/magento/idea/magento2plugin/actions/generation/MagentoGenerateAroundMethodAction.java b/src/com/magento/idea/magento2plugin/actions/generation/PluginGenerateAfterMethodAction.java
similarity index 73%
rename from src/com/magento/idea/magento2plugin/actions/generation/MagentoGenerateAroundMethodAction.java
rename to src/com/magento/idea/magento2plugin/actions/generation/PluginGenerateAfterMethodAction.java
index 948a250a6..0e5288952 100644
--- a/src/com/magento/idea/magento2plugin/actions/generation/MagentoGenerateAroundMethodAction.java
+++ b/src/com/magento/idea/magento2plugin/actions/generation/PluginGenerateAfterMethodAction.java
@@ -14,15 +14,14 @@
import com.jetbrains.php.lang.psi.elements.PhpClass;
import com.magento.idea.magento2plugin.actions.generation.data.MagentoPluginMethodData;
import com.magento.idea.magento2plugin.actions.generation.generator.MagentoPluginMethodsGenerator;
+import com.magento.idea.magento2plugin.magento.files.Plugin;
import org.jetbrains.annotations.NotNull;
-public class MagentoGenerateAroundMethodAction extends CodeInsightAction {
- public static final String MAGENTO_PLUGIN_AROUND_METHOD_TEMPLATE_NAME = "Magento Plugin Around Method";
-
- private final MagentoGeneratePluginMethodHandlerBase myHandler = new MagentoGeneratePluginMethodHandlerBase(MagentoPluginMethodData.Type.AROUND) {
+public class PluginGenerateAfterMethodAction extends CodeInsightAction {
+ private final PluginGeneratePluginMethodHandlerBase myHandler = new PluginGeneratePluginMethodHandlerBase(Plugin.PluginType.after) {
protected MagentoPluginMethodData[] createPluginMethods(PhpClass currentClass, Method method, Key targetClassKey) {
return (new MagentoPluginMethodsGenerator(currentClass, method, targetClassKey)
- .createPluginMethods(MAGENTO_PLUGIN_AROUND_METHOD_TEMPLATE_NAME, MagentoPluginMethodData.Type.AROUND));
+ .createPluginMethods(Plugin.PluginType.after));
}
};
diff --git a/src/com/magento/idea/magento2plugin/actions/generation/MagentoGenerateAfterMethodAction.java b/src/com/magento/idea/magento2plugin/actions/generation/PluginGenerateAroundMethodAction.java
similarity index 74%
rename from src/com/magento/idea/magento2plugin/actions/generation/MagentoGenerateAfterMethodAction.java
rename to src/com/magento/idea/magento2plugin/actions/generation/PluginGenerateAroundMethodAction.java
index 335c42cff..52042c359 100644
--- a/src/com/magento/idea/magento2plugin/actions/generation/MagentoGenerateAfterMethodAction.java
+++ b/src/com/magento/idea/magento2plugin/actions/generation/PluginGenerateAroundMethodAction.java
@@ -14,15 +14,14 @@
import com.jetbrains.php.lang.psi.elements.PhpClass;
import com.magento.idea.magento2plugin.actions.generation.data.MagentoPluginMethodData;
import com.magento.idea.magento2plugin.actions.generation.generator.MagentoPluginMethodsGenerator;
+import com.magento.idea.magento2plugin.magento.files.Plugin;
import org.jetbrains.annotations.NotNull;
-public class MagentoGenerateAfterMethodAction extends CodeInsightAction {
- public static final String MAGENTO_PLUGIN_AFTER_METHOD_TEMPLATE_NAME = "Magento Plugin After Method";
-
- private final MagentoGeneratePluginMethodHandlerBase myHandler = new MagentoGeneratePluginMethodHandlerBase(MagentoPluginMethodData.Type.AFTER) {
+public class PluginGenerateAroundMethodAction extends CodeInsightAction {
+ private final PluginGeneratePluginMethodHandlerBase myHandler = new PluginGeneratePluginMethodHandlerBase(Plugin.PluginType.around) {
protected MagentoPluginMethodData[] createPluginMethods(PhpClass currentClass, Method method, Key targetClassKey) {
return (new MagentoPluginMethodsGenerator(currentClass, method, targetClassKey)
- .createPluginMethods(MAGENTO_PLUGIN_AFTER_METHOD_TEMPLATE_NAME, MagentoPluginMethodData.Type.AFTER));
+ .createPluginMethods(Plugin.PluginType.around));
}
};
diff --git a/src/com/magento/idea/magento2plugin/actions/generation/MagentoGenerateBeforeMethodAction.java b/src/com/magento/idea/magento2plugin/actions/generation/PluginGenerateBeforeMethodAction.java
similarity index 73%
rename from src/com/magento/idea/magento2plugin/actions/generation/MagentoGenerateBeforeMethodAction.java
rename to src/com/magento/idea/magento2plugin/actions/generation/PluginGenerateBeforeMethodAction.java
index 221e0ebca..e38faa8c4 100644
--- a/src/com/magento/idea/magento2plugin/actions/generation/MagentoGenerateBeforeMethodAction.java
+++ b/src/com/magento/idea/magento2plugin/actions/generation/PluginGenerateBeforeMethodAction.java
@@ -13,16 +13,15 @@
import com.jetbrains.php.lang.psi.elements.PhpClass;
import com.magento.idea.magento2plugin.actions.generation.data.MagentoPluginMethodData;
import com.magento.idea.magento2plugin.actions.generation.generator.MagentoPluginMethodsGenerator;
+import com.magento.idea.magento2plugin.magento.files.Plugin;
import org.jetbrains.annotations.NotNull;
import com.intellij.openapi.util.Key;
-public class MagentoGenerateBeforeMethodAction extends CodeInsightAction {
- public static final String MAGENTO_PLUGIN_BEFORE_METHOD_TEMPLATE_NAME = "Magento Plugin Before Method";
-
- private final MagentoGeneratePluginMethodHandlerBase myHandler = new MagentoGeneratePluginMethodHandlerBase(MagentoPluginMethodData.Type.BEFORE) {
+public class PluginGenerateBeforeMethodAction extends CodeInsightAction {
+ private final PluginGeneratePluginMethodHandlerBase myHandler = new PluginGeneratePluginMethodHandlerBase(Plugin.PluginType.before) {
protected MagentoPluginMethodData[] createPluginMethods(PhpClass currentClass, Method method, Key targetClassKey) {
return (new MagentoPluginMethodsGenerator(currentClass, method, targetClassKey)
- .createPluginMethods(MAGENTO_PLUGIN_BEFORE_METHOD_TEMPLATE_NAME, MagentoPluginMethodData.Type.BEFORE));
+ .createPluginMethods(Plugin.PluginType.before));
}
};
diff --git a/src/com/magento/idea/magento2plugin/actions/generation/MagentoGeneratePluginMethodHandlerBase.java b/src/com/magento/idea/magento2plugin/actions/generation/PluginGeneratePluginMethodHandlerBase.java
similarity index 67%
rename from src/com/magento/idea/magento2plugin/actions/generation/MagentoGeneratePluginMethodHandlerBase.java
rename to src/com/magento/idea/magento2plugin/actions/generation/PluginGeneratePluginMethodHandlerBase.java
index d3d37ace0..50fdbfba1 100644
--- a/src/com/magento/idea/magento2plugin/actions/generation/MagentoGeneratePluginMethodHandlerBase.java
+++ b/src/com/magento/idea/magento2plugin/actions/generation/PluginGeneratePluginMethodHandlerBase.java
@@ -4,7 +4,6 @@
*/
package com.magento.idea.magento2plugin.actions.generation;
-import com.intellij.application.options.CodeStyle;
import com.intellij.codeInsight.hint.HintManager;
import com.intellij.ide.util.MemberChooser;
import com.intellij.lang.LanguageCodeInsightActionHandler;
@@ -16,14 +15,10 @@
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.codeStyle.CodeStyleManager;
-import com.intellij.psi.codeStyle.CommonCodeStyleSettings;
import com.intellij.psi.tree.IElementType;
import com.intellij.util.containers.ContainerUtil;
import com.jetbrains.php.codeInsight.PhpCodeInsightUtil;
-import com.jetbrains.php.lang.PhpLangUtil;
-import com.jetbrains.php.lang.PhpLanguage;
import com.jetbrains.php.lang.actions.PhpNamedElementNode;
-import com.jetbrains.php.lang.documentation.phpdoc.psi.PhpDocComment;
import com.jetbrains.php.lang.lexer.PhpTokenTypes;
import com.jetbrains.php.lang.parser.PhpElementTypes;
import com.jetbrains.php.lang.parser.PhpStubElementTypes;
@@ -34,17 +29,27 @@
import java.util.*;
import com.magento.idea.magento2plugin.actions.generation.ImportReferences.PhpClassReferenceResolver;
import com.magento.idea.magento2plugin.actions.generation.data.MagentoPluginMethodData;
+import com.magento.idea.magento2plugin.actions.generation.generator.MagentoPluginMethodsGenerator;
+import com.magento.idea.magento2plugin.actions.generation.util.CodeStyleSettings;
+import com.magento.idea.magento2plugin.actions.generation.util.CollectInsertedMethods;
+import com.magento.idea.magento2plugin.actions.generation.util.FillTextBufferWithPluginMethods;
+import com.magento.idea.magento2plugin.magento.files.Plugin;
import com.magento.idea.magento2plugin.util.GetPhpClassByFQN;
import com.magento.idea.magento2plugin.util.magento.plugin.GetTargetClassNamesByPluginClassName;
+import com.magento.idea.magento2plugin.util.magento.plugin.IsPluginAllowedForMethod;
import gnu.trove.THashSet;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
-public abstract class MagentoGeneratePluginMethodHandlerBase implements LanguageCodeInsightActionHandler {
+public abstract class PluginGeneratePluginMethodHandlerBase implements LanguageCodeInsightActionHandler {
+ private CollectInsertedMethods collectInsertedMethods;
public String type;
+ public FillTextBufferWithPluginMethods fillTextBuffer;
- public MagentoGeneratePluginMethodHandlerBase(MagentoPluginMethodData.Type type) {
+ public PluginGeneratePluginMethodHandlerBase(Plugin.PluginType type) {
this.type = type.toString();
+ this.fillTextBuffer = FillTextBufferWithPluginMethods.getInstance();
+ this.collectInsertedMethods = CollectInsertedMethods.getInstance();
}
public boolean isValidFor(Editor editor, PsiFile file) {
@@ -61,14 +66,14 @@ public boolean isValidFor(Editor editor, PsiFile file) {
return !targetClassNames.isEmpty();
}
- public void invoke(@NotNull Project project, @NotNull Editor editor, @NotNull PsiFile file) {
- PhpFile phpFile = (PhpFile)file;
- PhpClass currentClass = PhpCodeEditUtil.findClassAtCaret(editor, phpFile);
- Key targetClassKey = Key.create("original.target");
- if (currentClass == null) {
+ public void invoke(@NotNull Project project, @NotNull Editor editor, @NotNull PsiFile pluginFile) {
+ PhpFile pluginPhpFile = (PhpFile)pluginFile;
+ PhpClass pluginClass = PhpCodeEditUtil.findClassAtCaret(editor, pluginPhpFile);
+ Key targetClassKey = Key.create(MagentoPluginMethodsGenerator.originalTargetKey);
+ if (pluginClass == null) {
return;
}
- PhpNamedElementNode[] fieldsToShow = this.targetMethods(currentClass, targetClassKey);
+ PhpNamedElementNode[] fieldsToShow = this.targetMethods(pluginClass, targetClassKey);
if (fieldsToShow.length == 0) {
if (ApplicationManager.getApplication().isHeadlessEnvironment()) {
return;
@@ -76,83 +81,43 @@ public void invoke(@NotNull Project project, @NotNull Editor editor, @NotNull Ps
HintManager.getInstance().showErrorHint(editor, this.getErrorMessage());
return;
}
- PhpNamedElementNode[] members = this.chooseMembers(fieldsToShow, true, file.getProject());
+ PhpNamedElementNode[] members = this.chooseMembers(fieldsToShow, true, pluginFile.getProject());
if (members == null || members.length == 0) {
return;
}
- int insertPos = getSuitableEditorPosition(editor, phpFile);
- CommonCodeStyleSettings settings = CodeStyle.getLanguageSettings(file, PhpLanguage.INSTANCE);
- boolean currLineBreaks = settings.KEEP_LINE_BREAKS;
- int currBlankLines = settings.KEEP_BLANK_LINES_IN_CODE;
- settings.KEEP_LINE_BREAKS = false;
- settings.KEEP_BLANK_LINES_IN_CODE = 0;
+ int insertPos = getSuitableEditorPosition(editor, pluginPhpFile);
+
+ CodeStyleSettings codeStyleSettings = new CodeStyleSettings(pluginPhpFile);
+ codeStyleSettings.adjustBeforeWrite();
ApplicationManager.getApplication().runWriteAction(() -> {
Set insertedMethodsNames = new THashSet();
PhpClassReferenceResolver resolver = new PhpClassReferenceResolver();
StringBuffer textBuf = new StringBuffer();
- PhpPsiElement scope = PhpCodeInsightUtil.findScopeForUseOperator(currentClass);
+ PhpPsiElement scope = PhpCodeInsightUtil.findScopeForUseOperator(pluginClass);
for (PhpNamedElementNode member : members) {
PsiElement method = member.getPsiElement();
- MagentoPluginMethodData[] pluginMethods = this.createPluginMethods(currentClass, (Method) method, targetClassKey);
- for (MagentoPluginMethodData pluginMethod : pluginMethods) {
- insertedMethodsNames.add(pluginMethod.getMethod().getName());
- PhpDocComment comment = pluginMethod.getDocComment();
- if (comment != null) {
- textBuf.append(comment.getText());
- }
- Method targetMethod = pluginMethod.getTargetMethod();
- Parameter[] parameters = targetMethod.getParameters();
- Collection processElements = new ArrayList<>(Arrays.asList(parameters));
- resolver.processElements(processElements);
- PsiElement targetClass = (PsiElement) pluginMethod.getTargetMethod().getUserData(targetClassKey);
- resolver.processElement(targetClass);
- PhpReturnType returnType = targetMethod.getReturnType();
- if (returnType != null) {
- resolver.processElement(returnType);
- }
-
- textBuf.append('\n');
- textBuf.append(pluginMethod.getMethod().getText());
- }
+ MagentoPluginMethodData[] pluginMethods = this.createPluginMethods(pluginClass, (Method) method, targetClassKey);
+ fillTextBuffer.execute(targetClassKey, insertedMethodsNames, resolver, textBuf, pluginMethods);
}
- if (textBuf.length() > 0 && insertPos >= 0) {
- editor.getDocument().insertString(insertPos, textBuf);
- int endPos = insertPos + textBuf.length();
- CodeStyleManager.getInstance(project).reformatText(phpFile, insertPos, endPos);
- PsiDocumentManager.getInstance(project).commitDocument(editor.getDocument());
- }
- if (!insertedMethodsNames.isEmpty()) {
- List insertedMethods = collectInsertedMethods(file, currentClass.getNameCS(), insertedMethodsNames);
- if (scope != null && insertedMethods != null) {
- resolver.importReferences(scope, insertedMethods);
- }
- }
+ insertPluginMethodsToFile(project, editor, pluginFile, pluginClass, insertPos, insertedMethodsNames, resolver, textBuf, scope);
});
- settings.KEEP_LINE_BREAKS = currLineBreaks;
- settings.KEEP_BLANK_LINES_IN_CODE = currBlankLines;
+ codeStyleSettings.restore();
}
- @Nullable
- private static List collectInsertedMethods(@NotNull PsiFile file, @NotNull CharSequence className, @NotNull Set methodNames) {
- if (!(file instanceof PhpFile)) {
- return null;
+ private void insertPluginMethodsToFile(@NotNull Project project, @NotNull Editor editor, @NotNull PsiFile pluginFile, PhpClass pluginClass, int insertPos, Set insertedMethodsNames, PhpClassReferenceResolver resolver, StringBuffer textBuf, PhpPsiElement scope) {
+ if (textBuf.length() > 0 && insertPos >= 0) {
+ editor.getDocument().insertString(insertPos, textBuf);
+ int endPos = insertPos + textBuf.length();
+ CodeStyleManager.getInstance(project).reformatText(pluginFile, insertPos, endPos);
+ PsiDocumentManager.getInstance(project).commitDocument(editor.getDocument());
}
- PhpClass phpClass = PhpPsiUtil.findClass((PhpFile) file, (aClass) -> PhpLangUtil.equalsClassNames(aClass.getNameCS(), className));
- if (phpClass == null) {
- return null;
- } else {
- List insertedMethods = new ArrayList();
- Method[] ownMethods = phpClass.getOwnMethods();
-
- for (Method method : ownMethods) {
- if (methodNames.contains(method.getNameCS())) {
- insertedMethods.add(method);
- }
+ if (!insertedMethodsNames.isEmpty()) {
+ List insertedMethods = collectInsertedMethods.execute(pluginFile, pluginClass.getNameCS(), insertedMethodsNames);
+ if (scope != null && insertedMethods != null) {
+ resolver.importReferences(scope, insertedMethods);
}
-
- return insertedMethods;
}
}
@@ -170,7 +135,7 @@ public boolean startInWriteAction() {
protected PhpNamedElementNode[] chooseMembers(PhpNamedElementNode[] members, boolean allowEmptySelection, Project project) {
PhpNamedElementNode[] nodes = fixOrderToBeAsOriginalFiles(members).toArray(new PhpNamedElementNode[members.length]);
if (!ApplicationManager.getApplication().isHeadlessEnvironment()) {
- MagentoGeneratePluginMethodHandlerBase.MyMemberChooser chooser = new MagentoGeneratePluginMethodHandlerBase.MyMemberChooser(nodes, allowEmptySelection, project);
+ PluginGeneratePluginMethodHandlerBase.MyMemberChooser chooser = new PluginGeneratePluginMethodHandlerBase.MyMemberChooser(nodes, allowEmptySelection, project);
chooser.setTitle("Choose Methods");
chooser.setCopyJavadocVisible(false);
chooser.show();
@@ -198,7 +163,7 @@ protected PhpNamedElementNode[] targetMethods(@NotNull PhpClass phpClass, Key currentMethods = currentClass.getMethods();
String methodName = method.getName();
- String methodPrefix = type.toLowerCase();
+ String methodPrefix = type;
String methodSuffix = methodName.substring(0, 1).toUpperCase() + methodName.substring(1);
String pluginMethodName = methodPrefix.concat(methodSuffix);
for (Method currentMethod: currentMethods) {
diff --git a/src/com/magento/idea/magento2plugin/actions/generation/data/MagentoPluginDiXmlData.java b/src/com/magento/idea/magento2plugin/actions/generation/data/MagentoPluginDiXmlData.java
new file mode 100644
index 000000000..e7a8318c4
--- /dev/null
+++ b/src/com/magento/idea/magento2plugin/actions/generation/data/MagentoPluginDiXmlData.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright © Magento, Inc. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+package com.magento.idea.magento2plugin.actions.generation.data;
+
+import com.jetbrains.php.lang.psi.elements.PhpClass;
+
+public class MagentoPluginDiXmlData {
+ private String area;
+ private String pluginModule;
+ private PhpClass targetClass;
+ private final String sortOrder;
+ private final String pluginName;
+ private String pluginFqn;
+
+ public MagentoPluginDiXmlData(
+ String area,
+ String pluginModule,
+ PhpClass targetClass,
+ String sortOrder,
+ String pluginName,
+ String pluginFqn
+ ) {
+ this.area = area;
+ this.pluginModule = pluginModule;
+ this.targetClass = targetClass;
+ this.sortOrder = sortOrder;
+ this.pluginName = pluginName;
+ this.pluginFqn = pluginFqn;
+ }
+
+ public String getArea() {
+ return area;
+ }
+
+ public String getPluginModule() {
+ return pluginModule;
+ }
+
+ public PhpClass getTargetClass() {
+ return targetClass;
+ }
+
+ public String getPluginName() {
+ return pluginName;
+ }
+
+ public String getSortOrder() {
+ return sortOrder;
+ }
+
+ public String getPluginFqn() {
+ return pluginFqn;
+ }
+}
diff --git a/src/com/magento/idea/magento2plugin/actions/generation/data/MagentoPluginFileData.java b/src/com/magento/idea/magento2plugin/actions/generation/data/MagentoPluginFileData.java
new file mode 100644
index 000000000..6efa9ac3b
--- /dev/null
+++ b/src/com/magento/idea/magento2plugin/actions/generation/data/MagentoPluginFileData.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright © Magento, Inc. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+package com.magento.idea.magento2plugin.actions.generation.data;
+
+import com.jetbrains.php.lang.psi.elements.Method;
+import com.jetbrains.php.lang.psi.elements.PhpClass;
+
+public class MagentoPluginFileData {
+ private String pluginDirectory;
+ private String pluginClassName;
+ private String pluginType;
+ private String pluginModule;
+ private PhpClass targetClass;
+ private Method targetMethod;
+ private String pluginFqn;
+ private String namespace;
+
+ public MagentoPluginFileData(
+ String pluginDirectory,
+ String pluginClassName,
+ String pluginType,
+ String pluginModule,
+ PhpClass targetClass,
+ Method targetMethod,
+ String pluginFqn,
+ String namespace
+ ) {
+ this.pluginDirectory = pluginDirectory;
+ this.pluginClassName = pluginClassName;
+ this.pluginType = pluginType;
+ this.pluginModule = pluginModule;
+ this.targetClass = targetClass;
+ this.targetMethod = targetMethod;
+ this.pluginFqn = pluginFqn;
+ this.namespace = namespace;
+ }
+
+ public String getPluginClassName() {
+ return pluginClassName;
+ }
+
+ public String getPluginDirectory() {
+ return pluginDirectory;
+ }
+
+ public String getPluginType() {
+ return pluginType;
+ }
+
+ public String getPluginModule() {
+ return pluginModule;
+ }
+
+ public PhpClass getTargetClass() {
+ return targetClass;
+ }
+
+ public Method getTargetMethod() {
+ return targetMethod;
+ }
+
+ public String getPluginFqn() {
+ return pluginFqn;
+ }
+
+ public String getNamespace() {
+ return namespace;
+ }
+}
diff --git a/src/com/magento/idea/magento2plugin/actions/generation/data/MagentoPluginMethodData.java b/src/com/magento/idea/magento2plugin/actions/generation/data/MagentoPluginMethodData.java
index 03af87f53..8e945b7f7 100644
--- a/src/com/magento/idea/magento2plugin/actions/generation/data/MagentoPluginMethodData.java
+++ b/src/com/magento/idea/magento2plugin/actions/generation/data/MagentoPluginMethodData.java
@@ -6,23 +6,17 @@
import com.jetbrains.php.lang.documentation.phpdoc.psi.PhpDocComment;
import com.jetbrains.php.lang.psi.elements.Method;
-import com.jetbrains.php.lang.psi.elements.PhpClass;
-import org.jetbrains.annotations.NotNull;
public class MagentoPluginMethodData {
- private final PhpClass pluginClass;
private final PhpDocComment docComment;
private final Method method;
private final Method targetMethod;
- private final MagentoPluginMethodData.Type pluginType;
- public MagentoPluginMethodData(Method targetMethod, PhpClass pluginClass, PhpDocComment docComment, Method method, @NotNull MagentoPluginMethodData.Type pluginType) {
+ public MagentoPluginMethodData(Method targetMethod, PhpDocComment docComment, Method method) {
super();
- this.pluginClass = pluginClass;
this.docComment = docComment;
this.method = method;
this.targetMethod = targetMethod;
- this.pluginType = pluginType;
}
public PhpDocComment getDocComment() {
@@ -33,24 +27,7 @@ public Method getMethod() {
return this.method;
}
- public PhpClass getPluginClass() {
- return this.pluginClass;
- }
-
public Method getTargetMethod() {
return this.targetMethod;
}
-
- public Type getPluginType() {
- return pluginType;
- }
-
- public static enum Type {
- AROUND,
- AFTER,
- BEFORE;
-
- private Type() {
- }
- }
}
diff --git a/src/com/magento/idea/magento2plugin/actions/generation/dialog/CreateAPluginDialog.form b/src/com/magento/idea/magento2plugin/actions/generation/dialog/CreateAPluginDialog.form
new file mode 100644
index 000000000..ea05d6de4
--- /dev/null
+++ b/src/com/magento/idea/magento2plugin/actions/generation/dialog/CreateAPluginDialog.form
@@ -0,0 +1,199 @@
+
+
diff --git a/src/com/magento/idea/magento2plugin/actions/generation/dialog/CreateAPluginDialog.java b/src/com/magento/idea/magento2plugin/actions/generation/dialog/CreateAPluginDialog.java
new file mode 100644
index 000000000..d21ed0f43
--- /dev/null
+++ b/src/com/magento/idea/magento2plugin/actions/generation/dialog/CreateAPluginDialog.java
@@ -0,0 +1,188 @@
+/*
+ * 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.jetbrains.php.lang.psi.elements.Method;
+import com.jetbrains.php.lang.psi.elements.PhpClass;
+import com.magento.idea.magento2plugin.actions.generation.data.MagentoPluginDiXmlData;
+import com.magento.idea.magento2plugin.actions.generation.data.MagentoPluginFileData;
+import com.magento.idea.magento2plugin.actions.generation.dialog.validator.CreateAPluginDialogValidator;
+import com.magento.idea.magento2plugin.actions.generation.generator.MagentoPluginClassGenerator;
+import com.magento.idea.magento2plugin.actions.generation.generator.MagentoPluginDiXmlGenerator;
+import com.magento.idea.magento2plugin.indexes.ModuleIndex;
+import com.magento.idea.magento2plugin.magento.files.Plugin;
+import com.magento.idea.magento2plugin.magento.packages.Package;
+import com.magento.idea.magento2plugin.ui.FilteredComboBox;
+import org.jetbrains.annotations.NotNull;
+import javax.swing.*;
+import java.awt.*;
+import java.awt.event.*;
+import java.io.File;
+import java.util.List;
+
+public class CreateAPluginDialog extends JDialog {
+ @NotNull
+ private final Project project;
+ private Method targetMethod;
+ private PhpClass targetClass;
+ @NotNull
+ private final CreateAPluginDialogValidator validator;
+ private JPanel contentPane;
+ private JButton buttonOK;
+ private JButton buttonCancel;
+ private JTextField pluginClassName;
+ private JLabel pluginClassNameLabel;
+ private JTextField pluginDirectory;
+ private JLabel pluginDirectoryName;
+ private JLabel selectPluginModule;
+ private JComboBox pluginType;
+ private JLabel pluginTypeLabel;
+ private FilteredComboBox pluginModule;
+ private JComboBox pluginArea;
+ private JLabel pluginAreaLabel;
+ private JTextField pluginName;
+ private JLabel pluginNameLabel;
+ private JTextField pluginSortOrder;
+ private JLabel pluginSortOrderLabel;
+
+ public CreateAPluginDialog(@NotNull Project project, Method targetMethod, PhpClass targetClass) {
+ this.project = project;
+ this.targetMethod = targetMethod;
+ this.targetClass = targetClass;
+ this.validator = CreateAPluginDialogValidator.getInstance(this);
+
+ setContentPane(contentPane);
+ setModal(true);
+ getRootPane().setDefaultButton(buttonOK);
+ pushToMiddle();
+ fillPluginTypeOptions();
+ fillTargetAreaOptions();
+
+ buttonOK.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ onOK();
+ }
+ });
+
+ buttonCancel.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ onCancel();
+ }
+ });
+
+ setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
+ addWindowListener(new WindowAdapter() {
+ public void windowClosing(WindowEvent e) {
+ onCancel();
+ }
+ });
+
+ contentPane.registerKeyboardAction(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ onCancel();
+ }
+ }, KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
+ }
+
+ private void fillPluginTypeOptions() {
+ for (Plugin.PluginType pluginPrefixType: Plugin.PluginType.values()) {
+ pluginType.addItem(pluginPrefixType.toString());
+ }
+ }
+
+ private void fillTargetAreaOptions() {
+ for(Package.Areas area: Package.Areas.values()) {
+ pluginArea.addItem(area.toString());
+ }
+ }
+
+ private void pushToMiddle() {
+ Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();
+ this.setLocation(dim.width / 2 -this.getSize().width / 2, dim.height / 2 - this.getSize().height / 2);
+ }
+
+ private void onOK() {
+ if (!validator.validate(project)) {
+ return;
+ }
+ new MagentoPluginClassGenerator(new MagentoPluginFileData(
+ getPluginDirectory(),
+ getPluginClassName(),
+ getPluginType(),
+ getPluginModule(),
+ targetClass,
+ targetMethod,
+ getPluginClassFqn(),
+ getNamespace()
+ ), project).generate();
+
+ new MagentoPluginDiXmlGenerator(new MagentoPluginDiXmlData(
+ getPluginArea(),
+ getPluginModule(),
+ targetClass,
+ getPluginSortOrder(),
+ getPluginName(),
+ getPluginClassFqn()
+ ), project).generate();
+
+ this.setVisible(false);
+ }
+
+ public String getPluginName() {
+ return this.pluginName.getText().trim();
+ }
+
+ public String getPluginSortOrder() {
+ return this.pluginSortOrder.getText().trim();
+ }
+
+ public String getPluginClassName() {
+ return this.pluginClassName.getText().trim();
+ }
+
+ public String getPluginDirectory() {
+ return this.pluginDirectory.getText().trim();
+ }
+
+ public String getPluginArea() {
+ return this.pluginArea.getSelectedItem().toString();
+ }
+
+ public String getPluginType() {
+ return this.pluginType.getSelectedItem().toString();
+ }
+
+ public String getPluginModule() {
+ return this.pluginModule.getSelectedItem().toString();
+ }
+
+ private void onCancel() {
+ this.setVisible(false);
+ }
+
+ public static void open(@NotNull Project project, Method targetMethod, PhpClass targetClass) {
+ CreateAPluginDialog dialog = new CreateAPluginDialog(project, targetMethod, targetClass);
+ dialog.pack();
+ dialog.setVisible(true);
+ }
+
+ private void createUIComponents() {
+ List allModulesList = ModuleIndex.getInstance(project).getEditableModuleNames();
+
+ this.pluginModule = new FilteredComboBox(allModulesList);
+ }
+
+ private String getNamespace() {
+ String targetModule = getPluginModule();
+ String namespace = targetModule.replace(Package.VENDOR_MODULE_NAME_SEPARATOR, Package.FQN_SEPARATOR);
+ namespace = namespace.concat(Package.FQN_SEPARATOR);
+ return namespace.concat(getPluginDirectory().replace(File.separator, Package.FQN_SEPARATOR));
+ }
+
+ private String getPluginClassFqn() {
+ return getNamespace().concat(Package.FQN_SEPARATOR).concat(getPluginClassName());
+ }
+}
diff --git a/src/com/magento/idea/magento2plugin/actions/generation/dialog/NewMagentoModuleDialog.java b/src/com/magento/idea/magento2plugin/actions/generation/dialog/NewMagentoModuleDialog.java
index fa3cdd74d..a27593fe0 100644
--- a/src/com/magento/idea/magento2plugin/actions/generation/dialog/NewMagentoModuleDialog.java
+++ b/src/com/magento/idea/magento2plugin/actions/generation/dialog/NewMagentoModuleDialog.java
@@ -11,13 +11,14 @@
import com.intellij.psi.PsiFile;
import com.magento.idea.magento2plugin.actions.generation.NewModuleAction;
import com.magento.idea.magento2plugin.actions.generation.dialog.validator.NewMagentoModuleDialogValidator;
-import com.magento.idea.magento2plugin.actions.generation.generator.DirectoryGenerator;
-import com.magento.idea.magento2plugin.actions.generation.generator.FileFromTemplateGenerator;
+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.data.ModuleDirectoriesData;
+import com.magento.idea.magento2plugin.actions.generation.util.NavigateToCreatedFile;
import com.magento.idea.magento2plugin.magento.files.ComposerJson;
import com.magento.idea.magento2plugin.magento.files.ModuleXml;
import com.magento.idea.magento2plugin.magento.files.RegistrationPhp;
-import com.magento.idea.magento2plugin.magento.packages.MagentoPackages;
+import com.magento.idea.magento2plugin.magento.packages.Package;
import com.magento.idea.magento2plugin.util.CamelCaseToHyphen;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -41,6 +42,7 @@ public class NewMagentoModuleDialog extends JDialog {
private final FileFromTemplateGenerator fileFromTemplateGenerator;
private final NewMagentoModuleDialogValidator validator;
private final CamelCaseToHyphen camelCaseToHyphen;
+ private final NavigateToCreatedFile navigateToCreatedFile;
private JPanel contentPane;
private JButton buttonOK;
private JButton buttonCancel;
@@ -64,6 +66,7 @@ public NewMagentoModuleDialog(@NotNull Project project, @NotNull PsiDirectory in
this.fileFromTemplateGenerator = FileFromTemplateGenerator.getInstance(project);
this.camelCaseToHyphen = CamelCaseToHyphen.getInstance();
this.validator = NewMagentoModuleDialogValidator.getInstance(this);
+ this.navigateToCreatedFile = NavigateToCreatedFile.getInstance();
detectPackageName(initialBaseDir);
setContentPane(contentPane);
setModal(true);
@@ -98,7 +101,7 @@ public void actionPerformed(ActionEvent e) {
private void detectPackageName(@NotNull PsiDirectory initialBaseDir) {
PsiDirectory parentDir = initialBaseDir.getParent();
- if (parentDir != null && parentDir.toString().endsWith(MagentoPackages.PACKAGES_ROOT)) {
+ if (parentDir != null && parentDir.toString().endsWith(Package.PACKAGES_ROOT)) {
packageName.setVisible(false);
packageNameLabel.setVisible(false);
this.detectedPackageName = initialBaseDir.getName();
@@ -130,7 +133,9 @@ private void generateFiles() {
if (registrationPhp == null) {
return;
}
- fileFromTemplateGenerator.generate(ModuleXml.getInstance(), attributes, moduleDirectoriesData.getModuleEtcDirectory(), NewModuleAction.ACTION_NAME);
+ PsiFile moduleXml = fileFromTemplateGenerator.generate(ModuleXml.getInstance(), attributes, moduleDirectoriesData.getModuleEtcDirectory(), NewModuleAction.ACTION_NAME);
+
+ navigateToCreatedFile.navigate(project, moduleXml);
}
public String getPackageName() {
diff --git a/src/com/magento/idea/magento2plugin/actions/generation/dialog/validator/CreateAPluginDialogValidator.java b/src/com/magento/idea/magento2plugin/actions/generation/dialog/validator/CreateAPluginDialogValidator.java
new file mode 100644
index 000000000..bc70a8cc3
--- /dev/null
+++ b/src/com/magento/idea/magento2plugin/actions/generation/dialog/validator/CreateAPluginDialogValidator.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright © Magento, Inc. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+package com.magento.idea.magento2plugin.actions.generation.dialog.validator;
+
+import com.intellij.openapi.project.Project;
+import com.magento.idea.magento2plugin.actions.generation.dialog.CreateAPluginDialog;
+import com.magento.idea.magento2plugin.indexes.ModuleIndex;
+import com.magento.idea.magento2plugin.util.Regex;
+import javax.swing.*;
+import java.util.List;
+
+public class CreateAPluginDialogValidator {
+ private static CreateAPluginDialogValidator INSTANCE = null;
+ private CreateAPluginDialog dialog;
+
+ public static CreateAPluginDialogValidator getInstance(CreateAPluginDialog dialog) {
+ if (null == INSTANCE) {
+ INSTANCE = new CreateAPluginDialogValidator();
+ }
+ INSTANCE.dialog = dialog;
+ return INSTANCE;
+ }
+
+ public boolean validate(Project project)
+ {
+ String errorTitle = "Error";
+ String pluginClassName = dialog.getPluginClassName();
+ if (pluginClassName.length() == 0) {
+ JOptionPane.showMessageDialog(null, "Plugin Class Name must not be empty.", errorTitle, JOptionPane.ERROR_MESSAGE);
+ return false;
+ }
+
+ if (!pluginClassName.matches(Regex.ALPHANUMERIC)) {
+ JOptionPane.showMessageDialog(null, "Plugin Class Name must contain letters and numbers only.", errorTitle, JOptionPane.ERROR_MESSAGE);
+ return false;
+ }
+
+ if (!Character.isUpperCase(pluginClassName.charAt(0)) && !Character.isDigit(pluginClassName.charAt(0))) {
+ JOptionPane.showMessageDialog(null, "Plugin Class Name must start from a number or a capital letter", errorTitle, JOptionPane.ERROR_MESSAGE);
+ return false;
+ }
+
+ String pluginDirectory = dialog.getPluginDirectory();
+ if (pluginDirectory.length() == 0) {
+ JOptionPane.showMessageDialog(null, "Plugin Directory must not be empty.", errorTitle, JOptionPane.ERROR_MESSAGE);
+ return false;
+ }
+
+ if (!pluginDirectory.matches(Regex.DIRECTORY)) {
+ JOptionPane.showMessageDialog(null, "Plugin Directory is not valid.", errorTitle, JOptionPane.ERROR_MESSAGE);
+ return false;
+ }
+
+ String pluginName = dialog.getPluginName();
+ if (pluginName.length() == 0) {
+ JOptionPane.showMessageDialog(null, "Plugin Name must not be empty.", errorTitle, JOptionPane.ERROR_MESSAGE);
+ return false;
+ }
+
+ if (!pluginName.matches(Regex.IDENTIFIER)) {
+ JOptionPane.showMessageDialog(null, "Plugin Name must contain letters, numbers, dashes, and underscores only.", errorTitle, JOptionPane.ERROR_MESSAGE);
+ return false;
+ }
+
+ String sortOrder = dialog.getPluginSortOrder();
+ if (sortOrder.length() == 0) {
+ JOptionPane.showMessageDialog(null, "Sort Order must not be empty.", errorTitle, JOptionPane.ERROR_MESSAGE);
+ return false;
+ }
+
+ if (!sortOrder.matches(Regex.NUMERIC)) {
+ JOptionPane.showMessageDialog(null, "Sort Order must contain numbers only.", errorTitle, JOptionPane.ERROR_MESSAGE);
+ return false;
+ }
+
+ String pluginModule = dialog.getPluginModule();
+ if (pluginModule.length() == 0) {
+ JOptionPane.showMessageDialog(null, "Plugin Module must not be empty.", errorTitle, JOptionPane.ERROR_MESSAGE);
+ return false;
+ }
+
+ List allModulesList = ModuleIndex.getInstance(project).getEditableModuleNames();
+ if (!allModulesList.contains(pluginModule)) {
+ JOptionPane.showMessageDialog(null, "No such module '".concat(pluginModule).concat("'."), errorTitle, JOptionPane.ERROR_MESSAGE);
+ return false;
+ }
+
+ return true;
+ }
+}
diff --git a/src/com/magento/idea/magento2plugin/actions/generation/generator/MagentoPluginClassGenerator.java b/src/com/magento/idea/magento2plugin/actions/generation/generator/MagentoPluginClassGenerator.java
new file mode 100644
index 000000000..b9bfed8c2
--- /dev/null
+++ b/src/com/magento/idea/magento2plugin/actions/generation/generator/MagentoPluginClassGenerator.java
@@ -0,0 +1,181 @@
+/*
+ * 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.openapi.util.Key;
+import com.intellij.psi.PsiDirectory;
+import com.intellij.psi.PsiDocumentManager;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiFile;
+import com.intellij.psi.codeStyle.CodeStyleManager;
+import com.intellij.psi.impl.source.tree.LeafPsiElement;
+import com.intellij.psi.util.PsiTreeUtil;
+import com.jetbrains.php.codeInsight.PhpCodeInsightUtil;
+import com.jetbrains.php.lang.psi.PhpFile;
+import com.jetbrains.php.lang.psi.elements.Method;
+import com.jetbrains.php.lang.psi.elements.PhpClass;
+import com.jetbrains.php.lang.psi.elements.PhpPsiElement;
+import com.magento.idea.magento2plugin.actions.generation.CreateAPluginAction;
+import com.magento.idea.magento2plugin.actions.generation.ImportReferences.PhpClassReferenceResolver;
+import com.magento.idea.magento2plugin.actions.generation.data.MagentoPluginFileData;
+import com.magento.idea.magento2plugin.actions.generation.data.MagentoPluginMethodData;
+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.util.CodeStyleSettings;
+import com.magento.idea.magento2plugin.actions.generation.util.CollectInsertedMethods;
+import com.magento.idea.magento2plugin.actions.generation.util.FillTextBufferWithPluginMethods;
+import com.magento.idea.magento2plugin.actions.generation.util.NavigateToCreatedFile;
+import com.magento.idea.magento2plugin.indexes.ModuleIndex;
+import com.magento.idea.magento2plugin.magento.files.Plugin;
+import com.magento.idea.magento2plugin.magento.packages.MagentoPhpClass;
+import com.magento.idea.magento2plugin.util.GetFirstClassOfFile;
+import com.magento.idea.magento2plugin.util.GetPhpClassByFQN;
+import gnu.trove.THashSet;
+import org.jetbrains.annotations.NotNull;
+import javax.swing.*;
+import java.io.File;
+import java.util.Collection;
+import java.util.List;
+import java.util.Properties;
+import java.util.Set;
+
+public class MagentoPluginClassGenerator {
+ private final NavigateToCreatedFile navigateToCreatedFile;
+ private MagentoPluginFileData pluginFileData;
+ private Project project;
+ private final FillTextBufferWithPluginMethods fillTextBuffer;
+ private final CollectInsertedMethods collectInsertedMethods;
+ private final DirectoryGenerator directoryGenerator;
+ private final FileFromTemplateGenerator fileFromTemplateGenerator;
+ private final GetFirstClassOfFile getFirstClassOfFile;
+
+ public MagentoPluginClassGenerator(@NotNull MagentoPluginFileData pluginFileData, Project project) {
+ this.directoryGenerator = DirectoryGenerator.getInstance();
+ this.fileFromTemplateGenerator = FileFromTemplateGenerator.getInstance(project);
+ this.getFirstClassOfFile = GetFirstClassOfFile.getInstance();
+ this.fillTextBuffer = FillTextBufferWithPluginMethods.getInstance();
+ this.collectInsertedMethods = CollectInsertedMethods.getInstance();
+ this.pluginFileData = pluginFileData;
+ this.project = project;
+ this.navigateToCreatedFile = NavigateToCreatedFile.getInstance();
+ }
+
+ public void generate()
+ {
+ WriteCommandAction.runWriteCommandAction(project, () -> {
+ PhpClass pluginClass = GetPhpClassByFQN.getInstance(project).execute(pluginFileData.getPluginFqn());
+ if (pluginClass == null) {
+ pluginClass = createPluginClass();
+ }
+ if (pluginClass == null) {
+ JOptionPane.showMessageDialog(null, "Plugin Class cant be created!", "Error", JOptionPane.ERROR_MESSAGE);
+ return;
+ }
+
+ Key targetClassKey = Key.create(MagentoPluginMethodsGenerator.originalTargetKey);
+ Method targetMethod = pluginFileData.getTargetMethod();
+ targetMethod.putUserData(targetClassKey, pluginFileData.getTargetClass());
+ MagentoPluginMethodsGenerator pluginGenerator = new MagentoPluginMethodsGenerator(pluginClass, targetMethod, targetClassKey);
+
+ MagentoPluginMethodData[] pluginMethodData = pluginGenerator.createPluginMethods(getPluginType());
+ if (checkIfMethodExist(pluginClass, pluginMethodData)){
+ JOptionPane.showMessageDialog(null, "Plugin method already exist!", "Error", JOptionPane.ERROR_MESSAGE);
+ return;
+ }
+
+ Set insertedMethodsNames = new THashSet();
+ PhpClassReferenceResolver resolver = new PhpClassReferenceResolver();
+ StringBuffer textBuf = new StringBuffer();
+
+ fillTextBuffer.execute(targetClassKey, insertedMethodsNames, resolver, textBuf, pluginMethodData);
+
+ PsiFile pluginFile = pluginClass.getContainingFile();
+ CodeStyleSettings codeStyleSettings = new CodeStyleSettings((PhpFile) pluginFile);
+ codeStyleSettings.adjustBeforeWrite();
+
+ int insertPos = getInsertPos(pluginClass);
+ PhpPsiElement scope = PhpCodeInsightUtil.findScopeForUseOperator(pluginClass);
+
+ if (textBuf.length() > 0 && insertPos >= 0) {
+ PsiDocumentManager psiDocumentManager = PsiDocumentManager.getInstance(project);
+ Document document = psiDocumentManager.getDocument(pluginFile);
+ document.insertString(insertPos, textBuf);
+ int endPos = insertPos + textBuf.length() + 1;
+ CodeStyleManager.getInstance(project).reformatText(pluginFile, insertPos, endPos);
+ psiDocumentManager.commitDocument(document);
+ }
+ if (!insertedMethodsNames.isEmpty()) {
+ List insertedMethods = collectInsertedMethods.execute(pluginFile, pluginClass.getNameCS(), insertedMethodsNames);
+ if (scope != null && insertedMethods != null) {
+ resolver.importReferences(scope, insertedMethods);
+ }
+ }
+ codeStyleSettings.restore();
+ navigateToCreatedFile.navigate(project, pluginFile);
+ });
+ }
+
+ private boolean checkIfMethodExist(PhpClass pluginClass, MagentoPluginMethodData[] pluginMethodData) {
+ Collection currentPluginMethods = pluginClass.getMethods();
+ for (Method currentPluginMethod: currentPluginMethods) {
+ for (MagentoPluginMethodData pluginMethod: pluginMethodData) {
+ if (pluginMethod.getMethod().getName().equals(currentPluginMethod.getName())){
+ continue;
+ }
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private PhpClass createPluginClass() {
+ PsiDirectory parentDirectory = ModuleIndex.getInstance(project).getModuleDirectoryByModuleName(getPluginModule());
+ String[] pluginDirectories = pluginFileData.getPluginDirectory().split(File.separator);
+ for (String pluginDirectory: pluginDirectories) {
+ parentDirectory = directoryGenerator.findOrCreateSubdirectory(parentDirectory, pluginDirectory);
+ }
+
+ Properties attributes = getAttributes();
+ PsiFile pluginFile = fileFromTemplateGenerator.generate(Plugin.getInstance(pluginFileData.getPluginClassName()), attributes, parentDirectory, CreateAPluginAction.ACTION_NAME);
+ if (pluginFile == null) {
+ return null;
+ }
+ return getFirstClassOfFile.execute((PhpFile) pluginFile);
+ }
+
+ private Properties getAttributes() {
+ Properties attributes = new Properties();
+ this.fillAttributes(attributes);
+ return attributes;
+ }
+
+ private void fillAttributes(Properties attributes) {
+ attributes.setProperty("NAME", pluginFileData.getPluginClassName());
+ attributes.setProperty("NAMESPACE", pluginFileData.getNamespace());
+ }
+
+ public Plugin.PluginType getPluginType() {
+ return Plugin.getPluginTypeByString(pluginFileData.getPluginType());
+ }
+
+ public String getPluginModule() {
+ return pluginFileData.getPluginModule();
+ }
+
+ private int getInsertPos(PhpClass pluginClass) {
+ int insertPos = -1;
+ LeafPsiElement[] leafElements = PsiTreeUtil.getChildrenOfType(pluginClass, LeafPsiElement.class);
+ for (LeafPsiElement leafPsiElement: leafElements) {
+ if (!leafPsiElement.getText().equals(MagentoPhpClass.CLOSING_TAG)) {
+ continue;
+ }
+ insertPos = leafPsiElement.getTextOffset();
+ }
+ return insertPos;
+ }
+}
diff --git a/src/com/magento/idea/magento2plugin/actions/generation/generator/MagentoPluginDiXmlGenerator.java b/src/com/magento/idea/magento2plugin/actions/generation/generator/MagentoPluginDiXmlGenerator.java
new file mode 100644
index 000000000..8bf4a817d
--- /dev/null
+++ b/src/com/magento/idea/magento2plugin/actions/generation/generator/MagentoPluginDiXmlGenerator.java
@@ -0,0 +1,183 @@
+/*
+ * 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.PsiElement;
+import com.intellij.psi.PsiFile;
+import com.intellij.psi.codeStyle.CodeStyleManager;
+import com.intellij.psi.util.PsiTreeUtil;
+import com.intellij.psi.xml.*;
+import com.intellij.xml.util.XmlUtil;
+import com.jetbrains.php.lang.PhpLangUtil;
+import com.magento.idea.magento2plugin.actions.generation.CreateAPluginAction;
+import com.magento.idea.magento2plugin.actions.generation.data.MagentoPluginDiXmlData;
+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.GetCodeTemplate;
+import com.magento.idea.magento2plugin.indexes.ModuleIndex;
+import com.magento.idea.magento2plugin.magento.files.ModuleDiXml;
+import com.magento.idea.magento2plugin.magento.packages.Package;
+import com.magento.idea.magento2plugin.util.magento.FileBasedIndexUtil;
+import com.magento.idea.magento2plugin.xml.XmlPsiTreeUtil;
+import org.jetbrains.annotations.NotNull;
+import java.io.IOException;
+import java.util.*;
+
+public class MagentoPluginDiXmlGenerator {
+ private final FileFromTemplateGenerator fileFromTemplateGenerator;
+ private final DirectoryGenerator directoryGenerator;
+ private final GetCodeTemplate getCodeTemplate;
+ private MagentoPluginDiXmlData pluginFileData;
+ private Project project;
+
+ public MagentoPluginDiXmlGenerator(@NotNull MagentoPluginDiXmlData pluginFileData, Project project) {
+ this.pluginFileData = pluginFileData;
+ this.project = project;
+ this.fileFromTemplateGenerator = FileFromTemplateGenerator.getInstance(project);
+ this.directoryGenerator = DirectoryGenerator.getInstance();
+ this.getCodeTemplate = GetCodeTemplate.getInstance(project);
+ }
+
+ public void generate()
+ {
+ PsiFile diXmlFile = findOrCreateDiXml();
+ XmlAttributeValue typeAttributeValue = getTypeAttributeValue((XmlFile) diXmlFile);
+ boolean isPluginDeclared = false;
+ boolean isTypeDeclared = false;
+ if (typeAttributeValue != null) {
+ isTypeDeclared = true;
+ isPluginDeclared = isPluginDeclared(typeAttributeValue);
+ }
+ if (isPluginDeclared) {
+ return;
+ }
+ boolean finalIsTypeDeclared = isTypeDeclared;
+ WriteCommandAction.runWriteCommandAction(project, () -> {
+ StringBuffer textBuf = new StringBuffer();
+ try {
+ textBuf.append(getCodeTemplate.execute(ModuleDiXml.TEMPLATE_PLUGIN, getAttributes(finalIsTypeDeclared)));
+ } catch (IOException e) {
+ e.printStackTrace();
+ return;
+ }
+
+ int insertPos = finalIsTypeDeclared
+ ? getEndPositionOfTag(PsiTreeUtil.getParentOfType(typeAttributeValue, XmlTag.class))
+ : getRootInsertPosition((XmlFile) diXmlFile);
+ if (textBuf.length() > 0 && insertPos >= 0) {
+ PsiDocumentManager psiDocumentManager = PsiDocumentManager.getInstance(project);
+ Document document = psiDocumentManager.getDocument(diXmlFile);
+ document.insertString(insertPos, textBuf);
+ int endPos = insertPos + textBuf.length() + 1;
+ CodeStyleManager.getInstance(project).reformatText(diXmlFile, insertPos, endPos);
+ psiDocumentManager.commitDocument(document);
+ }
+ });
+ }
+
+ private boolean isPluginDeclared(XmlAttributeValue typeAttributeValue) {
+ XmlTag xmlTag = PsiTreeUtil.getParentOfType(typeAttributeValue, XmlTag.class);
+ XmlTag[] xmlTags = PsiTreeUtil.getChildrenOfType(xmlTag, XmlTag.class);
+ if (xmlTags == null) {
+ return false;
+ }
+ for (XmlTag child: xmlTags) {
+ if (!child.getName().equals(ModuleDiXml.PLUGIN_TAG_NAME)) {
+ continue;
+ }
+ XmlAttribute[] xmlAttributes = PsiTreeUtil.getChildrenOfType(child, XmlAttribute.class);
+ for (XmlAttribute xmlAttribute: xmlAttributes) {
+ if (!xmlAttribute.getName().equals(ModuleDiXml.PLUGIN_TYPE_ATTRIBUTE)) {
+ continue;
+ }
+ String declaredClass = PhpLangUtil.toPresentableFQN(xmlAttribute.getValue());
+ if (declaredClass.equals(pluginFileData.getPluginFqn())) {
+ return true;
+ }
+ }
+ }
+
+ return false;
+ }
+
+ private XmlAttributeValue getTypeAttributeValue(XmlFile diXml) {
+ Collection pluginTypes = XmlPsiTreeUtil.findAttributeValueElements(diXml, ModuleDiXml.PLUGIN_TYPE_TAG, ModuleDiXml.PLUGIN_TYPE_ATTR_NAME);
+ String pluginClassFqn = pluginFileData.getTargetClass().getPresentableFQN();
+ for (XmlAttributeValue pluginType: pluginTypes) {
+ if (!PhpLangUtil.toPresentableFQN(pluginType.getValue()).equals(pluginClassFqn)) {
+ continue;
+ }
+ return pluginType;
+ }
+
+ return null;
+ }
+
+ private Properties getAttributes(boolean isTypeDeclared) {
+ Properties attributes = new Properties();
+ this.fillAttributes(attributes, isTypeDeclared);
+ return attributes;
+ }
+
+ private void fillAttributes(Properties attributes, boolean isTypeDeclared) {
+ if (!isTypeDeclared) {
+ attributes.setProperty("TYPE", pluginFileData.getTargetClass().getPresentableFQN());
+ }
+ attributes.setProperty("NAME", pluginFileData.getPluginName());
+ attributes.setProperty("PLUGIN_TYPE", pluginFileData.getPluginFqn());
+ attributes.setProperty("PLUGIN_NAME", pluginFileData.getPluginName());
+ attributes.setProperty("SORT_ORDER", pluginFileData.getSortOrder());
+ }
+
+ private PsiFile findOrCreateDiXml() {
+ PsiDirectory parentDirectory = ModuleIndex.getInstance(project).getModuleDirectoryByModuleName(pluginFileData.getPluginModule());
+ ArrayList pluginDirectories = new ArrayList<>();
+ pluginDirectories.add(Package.MODULE_BASE_AREA_DIR);
+ if (!getArea().equals(Package.Areas.base)) {
+ pluginDirectories.add(getArea().toString());
+ }
+ for (String pluginDirectory: pluginDirectories) {
+ parentDirectory = directoryGenerator.findOrCreateSubdirectory(parentDirectory, pluginDirectory);
+ }
+ ModuleDiXml moduleDiXml = new ModuleDiXml();
+ PsiFile diXml = FileBasedIndexUtil.findModuleConfigFile(
+ moduleDiXml.getFileName(),
+ getArea(),
+ pluginFileData.getPluginModule(),
+ project
+ );
+ if (diXml == null) {
+ diXml = fileFromTemplateGenerator.generate(moduleDiXml, new Properties(), parentDirectory, CreateAPluginAction.ACTION_NAME);
+ }
+ return diXml;
+ }
+
+ public Package.Areas getArea() {
+ return Package.getAreaByString(pluginFileData.getArea());
+ }
+
+ private int getRootInsertPosition(XmlFile xmlFile) {
+ int insertPos = -1;
+ XmlTag rootTag = xmlFile.getRootTag();
+ if (rootTag == null) {
+ return insertPos;
+ }
+ return getEndPositionOfTag(rootTag);
+ }
+
+ private int getEndPositionOfTag(XmlTag tag) {
+ PsiElement tagEnd = XmlUtil.getTokenOfType(tag, XmlTokenType.XML_END_TAG_START);
+ if (tagEnd == null) {
+ return -1;
+ }
+
+ return tagEnd.getTextOffset();
+ }
+}
diff --git a/src/com/magento/idea/magento2plugin/actions/generation/generator/MagentoPluginMethodsGenerator.java b/src/com/magento/idea/magento2plugin/actions/generation/generator/MagentoPluginMethodsGenerator.java
index f42ef7fb4..fd9e79b45 100644
--- a/src/com/magento/idea/magento2plugin/actions/generation/generator/MagentoPluginMethodsGenerator.java
+++ b/src/com/magento/idea/magento2plugin/actions/generation/generator/MagentoPluginMethodsGenerator.java
@@ -16,33 +16,36 @@
import com.jetbrains.php.lang.psi.elements.*;
import com.jetbrains.php.lang.psi.resolve.types.PhpType;
import com.magento.idea.magento2plugin.actions.generation.data.MagentoPluginMethodData;
+import com.magento.idea.magento2plugin.magento.files.Plugin;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.*;
import java.util.regex.Pattern;
public class MagentoPluginMethodsGenerator {
+ public static String originalTargetKey = "original.target";
@NotNull
- private final PhpClass myCurrentClass;
+ private final PhpClass pluginClass;
@NotNull
private final Method myMethod;
@NotNull
private final PhpClass myTargetClass;
- public MagentoPluginMethodsGenerator(@NotNull PhpClass myCurrentClass, @NotNull Method method, Key targetClassKey) {
+ public MagentoPluginMethodsGenerator(@NotNull PhpClass pluginClass, @NotNull Method method, Key targetClassKey) {
super();
- this.myCurrentClass = myCurrentClass;
+ this.pluginClass = pluginClass;
this.myMethod = method;
this.myTargetClass = (PhpClass)Objects.requireNonNull(method.getUserData(targetClassKey));
}
@NotNull
- public MagentoPluginMethodData[] createPluginMethods(@NotNull String templateName, @NotNull MagentoPluginMethodData.Type type) {
+ public MagentoPluginMethodData[] createPluginMethods(@NotNull Plugin.PluginType type) {
List pluginMethods = new ArrayList();
- PhpClass currentClass = this.myCurrentClass;
+ String templateName = Plugin.getMethodTemplateByPluginType(type);
+ PhpClass currentClass = this.pluginClass;
if (currentClass != null) {
- Properties attributes = this.getAccessMethodAttributes(PhpCodeInsightUtil.findScopeForUseOperator(this.myMethod), templateName, type);
- String methodTemplate = PhpCodeUtil.getCodeTemplate(templateName, attributes, this.myCurrentClass.getProject());
+ Properties attributes = this.getAccessMethodAttributes(PhpCodeInsightUtil.findScopeForUseOperator(this.myMethod), type);
+ String methodTemplate = PhpCodeUtil.getCodeTemplate(templateName, attributes, this.pluginClass.getProject());
PhpClass dummyClass = PhpCodeUtil.createClassFromMethodTemplate(currentClass, currentClass.getProject(), methodTemplate);
if (dummyClass != null) {
PhpDocComment currDocComment = null;
@@ -51,31 +54,28 @@ public MagentoPluginMethodData[] createPluginMethods(@NotNull String templateNam
if (child instanceof PhpDocComment) {
currDocComment = (PhpDocComment)child;
} else if (child instanceof Method) {
- pluginMethods.add(new MagentoPluginMethodData(myMethod, currentClass, currDocComment, (Method)child, type));
+ pluginMethods.add(new MagentoPluginMethodData(myMethod, currDocComment, (Method)child));
currDocComment = null;
}
}
}
}
- MagentoPluginMethodData[] magentoPluginMethodData = pluginMethods.toArray(new MagentoPluginMethodData[0]);
-
- return magentoPluginMethodData;
+ return pluginMethods.toArray(new MagentoPluginMethodData[0]);
}
- private Properties getAccessMethodAttributes(@Nullable PhpPsiElement scopeForUseOperator, String templateName, @NotNull MagentoPluginMethodData.Type type) {
+ private Properties getAccessMethodAttributes(@Nullable PhpPsiElement scopeForUseOperator, @NotNull Plugin.PluginType type) {
Properties attributes = new Properties();
- String typeHint = this.fillAttributes(scopeForUseOperator, attributes, templateName, type);
+ String typeHint = this.fillAttributes(scopeForUseOperator, attributes, type);
this.addTypeHintsAndReturnType(attributes, typeHint);
return attributes;
}
@NotNull
- private String fillAttributes(@Nullable PhpPsiElement scopeForUseOperator, Properties attributes, String templateName, @NotNull MagentoPluginMethodData.Type type) {
+ private String fillAttributes(@Nullable PhpPsiElement scopeForUseOperator, Properties attributes, @NotNull Plugin.PluginType type) {
String fieldName = this.myMethod.getName();
- String methodPrefix = type.toString().toLowerCase();
String methodSuffix = fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);
- String pluginMethodName = methodPrefix.concat(methodSuffix);
+ String pluginMethodName = type.toString().concat(methodSuffix);
attributes.setProperty("NAME", pluginMethodName);
PhpReturnType targetMethodReturnType = myMethod.getReturnType();
@@ -97,7 +97,7 @@ private String fillAttributes(@Nullable PhpPsiElement scopeForUseOperator, Prope
}
private void addTypeHintsAndReturnType(Properties attributes, String typeHint) {
- Project project = this.myCurrentClass.getProject();
+ Project project = this.pluginClass.getProject();
if (PhpLanguageFeature.SCALAR_TYPE_HINTS.isSupported(project) && isDocTypeConvertable(typeHint)) {
attributes.setProperty("SCALAR_TYPE_HINT", convertDocTypeToHint(project, typeHint));
}
@@ -138,7 +138,7 @@ private static String convertDocTypeToHint(Project project, String typeHint) {
return hint;
}
- private String getParameterDoc(Collection parameters, @NotNull MagentoPluginMethodData.Type type, Project project) {
+ private String getParameterDoc(Collection parameters, @NotNull Plugin.PluginType type, Project project) {
StringBuilder sb = new StringBuilder();
PhpReturnType returnType = myMethod.getReturnType();
@@ -163,10 +163,10 @@ private String getParameterDoc(Collection parameters, @NotNull Magen
}
sb.append('$').append(paramName);
- if (type.equals(MagentoPluginMethodData.Type.AROUND) && i == 0) {
+ if (type.equals(Plugin.PluginType.around) && i == 0) {
sb.append("\n* @param callable $proceed");
}
- if (type.equals(MagentoPluginMethodData.Type.AFTER) && i == 0) {
+ if (type.equals(Plugin.PluginType.after) && i == 0) {
if (returnType != null) {
if (returnType.getText().equals("void")) {
sb.append("\n* @param null $result");
@@ -179,7 +179,7 @@ private String getParameterDoc(Collection parameters, @NotNull Magen
}
}
- if (!type.equals(MagentoPluginMethodData.Type.BEFORE) && returnType != null) {
+ if (!type.equals(Plugin.PluginType.before) && returnType != null) {
if (returnType.getText().equals("void")) {
sb.append("\n* @return void");
} else {
@@ -189,7 +189,7 @@ private String getParameterDoc(Collection parameters, @NotNull Magen
return sb.toString();
}
- protected String getParameterList(Collection parameters, @NotNull MagentoPluginMethodData.Type type) {
+ protected String getParameterList(Collection parameters, @NotNull Plugin.PluginType type) {
StringBuilder buf = new StringBuilder();
PhpReturnType returnType = myMethod.getReturnType();
Iterator iterator = parameters.iterator();
@@ -215,14 +215,14 @@ protected String getParameterList(Collection parameters, @NotNull Ma
}
buf.append("$").append(paramName);
}
- if (type.equals(MagentoPluginMethodData.Type.AFTER) && i == 0){
+ if (type.equals(Plugin.PluginType.after) && i == 0){
if (returnType != null && !returnType.getText().equals("void")) {
buf.append(", ").append(returnType.getText()).append(" $result");
} else {
buf.append(", $result");
}
}
- if (type.equals(MagentoPluginMethodData.Type.AROUND) && i == 0){
+ if (type.equals(Plugin.PluginType.around) && i == 0){
buf.append(", callable $proceed");
}
i++;
@@ -231,9 +231,9 @@ protected String getParameterList(Collection parameters, @NotNull Ma
return buf.toString();
}
- protected String getReturnVariables(@NotNull MagentoPluginMethodData.Type type) {
+ protected String getReturnVariables(@NotNull Plugin.PluginType type) {
StringBuilder buf = new StringBuilder();
- if (type.equals(MagentoPluginMethodData.Type.AFTER)) {
+ if (type.equals(Plugin.PluginType.after)) {
return buf.append("$result").toString();
}
Parameter[] parameters = myMethod.getParameters();
@@ -258,7 +258,7 @@ protected String getReturnVariables(@NotNull MagentoPluginMethodData.Type type)
@Nullable
private String getTypeHint(@NotNull PhpNamedElement element) {
- PhpType filedType = element.getType().global(this.myCurrentClass.getProject());
+ PhpType filedType = element.getType().global(this.pluginClass.getProject());
Set typeStrings = filedType.getTypes();
String typeString = null;
if (typeStrings.size() == 1) {
@@ -294,7 +294,7 @@ private String convertTypeToString(@NotNull PhpNamedElement element, Set
}
private String getFieldTypeString(PhpNamedElement element, @NotNull PhpType type) {
- return PhpDocUtil.getTypePresentation(this.myCurrentClass.getProject(), type, PhpCodeInsightUtil.findScopeForUseOperator(element));
+ return PhpDocUtil.getTypePresentation(this.pluginClass.getProject(), type, PhpCodeInsightUtil.findScopeForUseOperator(element));
}
private static PhpType filterNullCaseInsensitive(PhpType filedType) {
diff --git a/src/com/magento/idea/magento2plugin/actions/generation/generator/DirectoryGenerator.java b/src/com/magento/idea/magento2plugin/actions/generation/generator/util/DirectoryGenerator.java
similarity index 99%
rename from src/com/magento/idea/magento2plugin/actions/generation/generator/DirectoryGenerator.java
rename to src/com/magento/idea/magento2plugin/actions/generation/generator/util/DirectoryGenerator.java
index a2037adaa..ba26a3023 100644
--- a/src/com/magento/idea/magento2plugin/actions/generation/generator/DirectoryGenerator.java
+++ b/src/com/magento/idea/magento2plugin/actions/generation/generator/util/DirectoryGenerator.java
@@ -2,7 +2,7 @@
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
-package com.magento.idea.magento2plugin.actions.generation.generator;
+package com.magento.idea.magento2plugin.actions.generation.generator.util;
import com.intellij.openapi.application.WriteAction;
import com.intellij.psi.PsiDirectory;
diff --git a/src/com/magento/idea/magento2plugin/actions/generation/generator/FileFromTemplateGenerator.java b/src/com/magento/idea/magento2plugin/actions/generation/generator/util/FileFromTemplateGenerator.java
similarity index 95%
rename from src/com/magento/idea/magento2plugin/actions/generation/generator/FileFromTemplateGenerator.java
rename to src/com/magento/idea/magento2plugin/actions/generation/generator/util/FileFromTemplateGenerator.java
index 83d270524..80bdd87d0 100644
--- a/src/com/magento/idea/magento2plugin/actions/generation/generator/FileFromTemplateGenerator.java
+++ b/src/com/magento/idea/magento2plugin/actions/generation/generator/util/FileFromTemplateGenerator.java
@@ -2,7 +2,7 @@
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
-package com.magento.idea.magento2plugin.actions.generation.generator;
+package com.magento.idea.magento2plugin.actions.generation.generator.util;
import com.intellij.ide.fileTemplates.DefaultTemplatePropertiesProvider;
import com.intellij.ide.fileTemplates.FileTemplate;
@@ -56,7 +56,6 @@ public PsiFile generate(@NotNull ModuleFileInterface moduleFile, @NotNull Proper
} catch (IncorrectOperationException | IOException var9) {
exceptionRef.set(var9.getMessage());
}
-
};
ApplicationManager.getApplication().runWriteAction(run);
}, actionName, null);
@@ -72,7 +71,7 @@ public PsiFile generate(@NotNull ModuleFileInterface moduleFile, @NotNull Proper
private PsiFile createFile(@NotNull ModuleFileInterface moduleFile, @NotNull String filePath, @NotNull PsiDirectory baseDir, @NotNull Properties attributes) throws IOException, IncorrectOperationException {
List path = StringUtil.split(filePath.replace(File.separator, "/"), "/");
String fileName = path.get(path.size() - 1);
- PsiFile fileTemplate = createFileFromTemplate(getTestTemplateManager(), baseDir, moduleFile.getTemplate(), attributes, fileName, moduleFile.getLanguage());
+ PsiFile fileTemplate = createFileFromTemplate(getTemplateManager(), baseDir, moduleFile.getTemplate(), attributes, fileName, moduleFile.getLanguage());
if (fileTemplate == null) {
throw new IncorrectOperationException("Template not found!");
} else {
@@ -116,7 +115,7 @@ public void fillDefaultProperties(@NotNull FileTemplateManager templateManager,
}
}
- public FileTemplateManager getTestTemplateManager() {
+ public FileTemplateManager getTemplateManager() {
return FileTemplateManager.getInstance(project);
}
}
diff --git a/src/com/magento/idea/magento2plugin/actions/generation/generator/util/GetCodeTemplate.java b/src/com/magento/idea/magento2plugin/actions/generation/generator/util/GetCodeTemplate.java
new file mode 100644
index 000000000..0553e8649
--- /dev/null
+++ b/src/com/magento/idea/magento2plugin/actions/generation/generator/util/GetCodeTemplate.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright © Magento, Inc. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+package com.magento.idea.magento2plugin.actions.generation.generator.util;
+
+import com.intellij.ide.fileTemplates.FileTemplate;
+import com.intellij.ide.fileTemplates.FileTemplateManager;
+import com.intellij.openapi.project.Project;
+import java.io.IOException;
+import java.util.Properties;
+
+public class GetCodeTemplate {
+ private static GetCodeTemplate INSTANCE = null;
+ private Project project;
+
+ public static GetCodeTemplate getInstance(Project project) {
+ if (null == INSTANCE) {
+ INSTANCE = new GetCodeTemplate(project);
+ }
+
+ return INSTANCE;
+ }
+ GetCodeTemplate (Project project) {
+ this.project = project;
+ }
+
+ public String execute(String templateName, Properties properties) throws IOException {
+ FileTemplate fileTemplate = FileTemplateManager.getInstance(project).getCodeTemplate(templateName);
+ return fileTemplate.getText(properties);
+ }
+}
diff --git a/src/com/magento/idea/magento2plugin/actions/generation/util/CodeStyleSettings.java b/src/com/magento/idea/magento2plugin/actions/generation/util/CodeStyleSettings.java
new file mode 100644
index 000000000..d9a517f4e
--- /dev/null
+++ b/src/com/magento/idea/magento2plugin/actions/generation/util/CodeStyleSettings.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright © Magento, Inc. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+package com.magento.idea.magento2plugin.actions.generation.util;
+
+import com.intellij.application.options.CodeStyle;
+import com.intellij.psi.codeStyle.CommonCodeStyleSettings;
+import com.jetbrains.php.lang.PhpLanguage;
+import com.jetbrains.php.lang.psi.PhpFile;
+
+public class CodeStyleSettings {
+ private PhpFile phpFile;
+ private boolean currLineBreaks;
+ private int currBlankLines;
+ private CommonCodeStyleSettings settings;
+
+ public CodeStyleSettings(PhpFile phpFile){
+ this.phpFile = phpFile;
+ this.settings = CodeStyle.getLanguageSettings(this.phpFile, PhpLanguage.INSTANCE);
+ }
+
+ public void adjustBeforeWrite() {
+ this.currLineBreaks = settings.KEEP_LINE_BREAKS;
+ this.currBlankLines = settings.KEEP_BLANK_LINES_IN_CODE;
+ settings.KEEP_LINE_BREAKS = false;
+ settings.KEEP_BLANK_LINES_IN_CODE = 0;
+ };
+
+ public void restore() {
+ settings.KEEP_LINE_BREAKS = currLineBreaks;
+ settings.KEEP_BLANK_LINES_IN_CODE = currBlankLines;
+ }
+}
diff --git a/src/com/magento/idea/magento2plugin/actions/generation/util/CollectInsertedMethods.java b/src/com/magento/idea/magento2plugin/actions/generation/util/CollectInsertedMethods.java
new file mode 100644
index 000000000..566549a29
--- /dev/null
+++ b/src/com/magento/idea/magento2plugin/actions/generation/util/CollectInsertedMethods.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright © Magento, Inc. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+package com.magento.idea.magento2plugin.actions.generation.util;
+
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiFile;
+import com.jetbrains.php.lang.PhpLangUtil;
+import com.jetbrains.php.lang.psi.PhpFile;
+import com.jetbrains.php.lang.psi.PhpPsiUtil;
+import com.jetbrains.php.lang.psi.elements.Method;
+import com.jetbrains.php.lang.psi.elements.PhpClass;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+
+public class CollectInsertedMethods {
+ private static CollectInsertedMethods INSTANCE = null;
+
+ public static CollectInsertedMethods getInstance() {
+ if (null == INSTANCE) {
+ INSTANCE = new CollectInsertedMethods();
+ }
+ return INSTANCE;
+ }
+
+ @Nullable
+ public List execute(@NotNull PsiFile file, @NotNull CharSequence className, @NotNull Set methodNames) {
+ if (!(file instanceof PhpFile)) {
+ return null;
+ }
+ PhpClass phpClass = PhpPsiUtil.findClass((PhpFile) file, (aClass) -> PhpLangUtil.equalsClassNames(aClass.getNameCS(), className));
+ if (phpClass == null) {
+ return null;
+ } else {
+ List insertedMethods = new ArrayList();
+ Method[] ownMethods = phpClass.getOwnMethods();
+
+ for (Method method : ownMethods) {
+ if (methodNames.contains(method.getNameCS())) {
+ insertedMethods.add(method);
+ }
+ }
+
+ return insertedMethods;
+ }
+ }
+}
diff --git a/src/com/magento/idea/magento2plugin/actions/generation/util/FillTextBufferWithPluginMethods.java b/src/com/magento/idea/magento2plugin/actions/generation/util/FillTextBufferWithPluginMethods.java
new file mode 100644
index 000000000..ff01d11a4
--- /dev/null
+++ b/src/com/magento/idea/magento2plugin/actions/generation/util/FillTextBufferWithPluginMethods.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright © Magento, Inc. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+package com.magento.idea.magento2plugin.actions.generation.util;
+
+import com.intellij.openapi.util.Key;
+import com.intellij.psi.PsiElement;
+import com.jetbrains.php.lang.documentation.phpdoc.psi.PhpDocComment;
+import com.jetbrains.php.lang.psi.elements.Method;
+import com.jetbrains.php.lang.psi.elements.Parameter;
+import com.jetbrains.php.lang.psi.elements.PhpReturnType;
+import com.magento.idea.magento2plugin.actions.generation.ImportReferences.PhpClassReferenceResolver;
+import com.magento.idea.magento2plugin.actions.generation.data.MagentoPluginMethodData;
+import org.jetbrains.annotations.NotNull;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Set;
+
+public class FillTextBufferWithPluginMethods {
+ private static FillTextBufferWithPluginMethods INSTANCE = null;
+
+ public static FillTextBufferWithPluginMethods getInstance() {
+ if (null == INSTANCE) {
+ INSTANCE = new FillTextBufferWithPluginMethods();
+ }
+ return INSTANCE;
+ }
+
+ public void execute(@NotNull Key targetClassKey, Set insertedMethodsNames, @NotNull PhpClassReferenceResolver resolver, @NotNull StringBuffer textBuf, @NotNull MagentoPluginMethodData[] pluginMethods) {
+ for (MagentoPluginMethodData pluginMethod : pluginMethods) {
+ insertedMethodsNames.add(pluginMethod.getMethod().getName());
+ PhpDocComment comment = pluginMethod.getDocComment();
+ if (comment != null) {
+ textBuf.append(comment.getText());
+ }
+ Method targetMethod = pluginMethod.getTargetMethod();
+ Parameter[] parameters = targetMethod.getParameters();
+ Collection processElements = new ArrayList<>(Arrays.asList(parameters));
+ resolver.processElements(processElements);
+ PsiElement targetClass = (PsiElement) pluginMethod.getTargetMethod().getUserData(targetClassKey);
+ resolver.processElement(targetClass);
+ PhpReturnType returnType = targetMethod.getReturnType();
+ if (returnType != null) {
+ resolver.processElement(returnType);
+ }
+
+ textBuf.append('\n');
+ textBuf.append(pluginMethod.getMethod().getText());
+ }
+ }
+}
diff --git a/src/com/magento/idea/magento2plugin/actions/generation/util/NavigateToCreatedFile.java b/src/com/magento/idea/magento2plugin/actions/generation/util/NavigateToCreatedFile.java
new file mode 100644
index 000000000..f90a8c421
--- /dev/null
+++ b/src/com/magento/idea/magento2plugin/actions/generation/util/NavigateToCreatedFile.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright © Magento, Inc. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+package com.magento.idea.magento2plugin.actions.generation.util;
+
+import com.intellij.ide.util.PsiNavigationSupport;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.psi.PsiFile;
+import org.jetbrains.annotations.NotNull;
+
+public class NavigateToCreatedFile {
+ private static NavigateToCreatedFile INSTANCE = null;
+
+ public static NavigateToCreatedFile getInstance() {
+ if (null == INSTANCE) {
+ INSTANCE = new NavigateToCreatedFile();
+ }
+ return INSTANCE;
+ }
+
+ public void navigate(@NotNull Project project, @NotNull PsiFile createdFile) {
+ VirtualFile virtualFile = createdFile.getVirtualFile();
+ if (virtualFile == null) {
+ return;
+ }
+ PsiNavigationSupport.getInstance().createNavigatable(project, virtualFile, -1).navigate(false);
+ }
+}
diff --git a/src/com/magento/idea/magento2plugin/indexes/ModuleIndex.java b/src/com/magento/idea/magento2plugin/indexes/ModuleIndex.java
new file mode 100644
index 000000000..b82ea7031
--- /dev/null
+++ b/src/com/magento/idea/magento2plugin/indexes/ModuleIndex.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright © Magento, Inc. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+package com.magento.idea.magento2plugin.indexes;
+
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.psi.PsiDirectory;
+import com.intellij.psi.PsiManager;
+import com.intellij.psi.search.GlobalSearchScope;
+import com.intellij.util.indexing.FileBasedIndex;
+import com.jetbrains.php.lang.PhpFileType;
+import com.magento.idea.magento2plugin.magento.packages.Package;
+import com.magento.idea.magento2plugin.stubs.indexes.ModuleNameIndex;
+import com.magento.idea.magento2plugin.util.RegExUtil;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+public class ModuleIndex {
+
+ private static ModuleIndex INSTANCE;
+
+ private Project project;
+
+ private ModuleIndex() {
+ }
+
+ public static ModuleIndex getInstance(final Project project) {
+ if (null == INSTANCE) {
+ INSTANCE = new ModuleIndex();
+ }
+ INSTANCE.project = project;
+
+ return INSTANCE;
+ }
+
+ public List getEditableModuleNames() {
+ FileBasedIndex index = FileBasedIndex
+ .getInstance();
+ List allModulesList = new ArrayList<>();
+ Collection allModules = index.getAllKeys(ModuleNameIndex.KEY, project);
+ for (String moduleName : allModules) {
+ if (!moduleName.matches(RegExUtil.Magento.MODULE_NAME)) {
+ continue;
+ }
+ Collection files = index.getContainingFiles(ModuleNameIndex.KEY, moduleName, GlobalSearchScope.getScopeRestrictedByFileTypes(
+ GlobalSearchScope.allScope(project),
+ PhpFileType.INSTANCE
+ ));
+ if (files.isEmpty()) {
+ continue;
+ }
+ VirtualFile virtualFile = files.iterator().next();
+ if (virtualFile.getPath().contains(Package.VENDOR)) {
+ continue;
+ }
+
+ allModulesList.add(moduleName);
+ }
+ Collections.sort(allModulesList);
+ return allModulesList;
+ }
+
+ public PsiDirectory getModuleDirectoryByModuleName(String moduleName) {
+ FileBasedIndex index = FileBasedIndex
+ .getInstance();
+ Collection files = index.getContainingFiles(ModuleNameIndex.KEY, moduleName, GlobalSearchScope.getScopeRestrictedByFileTypes(
+ GlobalSearchScope.allScope(project),
+ PhpFileType.INSTANCE
+ ));
+ VirtualFile virtualFile = files.iterator().next();
+ return PsiManager.getInstance(project).findDirectory(virtualFile.getParent());
+ }
+}
diff --git a/src/com/magento/idea/magento2plugin/inspections/php/PluginInspection.java b/src/com/magento/idea/magento2plugin/inspections/php/PluginInspection.java
index 4c2789b73..183eced1b 100644
--- a/src/com/magento/idea/magento2plugin/inspections/php/PluginInspection.java
+++ b/src/com/magento/idea/magento2plugin/inspections/php/PluginInspection.java
@@ -19,6 +19,7 @@
import com.jetbrains.php.lang.psi.elements.PhpClass;
import com.jetbrains.php.lang.psi.visitors.PhpElementVisitor;
import com.magento.idea.magento2plugin.inspections.php.util.PhpClassImplementsInterfaceUtil;
+import com.magento.idea.magento2plugin.magento.files.Plugin;
import com.magento.idea.magento2plugin.util.GetPhpClassByFQN;
import com.magento.idea.magento2plugin.util.magento.plugin.GetTargetClassNamesByPluginClassName;
import org.jetbrains.annotations.NotNull;
@@ -37,22 +38,19 @@ public PsiElementVisitor buildVisitor(@NotNull ProblemsHolder problemsHolder, bo
private static final String pluginOnConstructorMethodProblemDescription = "You can't declare a plugin for a __construct method!";
private static final String redundantParameterProblemDescription = "Redundant parameter";
private static final String possibleTypeIncompatibilityProblemDescription = "Possible type incompatibility. Consider changing the parameter according to the target method.";
- private static final String aroundPluginPrefix = "around";
- private static final String beforePluginPrefix = "before";
- private static final String afterPluginPrefix = "after";
private final Integer beforePluginExtraParamsStart = 2;
private final Integer afterAndAroundPluginExtraParamsStart = 3;
private String getPluginPrefix(Method pluginMethod) {
String pluginMethodName = pluginMethod.getName();
- if (pluginMethodName.startsWith(aroundPluginPrefix)) {
- return aroundPluginPrefix;
+ if (pluginMethodName.startsWith(Plugin.PluginType.around.toString())) {
+ return Plugin.PluginType.around.toString();
}
- if (pluginMethodName.startsWith(beforePluginPrefix)) {
- return beforePluginPrefix;
+ if (pluginMethodName.startsWith(Plugin.PluginType.before.toString())) {
+ return Plugin.PluginType.before.toString();
}
- if (pluginMethodName.startsWith(afterPluginPrefix)) {
- return afterPluginPrefix;
+ if (pluginMethodName.startsWith(Plugin.PluginType.after.toString())) {
+ return Plugin.PluginType.after.toString();
}
return null;
@@ -106,7 +104,7 @@ private void checkTargetClass(PsiElement currentClassNameIdentifier, PhpClass ta
}
private void checkTargetMethod(Method pluginMethod, String targetClassMethodName, Method targetMethod) {
- if (targetClassMethodName.equals("__construct")) {
+ if (targetClassMethodName.equals(Plugin.constructMethodName)) {
problemsHolder.registerProblem(pluginMethod.getNameIdentifier(), pluginOnConstructorMethodProblemDescription, ProblemHighlightType.ERROR);
}
if (targetMethod.isFinal()) {
@@ -115,7 +113,7 @@ private void checkTargetMethod(Method pluginMethod, String targetClassMethodName
if (targetMethod.isStatic()) {
problemsHolder.registerProblem(pluginMethod.getNameIdentifier(), pluginOnStaticMethodProblemDescription, ProblemHighlightType.ERROR);
}
- if (!targetMethod.getAccess().toString().equals("public")) {
+ if (!targetMethod.getAccess().toString().equals(Plugin.publicAccess)) {
problemsHolder.registerProblem(pluginMethod.getNameIdentifier(), pluginOnNotPublicMethodProblemDescription, ProblemHighlightType.ERROR);
}
}
@@ -139,13 +137,13 @@ private void checkParametersCompatibility(Method pluginMethod, String pluginPref
}
continue;
}
- if (index == 2 && pluginPrefix.equals(aroundPluginPrefix)) {
+ if (index == 2 && pluginPrefix.equals(Plugin.PluginType.around.toString())) {
if (!checkTypeIncompatibility("callable", declaredType, phpIndex)) {
problemsHolder.registerProblem(pluginMethodParameter, PhpBundle.message("inspection.wrong_param_type", new Object[]{declaredType, "callable"}), ProblemHighlightType.ERROR);
}
continue;
}
- if (index == 2 && pluginPrefix.equals(afterPluginPrefix) &&
+ if (index == 2 && pluginPrefix.equals(Plugin.PluginType.after.toString()) &&
!targetMethod.getDeclaredType().toString().equals("void")) {
if (declaredType.isEmpty() || targetMethod.getDeclaredType().toString().isEmpty()) {
continue;
@@ -158,7 +156,7 @@ private void checkParametersCompatibility(Method pluginMethod, String pluginPref
}
continue;
}
- if (index == 2 && pluginPrefix.equals(afterPluginPrefix) &&
+ if (index == 2 && pluginPrefix.equals(Plugin.PluginType.after.toString()) &&
targetMethod.getDeclaredType().toString().equals("void")) {
if (declaredType.isEmpty()) {
continue;
@@ -168,7 +166,7 @@ private void checkParametersCompatibility(Method pluginMethod, String pluginPref
}
continue;
}
- int targetParameterKey = index - (pluginPrefix.equals(beforePluginPrefix) ?
+ int targetParameterKey = index - (pluginPrefix.equals(Plugin.PluginType.before.toString()) ?
beforePluginExtraParamsStart :
afterAndAroundPluginExtraParamsStart);
if (targetMethodParameters.length <= targetParameterKey) {
diff --git a/src/com/magento/idea/magento2plugin/inspections/xml/ObserverDeclarationInspection.java b/src/com/magento/idea/magento2plugin/inspections/xml/ObserverDeclarationInspection.java
index a29b8727a..e953ff85d 100644
--- a/src/com/magento/idea/magento2plugin/inspections/xml/ObserverDeclarationInspection.java
+++ b/src/com/magento/idea/magento2plugin/inspections/xml/ObserverDeclarationInspection.java
@@ -19,7 +19,7 @@
import com.jetbrains.php.lang.inspections.PhpInspection;
import com.magento.idea.magento2plugin.indexes.EventIndex;
import com.magento.idea.magento2plugin.magento.files.ModuleXml;
-import com.magento.idea.magento2plugin.magento.packages.MagentoPackages;
+import com.magento.idea.magento2plugin.magento.packages.Package;
import org.jetbrains.annotations.NotNull;
import java.net.MalformedURLException;
import java.net.URL;
@@ -254,22 +254,13 @@ private String getAreaFromFileDirectory(@NotNull PsiFile file) {
String areaFromFileDirectory = file.getParent().getName();
- if (areaFromFileDirectory.equals("etc")) {
- return MagentoPackages.AREA_BASE;
+ if (areaFromFileDirectory.equals(Package.MODULE_BASE_AREA_DIR)) {
+ return Package.Areas.base.toString();
}
- List possibleAreas = new ArrayList<>(Arrays.asList(
- MagentoPackages.AREA_ADMINHTML,
- MagentoPackages.AREA_FRONTEND,
- MagentoPackages.AREA_CRON,
- MagentoPackages.AREA_API_REST,
- MagentoPackages.AREA_API_SOAP,
- MagentoPackages.AREA_GRAPHQL
- ));
-
- for (String area: possibleAreas) {
- if (area.equals(areaFromFileDirectory)) {
- return area;
+ for (Package.Areas area: Package.Areas.values()) {
+ if (area.toString().equals(areaFromFileDirectory)) {
+ return area.toString();
}
}
diff --git a/src/com/magento/idea/magento2plugin/magento/files/ModuleDiXml.java b/src/com/magento/idea/magento2plugin/magento/files/ModuleDiXml.java
new file mode 100644
index 000000000..973993809
--- /dev/null
+++ b/src/com/magento/idea/magento2plugin/magento/files/ModuleDiXml.java
@@ -0,0 +1,41 @@
+/*
+ * 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 ModuleDiXml implements ModuleFileInterface {
+ public static String FILE_NAME = "di.xml";
+ public static String TEMPLATE = "Magento Module DI Xml";
+ public static String TEMPLATE_PLUGIN = "Magento Module DI Xml Plugin";
+ public static String PLUGIN_TYPE_TAG = "type";
+ public static String PLUGIN_TYPE_ATTRIBUTE = "type";
+ public static String PLUGIN_TAG_NAME = "plugin";
+ public static String PLUGIN_TYPE_ATTR_NAME = "name";
+ private static ModuleDiXml INSTANCE = null;
+
+ public static ModuleDiXml getInstance() {
+ if (null == INSTANCE) {
+ INSTANCE = new ModuleDiXml();
+ }
+ return INSTANCE;
+ }
+
+ @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/Plugin.java b/src/com/magento/idea/magento2plugin/magento/files/Plugin.java
new file mode 100644
index 000000000..61f0ff468
--- /dev/null
+++ b/src/com/magento/idea/magento2plugin/magento/files/Plugin.java
@@ -0,0 +1,83 @@
+/*
+ * 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.jetbrains.php.lang.PhpLanguage;
+
+public class Plugin implements ModuleFileInterface {
+ public static String TEMPLATE = "PHP Class";
+ public static final String BEFORE_METHOD_TEMPLATE_NAME = "Magento Plugin Before Method";
+ public static final String AROUND_METHOD_TEMPLATE_NAME = "Magento Plugin Around Method";
+ public static final String AFTER_METHOD_TEMPLATE_NAME = "Magento Plugin After Method";
+
+ public static enum PluginType {
+ before,
+ after,
+ around
+ }
+
+ //forbidden target method
+ public static final String constructMethodName = "__construct";
+
+ //allowed methods access type
+ public static final String publicAccess = "public";
+
+ private static Plugin INSTANCE = null;
+ private String fileName;
+
+ public static Plugin getInstance(String className) {
+ if (null == INSTANCE) {
+ INSTANCE = new Plugin();
+ }
+ INSTANCE.setFileName(className.concat(".php"));
+ return INSTANCE;
+ }
+
+ @Override
+ public String getFileName() {
+ return this.fileName;
+ }
+
+ @Override
+ public String getTemplate() {
+ return TEMPLATE;
+ }
+
+ @Override
+ public Language getLanguage() {
+ return PhpLanguage.INSTANCE;
+ }
+
+ private void setFileName(String filename) {
+ this.fileName = filename;
+ };
+
+ public static String getMethodTemplateByPluginType(PluginType pluginType)
+ {
+ if (pluginType.equals(PluginType.after)) {
+ return AFTER_METHOD_TEMPLATE_NAME;
+ }
+ if (pluginType.equals(PluginType.before)) {
+ return BEFORE_METHOD_TEMPLATE_NAME;
+ }
+ if (pluginType.equals(PluginType.around)) {
+ return AROUND_METHOD_TEMPLATE_NAME;
+ }
+ return null;
+ }
+
+ public static Plugin.PluginType getPluginTypeByString(String string)
+ {
+ for (Plugin.PluginType pluginType: Plugin.PluginType.values()) {
+ if (!pluginType.toString().equals(string))
+ {
+ continue;
+ }
+ return pluginType;
+ }
+ return null;
+ }
+}
diff --git a/src/com/magento/idea/magento2plugin/magento/packages/MagentoPackages.java b/src/com/magento/idea/magento2plugin/magento/packages/MagentoPackages.java
deleted file mode 100644
index 9a09eeb3b..000000000
--- a/src/com/magento/idea/magento2plugin/magento/packages/MagentoPackages.java
+++ /dev/null
@@ -1,16 +0,0 @@
-/*
- * Copyright © Magento, Inc. All rights reserved.
- * See COPYING.txt for license details.
- */
-package com.magento.idea.magento2plugin.magento.packages;
-
-public class MagentoPackages {
- public static String PACKAGES_ROOT = "app/code";
- public static String AREA_BASE = "base";
- public static String AREA_ADMINHTML = "adminhtml";
- public static String AREA_FRONTEND = "frontend";
- public static String AREA_CRON = "crontab";
- public static String AREA_API_REST = "webapi_rest";
- public static String AREA_API_SOAP = "webapi_soap";
- public static String AREA_GRAPHQL = "graphql";
-}
diff --git a/src/com/magento/idea/magento2plugin/magento/packages/MagentoPhpClass.java b/src/com/magento/idea/magento2plugin/magento/packages/MagentoPhpClass.java
new file mode 100644
index 000000000..bf588533a
--- /dev/null
+++ b/src/com/magento/idea/magento2plugin/magento/packages/MagentoPhpClass.java
@@ -0,0 +1,9 @@
+/*
+ * Copyright © Magento, Inc. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+package com.magento.idea.magento2plugin.magento.packages;
+
+public class MagentoPhpClass {
+ public static String CLOSING_TAG = "}";
+}
diff --git a/src/com/magento/idea/magento2plugin/magento/packages/Package.java b/src/com/magento/idea/magento2plugin/magento/packages/Package.java
new file mode 100644
index 000000000..ac37b3fd4
--- /dev/null
+++ b/src/com/magento/idea/magento2plugin/magento/packages/Package.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright © Magento, Inc. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+package com.magento.idea.magento2plugin.magento.packages;
+
+import com.magento.idea.magento2plugin.magento.files.Plugin;
+
+public class Package {
+ public static String PACKAGES_ROOT = "app/code";
+ public static String VENDOR = "vendor";
+ public static String MODULE_BASE_AREA_DIR = "etc";
+ public static String VENDOR_MODULE_NAME_SEPARATOR = "_";
+ public static String FQN_SEPARATOR = "\\";
+
+ public static enum Areas {
+ base,
+ adminhtml,
+ frontend,
+ crontab,
+ webapi_rest,
+ webapi_soap,
+ graphql
+ }
+
+ public static Package.Areas getAreaByString(String string)
+ {
+ for (Package.Areas areas: Package.Areas.values()) {
+ if (!areas.toString().equals(string))
+ {
+ continue;
+ }
+ return areas;
+ }
+ return null;
+ }
+}
diff --git a/src/com/magento/idea/magento2plugin/ui/FilteredComboBox.java b/src/com/magento/idea/magento2plugin/ui/FilteredComboBox.java
new file mode 100644
index 000000000..347711e54
--- /dev/null
+++ b/src/com/magento/idea/magento2plugin/ui/FilteredComboBox.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright © Magento, Inc. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+package com.magento.idea.magento2plugin.ui;
+
+import java.awt.event.KeyAdapter;
+import java.awt.event.KeyEvent;
+import java.util.ArrayList;
+import java.util.List;
+import javax.swing.DefaultComboBoxModel;
+import javax.swing.JComboBox;
+import javax.swing.JTextField;
+import javax.swing.SwingUtilities;
+
+public class FilteredComboBox extends JComboBox {
+ private List entries;
+
+ public List getEntries() {
+ return entries;
+ }
+
+ public FilteredComboBox(List entries) {
+ super(entries.toArray());
+ this.entries = entries;
+ this.setEditable(true);
+
+ final JTextField textfield =
+ (JTextField) this.getEditor().getEditorComponent();
+
+ textfield.addKeyListener(new KeyAdapter() {
+ public void keyReleased(KeyEvent ke) {
+ SwingUtilities.invokeLater(new Runnable() {
+ public void run() {
+ comboFilter(textfield.getText());
+ }
+ });
+ }
+ });
+
+ }
+
+ public void comboFilter(String enteredText) {
+ List entriesFiltered = new ArrayList();
+
+ for (String entry : getEntries()) {
+ if (entry.toLowerCase().contains(enteredText.toLowerCase())) {
+ entriesFiltered.add(entry);
+ }
+ }
+
+ if (entriesFiltered.size() > 0) {
+ this.setModel(
+ new DefaultComboBoxModel(
+ entriesFiltered.toArray()));
+ this.setSelectedItem(enteredText);
+ this.showPopup();
+ } else {
+ this.hidePopup();
+ }
+ }
+}
diff --git a/src/com/magento/idea/magento2plugin/util/GetFirstClassOfFile.java b/src/com/magento/idea/magento2plugin/util/GetFirstClassOfFile.java
new file mode 100644
index 000000000..1d308b9c5
--- /dev/null
+++ b/src/com/magento/idea/magento2plugin/util/GetFirstClassOfFile.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright © Magento, Inc. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+package com.magento.idea.magento2plugin.util;
+
+import com.intellij.psi.util.PsiTreeUtil;
+import com.jetbrains.php.lang.psi.PhpFile;
+import com.jetbrains.php.lang.psi.elements.PhpClass;
+import org.jetbrains.annotations.Nullable;
+import java.util.Collection;
+
+public class GetFirstClassOfFile {
+ private static GetFirstClassOfFile INSTANCE = null;
+
+ public static GetFirstClassOfFile getInstance() {
+ if (null == INSTANCE) {
+ INSTANCE = new GetFirstClassOfFile();
+ }
+ return INSTANCE;
+ }
+
+ @Nullable
+ public PhpClass execute(PhpFile phpFile) {
+ Collection phpClasses = PsiTreeUtil.collectElementsOfType(phpFile, PhpClass.class);
+ return phpClasses.size() == 0 ? null : phpClasses.iterator().next();
+ }
+}
diff --git a/src/com/magento/idea/magento2plugin/util/Regex.java b/src/com/magento/idea/magento2plugin/util/Regex.java
index 5fe10d817..7566edf46 100644
--- a/src/com/magento/idea/magento2plugin/util/Regex.java
+++ b/src/com/magento/idea/magento2plugin/util/Regex.java
@@ -1,5 +1,5 @@
-/**
- * Copyright © Dmytro Kvashnin. All rights reserved.
+/*
+ * Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
package com.magento.idea.magento2plugin.util;
@@ -8,4 +8,13 @@ public class Regex {
public static final String ALPHANUMERIC
= "[a-zA-Z0-9]*";
+
+ public static final String NUMERIC
+ = "[0-9]*";
+
+ public static final String IDENTIFIER
+ = "[a-zA-Z0-9_\\-]*";
+
+ public static final String DIRECTORY
+ = "^(?!\\/)[a-zA-Z0-9\\/]*[^\\/]$";
}
diff --git a/src/com/magento/idea/magento2plugin/util/magento/FileBasedIndexUtil.java b/src/com/magento/idea/magento2plugin/util/magento/FileBasedIndexUtil.java
index cb12b3741..31917ad28 100644
--- a/src/com/magento/idea/magento2plugin/util/magento/FileBasedIndexUtil.java
+++ b/src/com/magento/idea/magento2plugin/util/magento/FileBasedIndexUtil.java
@@ -6,12 +6,16 @@
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.psi.PsiFile;
+import com.intellij.psi.PsiManager;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.util.indexing.FileBasedIndex;
import com.jetbrains.php.lang.PhpFileType;
+import com.magento.idea.magento2plugin.magento.packages.Package;
import com.magento.idea.magento2plugin.stubs.indexes.ModuleNameIndex;
import com.magento.idea.magento2plugin.util.RegExUtil;
+import java.io.File;
import java.util.ArrayList;
import java.util.Collection;
import java.util.regex.Matcher;
@@ -43,6 +47,40 @@ public static Collection findViewVfsByModuleName(String moduleName,
return viewVfs;
}
+ public static PsiFile findModuleConfigFile(String virtualFieName, Package.Areas area, String moduleName, Project project)
+ {
+ Pattern pattern = Pattern.compile(RegExUtil.Magento.MODULE_NAME);
+ Matcher matcher = pattern.matcher(moduleName);
+ if (!matcher.find()) {
+ return null;
+ }
+
+ Collection moduleVfs =
+ FileBasedIndex.getInstance().getContainingFiles(ModuleNameIndex.KEY, moduleName,
+ GlobalSearchScope.getScopeRestrictedByFileTypes(
+ GlobalSearchScope.allScope(project),
+ PhpFileType.INSTANCE
+ )
+ );
+ if (moduleVfs.isEmpty()) {
+ return null;
+ }
+
+ VirtualFile moduleVf = moduleVfs.iterator().next();
+
+ String relativePath = File.separator.concat(Package.MODULE_BASE_AREA_DIR).concat(File.separator);
+ if (!area.equals(Package.Areas.base)) {
+ relativePath = relativePath.concat(area.toString()).concat(File.separator);
+ }
+ relativePath = relativePath.concat(virtualFieName);
+
+ VirtualFile configFile = moduleVf.getParent().findFileByRelativePath(relativePath);
+ if (configFile == null) {
+ return null;
+ }
+ return PsiManager.getInstance(project).findFile(configFile);
+ }
+
public static Collection findViewVfsByModuleVf(VirtualFile moduleVf, Project project)
{
Collection viewVfs = new ArrayList<>();
diff --git a/src/com/magento/idea/magento2plugin/util/magento/plugin/IsPluginAllowedForMethod.java b/src/com/magento/idea/magento2plugin/util/magento/plugin/IsPluginAllowedForMethod.java
new file mode 100644
index 000000000..9a99840c8
--- /dev/null
+++ b/src/com/magento/idea/magento2plugin/util/magento/plugin/IsPluginAllowedForMethod.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright © Magento, Inc. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+package com.magento.idea.magento2plugin.util.magento.plugin;
+
+import com.jetbrains.php.lang.psi.elements.Method;
+import com.magento.idea.magento2plugin.magento.files.Plugin;
+
+public class IsPluginAllowedForMethod {
+ private static IsPluginAllowedForMethod INSTANCE = null;
+
+ public static IsPluginAllowedForMethod getInstance() {
+ if (null == INSTANCE) {
+ INSTANCE = new IsPluginAllowedForMethod();
+ }
+ return INSTANCE;
+ }
+
+ public boolean check(Method targetMethod) {
+ String targetMethodName = targetMethod.getName();
+ if (targetMethodName.equals(Plugin.constructMethodName)) {
+ return false;
+ }
+ if (targetMethod.isFinal()) {
+ return false;
+ }
+ if (targetMethod.isStatic()) {
+ return false;
+ }
+ if (!targetMethod.getAccess().toString().equals(Plugin.publicAccess)) {
+ return false;
+ }
+
+ return true;
+ }
+}