diff --git a/CHANGELOG.md b/CHANGELOG.md
index 8ae353ccd..f9c377d5c 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -6,6 +6,25 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0).
## 5.0.0
+### Added
+
+- Code generation of a Data Patch Boilerplate file [#1188](https://github.com/magento/magento2-phpstorm-plugin/pull/1188)
+- Code generation of an Observer from the context menu [#1200](https://github.com/magento/magento2-phpstorm-plugin/pull/1200)
+- Code generation of events.xml file [#1189](https://github.com/magento/magento2-phpstorm-plugin/pull/1189)
+- Config Scope directory inspection [#1261](https://github.com/magento/magento2-phpstorm-plugin/pull/1261)
+
+### Changed
+
+- EAV attributes code generators: Added default values of the group property [#1259](https://github.com/magento/magento2-phpstorm-plugin/pull/1259)
+- All code generators: Added constants visibility and class property types [#1260](https://github.com/magento/magento2-phpstorm-plugin/pull/1260)
+- UCT custom coming versions [#1251](https://github.com/magento/magento2-phpstorm-plugin/pull/1251)
+
+### Fixed
+
+- Fixed wrong director(y|ies) generation for GraphQL resolver class [#1192](https://github.com/magento/magento2-phpstorm-plugin/pull/1192)
+- Fixed IndexOutOfBoundsException: CreateResolverClassQuickFix.applyFix(CreateResolverClassQuickFix.java:43) [#1192](https://github.com/magento/magento2-phpstorm-plugin/pull/1192)
+- Index out of range [#1239](https://github.com/magento/magento2-phpstorm-plugin/pull/1239)
+
## 4.4.0
### Added
diff --git a/resources/icons/graphql.svg b/resources/icons/graphql.svg
new file mode 100644
index 000000000..ffe677d5b
--- /dev/null
+++ b/resources/icons/graphql.svg
@@ -0,0 +1,11 @@
+
diff --git a/resources/magento2/inspection.properties b/resources/magento2/inspection.properties
index 7a47145af..e7596387e 100644
--- a/resources/magento2/inspection.properties
+++ b/resources/magento2/inspection.properties
@@ -15,7 +15,7 @@ inspection.plugin.duplicateInSameFile=The plugin name already used in this file.
inspection.plugin.duplicateInOtherPlaces=The plugin name "{0}" for targeted "{1}" class is already used in the module "{2}" ({3} scope). For more details see Inspection Description.
inspection.plugin.disabledPluginDoesNotExist=This plugin does not exist to be disabled.
inspection.graphql.resolver.mustImplement=Class must implements any of the following interfaces: \\Magento\\Framework\\GraphQl\\Query\\ResolverInterface, \\Magento\\Framework\\GraphQl\\Query\\Resolver\\BatchResolverInterface, \\Magento\\Framework\\GraphQl\\Query\\Resolver\\BatchServiceContractResolverInterface
-inspection.graphql.resolver.notExist=Resolver class do not exist
+inspection.graphql.resolver.notExist=The GraphQL resolver class do not exist
inspection.graphql.resolver.fix.family=Implement Resolver interface
inspection.graphql.resolver.fix.title=Select one of the following interface
inspection.graphql.schema.resolver.fix.family=Create GraphQL Resolver
@@ -41,3 +41,6 @@ inspection.warning.method.should.have.public.access=The method "{0}" should have
inspection.warning.method.should.have.public.access.fix=Change the method access
inspection.displayName.ModuleScopeInspection=Module Configuration Scope Inspection
inspection.config.wrong.area = The area of this config file is wrong. Please check the spelling of the parent directory, it should be equal to one of the following: adminhtml, frontend, crontab, webapi_rest, webapi_soap, graphql.
+inspection.warning.class.invalidFormat=The class "{0}" has invalid format
+inspection.error.graphqlResolverClass.tooShortFormat=The target GraphQL resolver class format is incorrect.\nThe fully qualified name "{0}" should contain at least 3 parts.
+inspection.error.graphqlResolverClass.tooShortFormatTitle=The GraphQL resolver class format is incorrect
diff --git a/src/com/magento/idea/magento2plugin/MagentoIcons.java b/src/com/magento/idea/magento2plugin/MagentoIcons.java
index dc83eab99..a360d9b18 100644
--- a/src/com/magento/idea/magento2plugin/MagentoIcons.java
+++ b/src/com/magento/idea/magento2plugin/MagentoIcons.java
@@ -17,4 +17,5 @@ public class MagentoIcons {
IconLoader.getIcon("/icons/pluginIcon16x16.svg", MagentoIcons.class);
public static final Icon PLUGIN_ICON_MEDIUM =
IconLoader.getIcon("/icons/pluginIcon64x64.svg", MagentoIcons.class);
+ public static final Icon GRAPHQL = IconLoader.getIcon("/icons/graphql.svg", MagentoIcons.class);
}
diff --git a/src/com/magento/idea/magento2plugin/actions/context/AbstractContextAction.java b/src/com/magento/idea/magento2plugin/actions/context/AbstractContextAction.java
index 47c826a48..bf520a212 100644
--- a/src/com/magento/idea/magento2plugin/actions/context/AbstractContextAction.java
+++ b/src/com/magento/idea/magento2plugin/actions/context/AbstractContextAction.java
@@ -24,6 +24,7 @@
import com.magento.idea.magento2plugin.magento.packages.Package;
import com.magento.idea.magento2plugin.project.Settings;
import com.magento.idea.magento2plugin.util.magento.GetMagentoModuleUtil;
+import javax.swing.Icon;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -51,6 +52,24 @@ public AbstractContextAction(
this.moduleFile = moduleFile;
}
+ /**
+ * Abstract context action constructor.
+ *
+ * @param title String
+ * @param description String
+ * @param moduleFile ModuleFileInterface
+ * @param icon Icon
+ */
+ public AbstractContextAction(
+ final @NotNull String title,
+ final @NotNull String description,
+ final @NotNull ModuleFileInterface moduleFile,
+ final @Nullable Icon icon
+ ) {
+ super(title, description, icon);
+ this.moduleFile = moduleFile;
+ }
+
@Override
@SuppressWarnings({"PMD.CyclomaticComplexity", "PMD.NPathComplexity"})
public void update(final @NotNull AnActionEvent event) {
diff --git a/src/com/magento/idea/magento2plugin/actions/context/xml/NewGraphQLSchemaAction.java b/src/com/magento/idea/magento2plugin/actions/context/xml/NewGraphQLSchemaAction.java
index 65b37bba8..6df71b95e 100644
--- a/src/com/magento/idea/magento2plugin/actions/context/xml/NewGraphQLSchemaAction.java
+++ b/src/com/magento/idea/magento2plugin/actions/context/xml/NewGraphQLSchemaAction.java
@@ -8,6 +8,7 @@
import com.intellij.ide.fileTemplates.actions.AttributesDefaults;
import com.intellij.psi.PsiDirectory;
import com.intellij.psi.PsiFile;
+import com.magento.idea.magento2plugin.MagentoIcons;
import com.magento.idea.magento2plugin.actions.context.AbstractContextAction;
import com.magento.idea.magento2plugin.magento.files.SchemaGraphQLsFile;
import com.magento.idea.magento2plugin.magento.packages.ComponentType;
@@ -25,7 +26,12 @@ public class NewGraphQLSchemaAction extends AbstractContextAction {
* New schema.graphqls file action constructor.
*/
public NewGraphQLSchemaAction() {
- super(ACTION_NAME, ACTION_DESCRIPTION, SchemaGraphQLsFile.getInstance());
+ super(
+ ACTION_NAME,
+ ACTION_DESCRIPTION,
+ SchemaGraphQLsFile.getInstance(),
+ MagentoIcons.GRAPHQL
+ );
}
@Override
diff --git a/src/com/magento/idea/magento2plugin/actions/generation/NewGraphQlResolverAction.java b/src/com/magento/idea/magento2plugin/actions/generation/NewGraphQlResolverAction.java
index 347e6b5c2..6a7f03cd8 100644
--- a/src/com/magento/idea/magento2plugin/actions/generation/NewGraphQlResolverAction.java
+++ b/src/com/magento/idea/magento2plugin/actions/generation/NewGraphQlResolverAction.java
@@ -23,7 +23,7 @@ public class NewGraphQlResolverAction extends AnAction {
public static final String ACTION_DESCRIPTION = "Create a new Magento 2 GraphQL Resolver";
public NewGraphQlResolverAction() {
- super(ACTION_NAME, ACTION_DESCRIPTION, MagentoIcons.MODULE);
+ super(ACTION_NAME, ACTION_DESCRIPTION, MagentoIcons.GRAPHQL);
}
@Override
diff --git a/src/com/magento/idea/magento2plugin/actions/generation/generator/ModuleGraphQlResolverClassGenerator.java b/src/com/magento/idea/magento2plugin/actions/generation/generator/ModuleGraphQlResolverClassGenerator.java
index b87da10d9..c9e734284 100644
--- a/src/com/magento/idea/magento2plugin/actions/generation/generator/ModuleGraphQlResolverClassGenerator.java
+++ b/src/com/magento/idea/magento2plugin/actions/generation/generator/ModuleGraphQlResolverClassGenerator.java
@@ -25,7 +25,6 @@
import com.magento.idea.magento2plugin.bundles.ValidatorBundle;
import com.magento.idea.magento2plugin.indexes.ModuleIndex;
import com.magento.idea.magento2plugin.magento.files.GraphQlResolverPhp;
-import com.magento.idea.magento2plugin.magento.packages.File;
import com.magento.idea.magento2plugin.magento.packages.MagentoPhpClass;
import com.magento.idea.magento2plugin.util.GetFirstClassOfFile;
import com.magento.idea.magento2plugin.util.GetPhpClassByFQN;
@@ -34,6 +33,7 @@
import org.jetbrains.annotations.NotNull;
public class ModuleGraphQlResolverClassGenerator extends FileGenerator {
+
private final GraphQlResolverFileData graphQlResolverFileData;
private final Project project;
private final ValidatorBundle validatorBundle;
@@ -132,15 +132,15 @@ private PhpClass createGraphQlResolverClass(final String actionName) {
if (parentDirectory == null) {
return null;
}
- final String[] graphQlResolverDirectories = graphQlResolverFileData
- .getGraphQlResolverDirectory().split(File.separator);
- for (final String graphQlResolverDirectory: graphQlResolverDirectories) {
- parentDirectory = directoryGenerator.findOrCreateSubdirectory(
+ final String graphQlResolverDirectory = graphQlResolverFileData
+ .getGraphQlResolverDirectory();
+
+ if (!graphQlResolverDirectory.isBlank()) {
+ parentDirectory = directoryGenerator.findOrCreateSubdirectories(
parentDirectory,
graphQlResolverDirectory
);
}
-
final Properties attributes = getAttributes();
final PsiFile graphQlResolverFile = fileFromTemplateGenerator.generate(
GraphQlResolverPhp.getInstance(
diff --git a/src/com/magento/idea/magento2plugin/completion/provider/LayoutBlockCompletionContributor.java b/src/com/magento/idea/magento2plugin/completion/provider/LayoutBlockCompletionContributor.java
index c01d64e1e..22be04952 100644
--- a/src/com/magento/idea/magento2plugin/completion/provider/LayoutBlockCompletionContributor.java
+++ b/src/com/magento/idea/magento2plugin/completion/provider/LayoutBlockCompletionContributor.java
@@ -2,36 +2,37 @@
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
+
package com.magento.idea.magento2plugin.completion.provider;
import com.intellij.codeInsight.completion.CompletionParameters;
import com.intellij.codeInsight.completion.CompletionProvider;
import com.intellij.codeInsight.completion.CompletionResultSet;
import com.intellij.codeInsight.lookup.LookupElementBuilder;
+import com.intellij.icons.AllIcons;
import com.intellij.psi.PsiElement;
import com.intellij.util.ProcessingContext;
-import com.jetbrains.php.PhpIcons;
import com.magento.idea.magento2plugin.indexes.LayoutIndex;
import com.magento.idea.magento2plugin.stubs.indexes.BlockNameIndex;
-import org.jetbrains.annotations.NotNull;
-
import java.util.Collection;
+import org.jetbrains.annotations.NotNull;
public class LayoutBlockCompletionContributor extends CompletionProvider {
@Override
- protected void addCompletions(@NotNull CompletionParameters parameters,
- ProcessingContext context,
- @NotNull CompletionResultSet result) {
- PsiElement position = parameters.getPosition().getOriginalElement();
+ protected void addCompletions(final @NotNull CompletionParameters parameters,
+ final ProcessingContext context,
+ final @NotNull CompletionResultSet result) {
+ final PsiElement position = parameters.getPosition().getOriginalElement();
if (position == null) {
return;
}
- Collection keys = LayoutIndex.getAllKeys(BlockNameIndex.KEY, position.getProject());
- for (String key: keys) {
+ final Collection keys
+ = LayoutIndex.getAllKeys(BlockNameIndex.KEY, position.getProject());
+ for (final String key: keys) {
result.addElement(
- LookupElementBuilder.create(key).withIcon(PhpIcons.XML_TAG_ICON)
+ LookupElementBuilder.create(key).withIcon(AllIcons.Nodes.Tag)
);
}
}
diff --git a/src/com/magento/idea/magento2plugin/completion/provider/LayoutContainerCompletionContributor.java b/src/com/magento/idea/magento2plugin/completion/provider/LayoutContainerCompletionContributor.java
index 3c6d6cf03..c127e968f 100644
--- a/src/com/magento/idea/magento2plugin/completion/provider/LayoutContainerCompletionContributor.java
+++ b/src/com/magento/idea/magento2plugin/completion/provider/LayoutContainerCompletionContributor.java
@@ -2,36 +2,37 @@
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
+
package com.magento.idea.magento2plugin.completion.provider;
import com.intellij.codeInsight.completion.CompletionParameters;
import com.intellij.codeInsight.completion.CompletionProvider;
import com.intellij.codeInsight.completion.CompletionResultSet;
import com.intellij.codeInsight.lookup.LookupElementBuilder;
+import com.intellij.icons.AllIcons;
import com.intellij.psi.PsiElement;
import com.intellij.util.ProcessingContext;
-import com.jetbrains.php.PhpIcons;
import com.magento.idea.magento2plugin.indexes.LayoutIndex;
import com.magento.idea.magento2plugin.stubs.indexes.ContainerNameIndex;
-import org.jetbrains.annotations.NotNull;
-
import java.util.Collection;
+import org.jetbrains.annotations.NotNull;
public class LayoutContainerCompletionContributor extends CompletionProvider {
@Override
- protected void addCompletions(@NotNull CompletionParameters parameters,
- ProcessingContext context,
- @NotNull CompletionResultSet result) {
- PsiElement position = parameters.getPosition().getOriginalElement();
+ protected void addCompletions(final @NotNull CompletionParameters parameters,
+ final ProcessingContext context,
+ final @NotNull CompletionResultSet result) {
+ final PsiElement position = parameters.getPosition().getOriginalElement();
if (position == null) {
return;
}
- Collection keys = LayoutIndex.getAllKeys(ContainerNameIndex.KEY, position.getProject());
- for (String key: keys) {
+ final Collection keys
+ = LayoutIndex.getAllKeys(ContainerNameIndex.KEY, position.getProject());
+ for (final String key: keys) {
result.addElement(
- LookupElementBuilder.create(key).withIcon(PhpIcons.XML_TAG_ICON)
+ LookupElementBuilder.create(key).withIcon(AllIcons.Nodes.Tag)
);
}
}
diff --git a/src/com/magento/idea/magento2plugin/completion/provider/LayoutUpdateCompletionContributor.java b/src/com/magento/idea/magento2plugin/completion/provider/LayoutUpdateCompletionContributor.java
index 071bdd3df..359534316 100644
--- a/src/com/magento/idea/magento2plugin/completion/provider/LayoutUpdateCompletionContributor.java
+++ b/src/com/magento/idea/magento2plugin/completion/provider/LayoutUpdateCompletionContributor.java
@@ -2,39 +2,40 @@
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
+
package com.magento.idea.magento2plugin.completion.provider;
import com.intellij.codeInsight.completion.CompletionParameters;
import com.intellij.codeInsight.completion.CompletionProvider;
import com.intellij.codeInsight.completion.CompletionResultSet;
import com.intellij.codeInsight.lookup.LookupElementBuilder;
+import com.intellij.icons.AllIcons;
import com.intellij.psi.PsiElement;
import com.intellij.psi.xml.XmlFile;
import com.intellij.util.ProcessingContext;
-import com.jetbrains.php.PhpIcons;
import com.magento.idea.magento2plugin.indexes.LayoutIndex;
+import java.util.List;
import org.jetbrains.annotations.NotNull;
-import java.util.List;
public class LayoutUpdateCompletionContributor extends CompletionProvider {
@Override
- protected void addCompletions(@NotNull CompletionParameters parameters,
- ProcessingContext context,
- @NotNull CompletionResultSet result) {
- PsiElement position = parameters.getPosition().getOriginalElement();
+ protected void addCompletions(final @NotNull CompletionParameters parameters,
+ final ProcessingContext context,
+ final @NotNull CompletionResultSet result) {
+ final PsiElement position = parameters.getPosition().getOriginalElement();
if (position == null) {
return;
}
- List targets = LayoutIndex.getLayoutFiles(position.getProject());
- if (targets.size() > 0) {
- for (XmlFile file : targets) {
+ final List targets = LayoutIndex.getLayoutFiles(position.getProject());
+ if (!targets.isEmpty()) {
+ for (final XmlFile file : targets) {
result.addElement(
- LookupElementBuilder
+ LookupElementBuilder
.create(file.getVirtualFile().getNameWithoutExtension())
- .withIcon(PhpIcons.XML_TAG_ICON)
+ .withIcon(AllIcons.Nodes.Tag)
);
}
}
diff --git a/src/com/magento/idea/magento2plugin/completion/provider/UiComponentCompletionProvider.java b/src/com/magento/idea/magento2plugin/completion/provider/UiComponentCompletionProvider.java
index 0091aae2b..cf80246df 100644
--- a/src/com/magento/idea/magento2plugin/completion/provider/UiComponentCompletionProvider.java
+++ b/src/com/magento/idea/magento2plugin/completion/provider/UiComponentCompletionProvider.java
@@ -9,10 +9,10 @@
import com.intellij.codeInsight.completion.CompletionProvider;
import com.intellij.codeInsight.completion.CompletionResultSet;
import com.intellij.codeInsight.lookup.LookupElementBuilder;
+import com.intellij.icons.AllIcons;
import com.intellij.psi.PsiElement;
import com.intellij.psi.xml.XmlFile;
import com.intellij.util.ProcessingContext;
-import com.jetbrains.php.PhpIcons;
import com.magento.idea.magento2plugin.indexes.UIComponentIndex;
import java.util.List;
import org.jetbrains.annotations.NotNull;
@@ -34,7 +34,7 @@ protected void addCompletions(@NotNull final CompletionParameters parameters,
for (final XmlFile file : targets) {
result.addElement(LookupElementBuilder
.create(file.getVirtualFile().getNameWithoutExtension())
- .withIcon(PhpIcons.XML_TAG_ICON)
+ .withIcon(AllIcons.Nodes.Tag)
);
}
}
diff --git a/src/com/magento/idea/magento2plugin/completion/provider/VirtualTypeCompletionProvider.java b/src/com/magento/idea/magento2plugin/completion/provider/VirtualTypeCompletionProvider.java
index 1f16cf285..0e96a9f14 100644
--- a/src/com/magento/idea/magento2plugin/completion/provider/VirtualTypeCompletionProvider.java
+++ b/src/com/magento/idea/magento2plugin/completion/provider/VirtualTypeCompletionProvider.java
@@ -2,6 +2,7 @@
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
+
package com.magento.idea.magento2plugin.completion.provider;
import com.intellij.codeInsight.completion.CompletionParameters;
@@ -9,35 +10,38 @@
import com.intellij.codeInsight.completion.CompletionResultSet;
import com.intellij.codeInsight.completion.PlainPrefixMatcher;
import com.intellij.codeInsight.lookup.LookupElementBuilder;
+import com.intellij.icons.AllIcons;
import com.intellij.psi.PsiElement;
import com.intellij.util.ProcessingContext;
-import com.jetbrains.php.PhpIcons;
import com.magento.idea.magento2plugin.indexes.DiIndex;
+import java.util.Collection;
import org.jetbrains.annotations.NotNull;
-import java.util.Collection;
public class VirtualTypeCompletionProvider extends CompletionProvider {
@Override
- protected void addCompletions(@NotNull CompletionParameters parameters,
- ProcessingContext context,
- @NotNull CompletionResultSet result) {
- PsiElement position = parameters.getPosition().getOriginalElement();
+ protected void addCompletions(final @NotNull CompletionParameters parameters,
+ final ProcessingContext context,
+ final @NotNull CompletionResultSet result) {
+ final PsiElement position = parameters.getPosition().getOriginalElement();
if (position == null) {
return;
}
- String prefix = result.getPrefixMatcher().getPrefix();
+ final String prefix = result.getPrefixMatcher().getPrefix();
- DiIndex index = DiIndex.getInstance(position.getProject());
- Collection elements = index.getAllVirtualTypeElementNames(new PlainPrefixMatcher(prefix), position.getResolveScope());
+ final DiIndex index = DiIndex.getInstance(position.getProject());
+ final Collection elements = index.getAllVirtualTypeElementNames(
+ new PlainPrefixMatcher(prefix),
+ position.getResolveScope()
+ );
- for (String elementName:elements) {
+ for (final String elementName:elements) {
result.addElement(
LookupElementBuilder
.create(elementName)
- .withIcon(PhpIcons.CLASS_ICON)
+ .withIcon(AllIcons.Nodes.Class)
);
}
}
diff --git a/src/com/magento/idea/magento2plugin/generation/php/MagentoTemplatesFactory.java b/src/com/magento/idea/magento2plugin/generation/php/MagentoTemplatesFactory.java
index 83ab09dec..b9476e54f 100644
--- a/src/com/magento/idea/magento2plugin/generation/php/MagentoTemplatesFactory.java
+++ b/src/com/magento/idea/magento2plugin/generation/php/MagentoTemplatesFactory.java
@@ -2,6 +2,7 @@
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
+
package com.magento.idea.magento2plugin.generation.php;
import com.intellij.ide.util.projectWizard.WizardContext;
@@ -9,25 +10,26 @@
import com.intellij.platform.ProjectTemplatesFactory;
import com.jetbrains.php.config.generation.PhpEmptyTemplatesFactory;
import icons.PhpIcons;
+import javax.swing.Icon;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
-import javax.swing.Icon;
public class MagentoTemplatesFactory extends ProjectTemplatesFactory {
- public MagentoTemplatesFactory() {
- }
@NotNull
public String[] getGroups() {
return new String[]{PhpEmptyTemplatesFactory.PHP_PROJECT_TEMPLATE_GROUP};
}
- public Icon getGroupIcon(String group) {
- return PhpIcons.Php_icon;
+ public Icon getGroupIcon(final String group) {
+ return PhpIcons.PhpIcon;
}
@NotNull
- public ProjectTemplate[] createTemplates(@Nullable String group, WizardContext context) {
+ public ProjectTemplate[] createTemplates(
+ final @Nullable String group,
+ final WizardContext context
+ ) {
return new ProjectTemplate[]{new MagentoModuleGenerator()};
}
}
diff --git a/src/com/magento/idea/magento2plugin/inspections/graphqls/SchemaResolverInspection.java b/src/com/magento/idea/magento2plugin/inspections/graphqls/SchemaResolverInspection.java
index 28de3bd91..2de57a155 100644
--- a/src/com/magento/idea/magento2plugin/inspections/graphqls/SchemaResolverInspection.java
+++ b/src/com/magento/idea/magento2plugin/inspections/graphqls/SchemaResolverInspection.java
@@ -8,12 +8,16 @@
import com.intellij.codeInspection.LocalInspectionTool;
import com.intellij.codeInspection.ProblemHighlightType;
import com.intellij.codeInspection.ProblemsHolder;
+import com.intellij.lang.jsgraphql.psi.GraphQLNamedElement;
import com.intellij.lang.jsgraphql.psi.GraphQLValue;
import com.intellij.lang.jsgraphql.psi.GraphQLVisitor;
+import com.intellij.psi.PsiElement;
import com.jetbrains.php.lang.psi.elements.PhpClass;
import com.magento.idea.magento2plugin.bundles.InspectionBundle;
import com.magento.idea.magento2plugin.inspections.graphqls.fix.CreateResolverClassQuickFix;
+import com.magento.idea.magento2plugin.magento.files.GraphQlResolver;
import com.magento.idea.magento2plugin.util.GetPhpClassByFQN;
+import com.magento.idea.magento2plugin.util.RegExUtil;
import com.magento.idea.magento2plugin.util.magento.graphql.GraphQlUtil;
import org.jetbrains.annotations.NotNull;
@@ -21,30 +25,49 @@ public class SchemaResolverInspection extends LocalInspectionTool {
private final InspectionBundle inspectionBundle = new InspectionBundle();
- @NotNull
@Override
- public GraphQLVisitor buildVisitor(
- @NotNull final ProblemsHolder holder,
+ public @NotNull GraphQLVisitor buildVisitor(
+ final @NotNull ProblemsHolder holder,
final boolean isOnTheFly
) {
return new GraphQLVisitor() {
@Override
- public void visitValue(@NotNull final GraphQLValue element) {
+ public void visitValue(final @NotNull GraphQLValue element) {
final String getVisitedElementValue = element.getText();
- if (getVisitedElementValue == null) {
+ final PsiElement parentElementValue = element.getParent();
+
+ if (getVisitedElementValue == null
+ || !(parentElementValue instanceof GraphQLNamedElement)) {
return;
}
+ final String attributeName = ((GraphQLNamedElement) parentElementValue).getName();
+ if (!GraphQlResolver.CLASS_ARGUMENT.equals(attributeName)) {
+ return;
+ }
final String resolverFQN
= GraphQlUtil.resolverStringToPhpFQN(getVisitedElementValue);
+
+ if (!resolverFQN.matches(RegExUtil.PhpRegex.FQN)) {
+ holder.registerProblem(
+ element,
+ inspectionBundle.message(
+ "inspection.warning.class.invalidFormat",
+ resolverFQN
+ ),
+ ProblemHighlightType.WARNING
+ );
+ return;
+ }
final GetPhpClassByFQN getPhpClassByFQN
= GetPhpClassByFQN.getInstance(holder.getProject());
final PhpClass resolverClass = getPhpClassByFQN.execute(resolverFQN);
+
if (resolverClass == null) {
holder.registerProblem(
element,
inspectionBundle.message(
- "inspection.graphql.resolver.notExist"
+ "inspection.graphql.resolver.notExist"
),
ProblemHighlightType.ERROR,
new CreateResolverClassQuickFix());
diff --git a/src/com/magento/idea/magento2plugin/inspections/graphqls/fix/CreateResolverClassQuickFix.java b/src/com/magento/idea/magento2plugin/inspections/graphqls/fix/CreateResolverClassQuickFix.java
index 57d0dca4c..44ee91b9c 100644
--- a/src/com/magento/idea/magento2plugin/inspections/graphqls/fix/CreateResolverClassQuickFix.java
+++ b/src/com/magento/idea/magento2plugin/inspections/graphqls/fix/CreateResolverClassQuickFix.java
@@ -14,12 +14,19 @@
import com.magento.idea.magento2plugin.actions.generation.data.GraphQlResolverFileData;
import com.magento.idea.magento2plugin.actions.generation.generator.ModuleGraphQlResolverClassGenerator;
import com.magento.idea.magento2plugin.bundles.InspectionBundle;
+import com.magento.idea.magento2plugin.magento.packages.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
+import javax.swing.JOptionPane;
import org.jetbrains.annotations.NotNull;
public class CreateResolverClassQuickFix implements LocalQuickFix {
+
+ private static final int CLASSPATH_MIN_DEPTH = 3;
+
+ private final InspectionBundle inspectionBundle = new InspectionBundle();
+
@Override
public @NotNull String getFamilyName() {
return new InspectionBundle().message(
@@ -39,10 +46,25 @@ public void applyFix(
fqnPartsList.removeIf(Strings::isNullOrEmpty);
+ if (fqnPartsList.size() < CLASSPATH_MIN_DEPTH) {
+ JOptionPane.showMessageDialog(
+ null,
+ inspectionBundle.message(
+ "inspection.error.graphqlResolverClass.tooShortFormat",
+ resolverFqn
+ ),
+ inspectionBundle.message(
+ "inspection.error.graphqlResolverClass.tooShortFormatTitle"
+ ),
+ JOptionPane.ERROR_MESSAGE
+ );
+ return;
+ }
+
final int endIndex = fqnPartsList.size() - 1;
final String moduleName = String.join("_", fqnPartsList.subList(0, 2));
final String resolverName = fqnPartsList.get(endIndex);
- final String directory = fqnPartsList.get(2);
+ final String directory = String.join(File.separator, fqnPartsList.subList(2, endIndex));
final String namespace = String.join("\\", fqnPartsList.subList(0, endIndex));
final GraphQlResolverFileData graphQlResolverFileData = new GraphQlResolverFileData(
diff --git a/src/com/magento/idea/magento2uct/execution/configurations/UctRunConfiguration.java b/src/com/magento/idea/magento2uct/execution/configurations/UctRunConfiguration.java
index dc40ca81f..91cb841eb 100644
--- a/src/com/magento/idea/magento2uct/execution/configurations/UctRunConfiguration.java
+++ b/src/com/magento/idea/magento2uct/execution/configurations/UctRunConfiguration.java
@@ -5,6 +5,8 @@
package com.magento.idea.magento2uct.execution.configurations;
+import static com.magento.idea.magento2uct.execution.configurations.UctSettingsEditor.MAGENTO_VERSION_PATTERN;
+
import com.intellij.execution.ExecutionException;
import com.intellij.execution.Executor;
import com.intellij.execution.RunManager;
@@ -32,6 +34,7 @@
import com.magento.idea.magento2uct.settings.UctSettingsService;
import com.magento.idea.magento2uct.util.UctExecutableValidatorUtil;
import com.magento.idea.magento2uct.util.module.UctModulePathValidatorUtil;
+import java.util.regex.Matcher;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -241,6 +244,11 @@ public boolean isNewlyCreated() {
throw new ExecutionException("The coming/target version is not specified");
}
+ final Matcher matcher = MAGENTO_VERSION_PATTERN.matcher(getComingVersion());
+ if (!matcher.find()) {
+ throw new ExecutionException("The coming/target version is not correct");
+ }
+
if (getProjectRoot().isEmpty()) {
throw new ExecutionException("The project root is not specified");
}
@@ -255,14 +263,12 @@ public boolean isNewlyCreated() {
commandSettingsBuilder.addArgument("--coming-version=" + getComingVersion());
}
- commandSettingsBuilder.addArgument(getProjectRoot());
-
final GeneralCommandLine commandLine =
commandSettingsBuilder.createGeneralCommandLine();
if (!getModulePath().isEmpty()) {
if (UctModulePathValidatorUtil.validate(getModulePath())) {
- commandLine.addParameter("--module-path=".concat(getModulePath()));
+ commandLine.addParameter(getModulePath());
} else {
throw new ExecutionException("The path to analyse is not valid");
}
diff --git a/src/com/magento/idea/magento2uct/execution/configurations/UctSettingsEditor.form b/src/com/magento/idea/magento2uct/execution/configurations/UctSettingsEditor.form
index a3de59bfc..1e7f0ca56 100644
--- a/src/com/magento/idea/magento2uct/execution/configurations/UctSettingsEditor.form
+++ b/src/com/magento/idea/magento2uct/execution/configurations/UctSettingsEditor.form
@@ -25,7 +25,9 @@
-
+
+
+
diff --git a/src/com/magento/idea/magento2uct/execution/configurations/UctSettingsEditor.java b/src/com/magento/idea/magento2uct/execution/configurations/UctSettingsEditor.java
index 215bf5626..ff71c219e 100644
--- a/src/com/magento/idea/magento2uct/execution/configurations/UctSettingsEditor.java
+++ b/src/com/magento/idea/magento2uct/execution/configurations/UctSettingsEditor.java
@@ -29,6 +29,9 @@
import java.awt.Container;
import java.net.URI;
import java.net.URISyntaxException;
+import java.util.Objects;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JComponent;
@@ -45,6 +48,10 @@ public class UctSettingsEditor extends SettingsEditor {
private static final String LEARN_MORE_URI =
"https://docs.magento.com/user-guide/getting-started.html#product-editions";
private static final String LEARN_MORE_TEXT = "Learn more. ";
+ @SuppressWarnings("checkstyle:LineLength")
+ private static final String MAGENTO_VERSION_REGEX = "^(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(?:-((?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\.(?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\\+([0-9a-zA-Z-]+(?:\\.[0-9a-zA-Z-]+)*))?$";
+ public static final Pattern MAGENTO_VERSION_PATTERN
+ = Pattern.compile(MAGENTO_VERSION_REGEX);
private final Project project;
private String uctExecutablePath;
@@ -126,6 +133,14 @@ protected void resetEditorFrom(final @NotNull UctRunConfiguration uctRunConfigur
if (!uctRunConfiguration.getComingVersion().isEmpty()) {
final String storedComingVersion = uctRunConfiguration.getComingVersion();
setSelectedValueByItsKey(comingVersion, storedComingVersion);
+
+ if (!Objects.requireNonNull(
+ comingVersion.getSelectedItem()).toString().equals(storedComingVersion)) {
+ final ComboBoxItemData customVersion
+ = new ComboBoxItemData(storedComingVersion, storedComingVersion);
+ comingVersion.addItem(customVersion);
+ comingVersion.setSelectedItem(customVersion);
+ }
}
if (uctRunConfiguration.getMinIssueLevel() > 0) {
@@ -148,8 +163,8 @@ protected void applyEditorTo(final @NotNull UctRunConfiguration uctRunConfigurat
uctRunConfiguration.setProjectRoot(projectRoot.getComponent().getText());
uctRunConfiguration.setModulePath(modulePath.getComponent().getText());
- final ComboBoxItemData selectedComingVersion =
- (ComboBoxItemData) comingVersion.getSelectedItem();
+ final ComboBoxItemData selectedComingVersion
+ = getCorrectedSelectedItem(comingVersion.getSelectedItem());
if (selectedComingVersion == null) {
uctRunConfiguration.setComingVersion("");
@@ -299,7 +314,7 @@ private String getStoredUctExecutablePath(
*/
@SuppressWarnings("PMD.AvoidInstantiatingObjectsInLoops")
private void initializeComboboxSources() {
- comingVersion.addItem(new ComboBoxItemData("", "Choose a target version"));
+ comingVersion.setToolTipText("Choose a target version");
for (final String version : SupportedVersion.getSupportedVersions()) {
comingVersion.addItem(new ComboBoxItemData(version, version));
@@ -339,7 +354,7 @@ protected void textChanged(final @NotNull DocumentEvent event) {
});
comingVersion.addItemListener(event -> {
- final ComboBoxItemData selectedItem = (ComboBoxItemData) event.getItem();
+ final ComboBoxItemData selectedItem = getCorrectedSelectedItem(event.getItem());
validateComingVersionField(selectedItem);
});
@@ -366,13 +381,37 @@ private void validateExecutablePathField() {
* @param selectedItem ComboBoxItemData
*/
private void validateComingVersionField(final ComboBoxItemData selectedItem) {
+ final Matcher matcher = MAGENTO_VERSION_PATTERN.matcher(selectedItem.getText());
+
if (selectedItem != null && selectedItem.getKey().isEmpty()) {
comingVersionError.setText("Please, specify target version");
+ } else if (!matcher.find()) { // NOPMD
+ comingVersionError.setText("Please, correct target version");
} else {
comingVersionError.setText("");
}
}
+ /**
+ * Get existing item or select and convert custom version.
+ *
+ * @param selectedItem String|ComboBoxItemData
+ * @return ComboBoxItemData
+ */
+ private ComboBoxItemData getCorrectedSelectedItem(final Object selectedItem) {
+ ComboBoxItemData selectedComingVersion;
+
+ if (selectedItem instanceof ComboBoxItemData) {
+ selectedComingVersion = (ComboBoxItemData) selectedItem;
+ } else {
+ final String customSelectedVersion = selectedItem.toString();
+ selectedComingVersion
+ = new ComboBoxItemData(customSelectedVersion, customSelectedVersion);
+ }
+
+ return selectedComingVersion;
+ }
+
/**
* Set selected combobox item by key.
*