diff --git a/CHANGELOG.md b/CHANGELOG.md
index 95d74d72a..fc13a881e 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,13 +2,21 @@
All notable changes to this project will be documented in this file.
-The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0).
+The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0).
## 3.1.0
### Added
-- Extended `.phpstorm.meta.php` for more convenient autocomplete
+- Extended `.phpstorm.meta.php` for more convenient autocomplete [#467](https://github.com/magento/magento2-phpstorm-plugin/pull/467)
+- Code generation for message queue in [#411](https://github.com/magento/magento2-phpstorm-plugin/pull/411)
+- Code generation for declarative schema [#453](https://github.com/magento/magento2-phpstorm-plugin/pull/453)
+- Inspection warning for disabled observer [#432](https://github.com/magento/magento2-phpstorm-plugin/pull/432)
+- The action item to the context menu to copy file path in the Magento format [#451](https://github.com/magento/magento2-phpstorm-plugin/pull/451)
+
+### Fixed
+
+- The null pointer exception on the Create Module Dialog
## 3.0.4
diff --git a/README.md b/README.md
index c03a8415e..f9a9616ee 100644
--- a/README.md
+++ b/README.md
@@ -9,6 +9,7 @@
[](https://plugins.jetbrains.com/plugin/8024)
[](https://plugins.jetbrains.com/plugin/8024)

+[](https://magento.com)
## Installation
diff --git a/resources/phpstorm.meta.php/di-autocomplete.php b/resources/.phpstorm.meta.php/di-autocomplete.php
similarity index 100%
rename from resources/phpstorm.meta.php/di-autocomplete.php
rename to resources/.phpstorm.meta.php/di-autocomplete.php
diff --git a/resources/META-INF/plugin.xml b/resources/META-INF/plugin.xml
index 35d9f7eb1..e7fd64154 100644
--- a/resources/META-INF/plugin.xml
+++ b/resources/META-INF/plugin.xml
@@ -236,7 +236,6 @@
-
+
-
diff --git a/resources/fileTemplates/internal/Magento Data Model Interface.php.ft b/resources/fileTemplates/internal/Magento Data Model Interface.php.ft
index 2efe47430..efa91463e 100644
--- a/resources/fileTemplates/internal/Magento Data Model Interface.php.ft
+++ b/resources/fileTemplates/internal/Magento Data Model Interface.php.ft
@@ -1,6 +1,5 @@
diff --git a/src/com/magento/idea/magento2plugin/actions/generation/dialog/NewMessageQueueDialog.java b/src/com/magento/idea/magento2plugin/actions/generation/dialog/NewMessageQueueDialog.java
index fa108e58e..e444c0574 100644
--- a/src/com/magento/idea/magento2plugin/actions/generation/dialog/NewMessageQueueDialog.java
+++ b/src/com/magento/idea/magento2plugin/actions/generation/dialog/NewMessageQueueDialog.java
@@ -7,8 +7,9 @@
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiDirectory;
-import com.magento.idea.magento2plugin.actions.generation.NewDataModelAction;
+import com.intellij.ui.DocumentAdapter;
import com.magento.idea.magento2plugin.actions.generation.NewMessageQueueAction;
+import com.magento.idea.magento2plugin.actions.generation.data.MessageQueueClassData;
import com.magento.idea.magento2plugin.actions.generation.data.QueueCommunicationData;
import com.magento.idea.magento2plugin.actions.generation.data.QueueConsumerData;
import com.magento.idea.magento2plugin.actions.generation.data.QueuePublisherData;
@@ -22,23 +23,32 @@
import com.magento.idea.magento2plugin.actions.generation.dialog.validator.rule.NotEmptyRule;
import com.magento.idea.magento2plugin.actions.generation.dialog.validator.rule.NumericRule;
import com.magento.idea.magento2plugin.actions.generation.dialog.validator.rule.PhpClassFqnRule;
+import com.magento.idea.magento2plugin.actions.generation.generator.MessageQueueClassGenerator;
import com.magento.idea.magento2plugin.actions.generation.generator.QueueCommunicationGenerator;
import com.magento.idea.magento2plugin.actions.generation.generator.QueueConsumerGenerator;
import com.magento.idea.magento2plugin.actions.generation.generator.QueuePublisherGenerator;
import com.magento.idea.magento2plugin.actions.generation.generator.QueueTopologyGenerator;
+import com.magento.idea.magento2plugin.actions.generation.generator.util.NamespaceBuilder;
+import com.magento.idea.magento2plugin.magento.files.MessageQueueClassPhp;
+import com.magento.idea.magento2plugin.magento.packages.MessageQueueConnections;
import com.magento.idea.magento2plugin.util.magento.GetModuleNameByDirectoryUtil;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.JButton;
+import javax.swing.JComboBox;
import javax.swing.JComponent;
+import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.KeyStroke;
+import javax.swing.event.DocumentEvent;
+import org.jetbrains.annotations.NotNull;
@SuppressWarnings({
"PMD.TooManyFields",
+ "PMD.TooManyMethods",
"PMD.ExcessiveImports",
})
public class NewMessageQueueDialog extends AbstractDialog {
@@ -49,11 +59,12 @@ public class NewMessageQueueDialog extends AbstractDialog {
private static final String QUEUE_NAME = "Queue Name";
private static final String CONSUMER_TYPE = "Consumer Type";
private static final String MAX_MESSAGES = "Maximum Messages";
- private static final String CONNECTION_NAME = "Connection Name";
private static final String EXCHANGE_NAME = "Exchange Name";
private static final String BINDING_ID = "Binding ID";
private static final String BINDING_TOPIC = "Binding Topic";
+ private JComboBox connectionName;
+
/* TODO: Improve validation */
@FieldValidation(rule = RuleRegistry.NOT_EMPTY,
message = {NotEmptyRule.MESSAGE, TOPIC_NAME})
@@ -65,15 +76,15 @@ public class NewMessageQueueDialog extends AbstractDialog {
@FieldValidation(rule = RuleRegistry.NOT_EMPTY,
message = {NotEmptyRule.MESSAGE, HANDLER_NAME})
- @FieldValidation(rule = RuleRegistry.ALPHANUMERIC_WITH_UNDERSCORE,
+ @FieldValidation(rule = RuleRegistry.ALPHA_WITH_PERIOD,
message = {AlphanumericWithUnderscoreRule.MESSAGE, HANDLER_NAME})
private JTextField handlerName;
@FieldValidation(rule = RuleRegistry.NOT_EMPTY,
message = {NotEmptyRule.MESSAGE, HANDLER_TYPE})
- @FieldValidation(rule = RuleRegistry.PHP_CLASS_FQN,
+ @FieldValidation(rule = RuleRegistry.PHP_CLASS,
message = {PhpClassFqnRule.MESSAGE, HANDLER_TYPE})
- private JTextField handlerType;
+ private JTextField handlerClass;
@FieldValidation(rule = RuleRegistry.NOT_EMPTY,
message = {NotEmptyRule.MESSAGE, CONSUMER_NAME})
@@ -93,9 +104,9 @@ public class NewMessageQueueDialog extends AbstractDialog {
@FieldValidation(rule = RuleRegistry.NOT_EMPTY,
message = {NotEmptyRule.MESSAGE, CONSUMER_TYPE})
- @FieldValidation(rule = RuleRegistry.PHP_CLASS_FQN,
+ @FieldValidation(rule = RuleRegistry.PHP_CLASS,
message = {PhpClassFqnRule.MESSAGE, CONSUMER_TYPE})
- private JTextField consumerType;
+ private JTextField consumerClass;
@FieldValidation(rule = RuleRegistry.NOT_EMPTY,
message = {NotEmptyRule.MESSAGE, MAX_MESSAGES})
@@ -103,11 +114,6 @@ public class NewMessageQueueDialog extends AbstractDialog {
message = {NumericRule.MESSAGE, MAX_MESSAGES})
private JTextField maxMessages;
- // TODO: Can this be made a dropdown?
- @FieldValidation(rule = RuleRegistry.NOT_EMPTY,
- message = {NotEmptyRule.MESSAGE, CONNECTION_NAME})
- private JTextField connectionName;
-
@FieldValidation(rule = RuleRegistry.NOT_EMPTY,
message = {NotEmptyRule.MESSAGE, EXCHANGE_NAME})
@FieldValidation(rule = RuleRegistry.ALPHA_WITH_DASH,
@@ -120,14 +126,25 @@ public class NewMessageQueueDialog extends AbstractDialog {
message = {AlphaWithDashRule.MESSAGE, BINDING_ID})
private JTextField bindingId;
- // TODO: New validation rule
@FieldValidation(rule = RuleRegistry.NOT_EMPTY,
message = {NotEmptyRule.MESSAGE, BINDING_TOPIC})
+ @FieldValidation(rule = RuleRegistry.ALPHA_WITH_PERIOD,
+ message = {AlphanumericWithUnderscoreRule.MESSAGE, BINDING_TOPIC})
private JTextField bindingTopic;
+ private JTextField consumerDirectory;
+ private JTextField handlerDirectory;
+
private JPanel contentPanel;
private JButton buttonOK;
private JButton buttonCancel;
+ private JLabel consumerDirectoryLabel;
+ private JLabel consumerClassLabel;
+ private JLabel maxMessagesLabel;
+ private JLabel bindingTopicLabel;//NOPMD
+ private JLabel handlerClassLabel;//NOPMD
+ private JLabel consumerNameLabel;//NOPMD
+ private JLabel handlerDirectoryLabel;//NOPMD
private final Project project;
private final String moduleName;
@@ -143,9 +160,13 @@ public NewMessageQueueDialog(final Project project, final PsiDirectory directory
setContentPane(contentPanel);
setModal(true);
- setTitle(NewDataModelAction.ACTION_DESCRIPTION);
+ setTitle(NewMessageQueueAction.ACTION_DESCRIPTION);
getRootPane().setDefaultButton(buttonOK);
+ for (final String connection : MessageQueueConnections.getList()) {
+ connectionName.addItem(connection);
+ }
+
buttonOK.addActionListener((final ActionEvent event) -> onOK());
buttonCancel.addActionListener((final ActionEvent event) -> onCancel());
@@ -164,6 +185,39 @@ public void windowClosing(final WindowEvent event) {
KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0),
JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT
);
+
+ this.topicName.getDocument().addDocumentListener(new DocumentAdapter() {
+ @Override
+ protected void textChanged(final @NotNull DocumentEvent event) {
+ updateIndefiersTextes();
+ }
+ });
+ this.handlerClass.getDocument().addDocumentListener(new DocumentAdapter() {
+ @Override
+ protected void textChanged(final @NotNull DocumentEvent event) {
+ updateBindingText();
+ }
+ });
+
+ connectionName.addActionListener(e -> toggleConsumer());
+ }
+
+ private void toggleConsumer() {
+ if (getConnectionName().equals(MessageQueueConnections.AMPQ.getType())) {
+ consumerDirectoryLabel.setVisible(false);
+ consumerDirectory.setVisible(false);
+ consumerClass.setVisible(false);
+ consumerClassLabel.setVisible(false);
+ maxMessages.setVisible(false);
+ maxMessagesLabel.setVisible(false);
+ return;
+ }
+ consumerDirectoryLabel.setVisible(true);
+ consumerDirectory.setVisible(true);
+ consumerClass.setVisible(true);
+ consumerClassLabel.setVisible(true);
+ maxMessages.setVisible(true);
+ maxMessagesLabel.setVisible(true);
}
/**
@@ -187,6 +241,10 @@ private void onOK() {
generateConsumer();
generateTopology();
generatePublisher();
+ generateHandlerClass();
+ if (getConnectionName().equals(MessageQueueConnections.DB.getType())) {
+ generateConsumerClass();
+ }
this.setVisible(false);
}
}
@@ -195,7 +253,7 @@ private void generateCommunication() {
new QueueCommunicationGenerator(project, new QueueCommunicationData(
getTopicName(),
getHandlerName(),
- getHandlerType(),
+ getHandlerClass(),
getHandlerMethod(),
getModuleName()
)).generate(NewMessageQueueAction.ACTION_NAME, true);
@@ -205,11 +263,12 @@ private void generateConsumer() {
new QueueConsumerGenerator(project, new QueueConsumerData(
getConsumerName(),
getQueueName(),
- getConsumerType(),
+ getConsumerClass(),
getMaxMessages(),
getConnectionName(),
- getModuleName()
- )).generate(NewMessageQueueAction.ACTION_NAME, true);
+ getModuleName(),
+ getHandlerClass().concat("::").concat(getHandlerMethod())
+ )).generate(NewMessageQueueAction.ACTION_NAME, false);
}
private void generateTopology() {
@@ -220,7 +279,7 @@ private void generateTopology() {
getBindingTopic(),
getQueueName(),
getModuleName()
- )).generate(NewMessageQueueAction.ACTION_NAME, true);
+ )).generate(NewMessageQueueAction.ACTION_NAME, false);
}
private void generatePublisher() {
@@ -229,7 +288,29 @@ private void generatePublisher() {
getConnectionName(),
getExchangeName(),
getModuleName()
- )).generate(NewMessageQueueAction.ACTION_NAME, true);
+ )).generate(NewMessageQueueAction.ACTION_NAME, false);
+ }
+
+ private void generateHandlerClass() {
+ @NotNull final NamespaceBuilder handlerNamespaceBuilder = getHandlerNamespaceBuilder();
+ new MessageQueueClassGenerator(new MessageQueueClassData(
+ handlerClass.getText().trim(),
+ handlerNamespaceBuilder.getNamespace(),
+ handlerDirectory.getText().trim(),
+ handlerNamespaceBuilder.getClassFqn(),
+ MessageQueueClassPhp.Type.HANDLER
+ ), getModuleName(), project).generate(NewMessageQueueAction.ACTION_NAME, false);
+ }
+
+ private void generateConsumerClass() {
+ @NotNull final NamespaceBuilder consumerNamespaceBuilder = getConsumerNamespaceBuilder();
+ new MessageQueueClassGenerator(new MessageQueueClassData(
+ consumerClass.getText().trim(),
+ consumerNamespaceBuilder.getNamespace(),
+ consumerDirectory.getText().trim(),
+ consumerNamespaceBuilder.getClassFqn(),
+ MessageQueueClassPhp.Type.CONSUMER
+ ), getModuleName(), project).generate(NewMessageQueueAction.ACTION_NAME, false);
}
public String getTopicName() {
@@ -240,8 +321,30 @@ public String getHandlerName() {
return handlerName.getText().trim();
}
- public String getHandlerType() {
- return handlerType.getText().trim();
+ @NotNull
+ private NamespaceBuilder getHandlerNamespaceBuilder() {
+ return new NamespaceBuilder(
+ getModuleName(),
+ handlerClass.getText().trim(),
+ handlerDirectory.getText().trim()
+ );
+ }
+
+ @NotNull
+ private NamespaceBuilder getConsumerNamespaceBuilder() {
+ return new NamespaceBuilder(
+ getModuleName(),
+ consumerClass.getText().trim(),
+ consumerDirectory.getText().trim()
+ );
+ }
+
+ public String getHandlerClass() {
+ return getHandlerNamespaceBuilder().getClassFqn();
+ }
+
+ public String getConsumerClass() {
+ return getConsumerNamespaceBuilder().getClassFqn();
}
public String getHandlerMethod() {
@@ -256,16 +359,12 @@ public String getQueueName() {
return queueName.getText().trim();
}
- public String getConsumerType() {
- return consumerType.getText().trim();
- }
-
public String getMaxMessages() {
return maxMessages.getText().trim();
}
public String getConnectionName() {
- return connectionName.getText().trim();
+ return connectionName.getSelectedItem().toString();
}
public String getExchangeName() {
@@ -283,4 +382,24 @@ public String getBindingTopic() {
public String getModuleName() {
return moduleName;
}
+
+ /**
+ * Update identifier texts.
+ */
+ public void updateIndefiersTextes() {
+ final String topicNameText = this.topicName.getText();
+ this.handlerName.setText(topicNameText.concat(".handler"));
+ this.consumerName.setText(topicNameText);
+ this.queueName.setText(topicNameText);
+ this.bindingTopic.setText(topicNameText);
+ }
+
+ /**
+ * Update identifier texts.
+ */
+ public void updateBindingText() {
+ final String handlerTypeText = this.handlerClass.getText();
+ this.consumerClass.setText(handlerTypeText.replace("Handler", "").concat("Consumer"));
+ this.bindingId.setText(handlerTypeText.replace("Handler", "").concat("Binding"));
+ }
}
diff --git a/src/com/magento/idea/magento2plugin/actions/generation/generator/MessageQueueClassGenerator.java b/src/com/magento/idea/magento2plugin/actions/generation/generator/MessageQueueClassGenerator.java
new file mode 100644
index 000000000..02d5cf79f
--- /dev/null
+++ b/src/com/magento/idea/magento2plugin/actions/generation/generator/MessageQueueClassGenerator.java
@@ -0,0 +1,145 @@
+/*
+ * 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.project.Project;
+import com.intellij.psi.PsiDirectory;
+import com.intellij.psi.PsiFile;
+import com.jetbrains.php.lang.psi.PhpFile;
+import com.jetbrains.php.lang.psi.elements.PhpClass;
+import com.magento.idea.magento2plugin.actions.generation.data.MessageQueueClassData;
+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.bundles.CommonBundle;
+import com.magento.idea.magento2plugin.bundles.ValidatorBundle;
+import com.magento.idea.magento2plugin.indexes.ModuleIndex;
+import com.magento.idea.magento2plugin.magento.files.MessageQueueClassPhp;
+import com.magento.idea.magento2plugin.magento.packages.File;
+import com.magento.idea.magento2plugin.util.GetFirstClassOfFile;
+import com.magento.idea.magento2plugin.util.GetPhpClassByFQN;
+import java.util.Properties;
+import javax.swing.JOptionPane;
+
+public class MessageQueueClassGenerator extends FileGenerator {
+ private final MessageQueueClassData messageQueueClassDataName;
+ private final Project project;
+ private final DirectoryGenerator directoryGenerator;
+ private final FileFromTemplateGenerator fileFromTemplateGenerator;
+ private final ValidatorBundle validatorBundle;
+ private final CommonBundle commonBundle;
+ private final String moduleName;
+ private final GetFirstClassOfFile getFirstClassOfFile;
+
+ /**
+ * Message queue handler constructor.
+ *
+ * @param messageQueueClassData MessageQueueHandlerData
+ * @param moduleName String
+ * @param project Project
+ */
+ public MessageQueueClassGenerator(
+ final MessageQueueClassData messageQueueClassData,
+ final String moduleName,
+ final Project project
+ ) {
+ super(project);
+
+ this.messageQueueClassDataName = messageQueueClassData;
+ this.directoryGenerator = DirectoryGenerator.getInstance();
+ this.fileFromTemplateGenerator = FileFromTemplateGenerator.getInstance(project);
+ this.validatorBundle = new ValidatorBundle();
+ this.commonBundle = new CommonBundle();
+ this.getFirstClassOfFile = GetFirstClassOfFile.getInstance();
+ this.project = project;
+ this.moduleName = moduleName;
+ }
+
+ @Override
+ public PsiFile generate(final String actionName) {
+ final PsiFile[] handlerFiles = new PsiFile[1];
+
+ WriteCommandAction.runWriteCommandAction(project, () -> {
+ PhpClass handler = GetPhpClassByFQN.getInstance(project).execute(
+ messageQueueClassDataName.getFqn()
+ );
+
+ if (handler != null) {
+ final String errorMessage = this.validatorBundle.message(
+ "validator.file.alreadyExists",
+ "Handler Class"
+ );
+ JOptionPane.showMessageDialog(
+ null,
+ errorMessage,
+ commonBundle.message("common.error"),
+ JOptionPane.ERROR_MESSAGE
+ );
+
+ return;
+ }
+
+ handler = createHandlerClass(actionName);
+
+ if (handler == null) {
+ final String errorMessage = this.validatorBundle.message(
+ "validator.file.cantBeCreated",
+ "Handler Class"
+ );
+ JOptionPane.showMessageDialog(
+ null,
+ errorMessage,
+ commonBundle.message("common.error"),
+ JOptionPane.ERROR_MESSAGE
+ );
+
+ return;
+ }
+
+ handlerFiles[0] = handler.getContainingFile();
+ });
+
+ return handlerFiles[0];
+ }
+
+ @Override
+ protected void fillAttributes(final Properties attributes) {
+ attributes.setProperty("NAMESPACE", messageQueueClassDataName.getNamespace());
+ attributes.setProperty("CLASS_NAME", messageQueueClassDataName.getName());
+ }
+
+ private PhpClass createHandlerClass(final String actionName) {
+ PsiDirectory parentDirectory = ModuleIndex.getInstance(project)
+ .getModuleDirectoryByModuleName(this.moduleName);
+ final PsiFile handlerFile;
+ final String[] handlerDirectories = messageQueueClassDataName.getPath().split(
+ File.separator
+ );
+ for (final String handlerDirectory: handlerDirectories) {
+ parentDirectory = directoryGenerator.findOrCreateSubdirectory(
+ parentDirectory, handlerDirectory
+ );
+ }
+
+ final Properties attributes = getAttributes();
+
+ handlerFile = fileFromTemplateGenerator.generate(
+ new MessageQueueClassPhp(
+ messageQueueClassDataName.getName(),
+ messageQueueClassDataName.getType()
+ ),
+ attributes,
+ parentDirectory,
+ actionName
+ );
+
+ if (handlerFile == null) {
+ return null;
+ }
+
+ return getFirstClassOfFile.execute((PhpFile) handlerFile);
+ }
+}
diff --git a/src/com/magento/idea/magento2plugin/actions/generation/generator/QueueConsumerGenerator.java b/src/com/magento/idea/magento2plugin/actions/generation/generator/QueueConsumerGenerator.java
index 961b55bfa..5e1ada751 100644
--- a/src/com/magento/idea/magento2plugin/actions/generation/generator/QueueConsumerGenerator.java
+++ b/src/com/magento/idea/magento2plugin/actions/generation/generator/QueueConsumerGenerator.java
@@ -14,6 +14,7 @@
import com.intellij.psi.xml.XmlTag;
import com.magento.idea.magento2plugin.actions.generation.data.QueueConsumerData;
import com.magento.idea.magento2plugin.actions.generation.generator.util.FindOrCreateQueueConsumerXml;
+import com.magento.idea.magento2plugin.magento.packages.MessageQueueConnections;
import java.util.Properties;
public class QueueConsumerGenerator extends FileGenerator {
@@ -58,9 +59,14 @@ public PsiFile generate(final String actionName) {
final XmlTag consumerTag = rootTag.createChildTag("consumer", null, null, false);
consumerTag.setAttribute("name", consumerData.getConsumerName());
consumerTag.setAttribute("queue", consumerData.getQueueName());
- consumerTag.setAttribute("consumerInstance", consumerData.getConsumerType());
consumerTag.setAttribute("connection", consumerData.getConnectionName());
- consumerTag.setAttribute("maxMessages", consumerData.getMaxMessages());
+
+ if (consumerData.getConnectionName().equals(MessageQueueConnections.DB.getType())) {
+ consumerTag.setAttribute("consumerInstance", consumerData.getConsumerClass());
+ consumerTag.setAttribute("maxMessages", consumerData.getMaxMessages());
+ } else {
+ consumerTag.setAttribute("handler", consumerData.getHandler());
+ }
rootTag.addSubTag(consumerTag, false);
}
diff --git a/src/com/magento/idea/magento2plugin/inspections/xml/PluginDeclarationInspection.java b/src/com/magento/idea/magento2plugin/inspections/xml/PluginDeclarationInspection.java
index 6fe323cdc..99412796d 100644
--- a/src/com/magento/idea/magento2plugin/inspections/xml/PluginDeclarationInspection.java
+++ b/src/com/magento/idea/magento2plugin/inspections/xml/PluginDeclarationInspection.java
@@ -71,6 +71,9 @@ public void visitFile(final PsiFile file) {
final XmlAttribute pluginNameAttribute =
pluginXmlTag.getAttribute(ModuleDiXml.NAME_ATTR);
+ if (pluginNameAttribute == null) {
+ continue;
+ }
final String pluginNameAttributeValue = pluginNameAttribute.getValue();
if (pluginNameAttributeValue == null) {
diff --git a/src/com/magento/idea/magento2plugin/magento/files/MessageQueueClassPhp.java b/src/com/magento/idea/magento2plugin/magento/files/MessageQueueClassPhp.java
new file mode 100644
index 000000000..5815ad8dc
--- /dev/null
+++ b/src/com/magento/idea/magento2plugin/magento/files/MessageQueueClassPhp.java
@@ -0,0 +1,63 @@
+/*
+ * 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 MessageQueueClassPhp implements ModuleFileInterface {
+ public static final String HANDLER_TEMPLATE = "Magento Message Queue Handler Class";
+ public static final String CONSUMER_TEMPLATE = "Magento Message Queue Consumer Class";
+ public static final String FILE_EXTENSION = "php";
+ private String className;
+ private final Type type;
+
+ /**
+ * Constructor.
+ *
+ * @param className String
+ * @param type Type
+ */
+ public MessageQueueClassPhp(
+ final String className,
+ final Type type
+ ) {
+ this.className = className;
+ this.type = type;
+ }
+
+ /**
+ * Set class name.
+ *
+ * @param className String
+ */
+ public void setClassName(final String className) {
+ this.className = className;
+ }
+
+ @Override
+ public String getFileName() {
+ return String.format("%s.%s", className, FILE_EXTENSION);
+ }
+
+ @Override
+ public String getTemplate() {
+ if (type.equals(Type.CONSUMER)) {
+ return CONSUMER_TEMPLATE;
+ }
+ return HANDLER_TEMPLATE;
+ }
+
+ @Override
+ public Language getLanguage() {
+ return PhpLanguage.INSTANCE;
+ }
+
+ public enum Type {
+ HANDLER,
+ CONSUMER
+ }
+}
diff --git a/src/com/magento/idea/magento2plugin/magento/packages/MessageQueueConnections.java b/src/com/magento/idea/magento2plugin/magento/packages/MessageQueueConnections.java
new file mode 100644
index 000000000..e3683914b
--- /dev/null
+++ b/src/com/magento/idea/magento2plugin/magento/packages/MessageQueueConnections.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright © Magento, Inc. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+package com.magento.idea.magento2plugin.magento.packages;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public enum MessageQueueConnections {
+ DB("db"),
+ AMPQ("ampq");
+
+ private final String type;
+
+ /**
+ * Queue connection constructor.
+ *
+ * @param type String
+ */
+ MessageQueueConnections(final String type) {
+ this.type = type;
+ }
+
+ /**
+ * Get connection type.
+ *
+ * @return String
+ */
+ public String getType() {
+ return type;
+ }
+
+ /**
+ * Get connection type by name.
+ *
+ * @param typeName type name
+ * @return Request Interface
+ */
+ public static String getConnectionTypeByName(final String typeName) {
+ return MessageQueueConnections.valueOf(typeName).getType();
+ }
+
+ /**
+ * Get list of connection types.
+ *
+ * @return List connection types.
+ */
+ public static List getList() {
+ final List typeList = new ArrayList<>();
+
+ for (final MessageQueueConnections type: MessageQueueConnections.values()) {
+ typeList.add(getConnectionTypeByName(type.name()));
+ }
+
+ return typeList;
+ }
+}
diff --git a/src/com/magento/idea/magento2plugin/util/magento/MagentoVersionUtil.java b/src/com/magento/idea/magento2plugin/util/magento/MagentoVersionUtil.java
index 230d22b21..7b5c22180 100644
--- a/src/com/magento/idea/magento2plugin/util/magento/MagentoVersionUtil.java
+++ b/src/com/magento/idea/magento2plugin/util/magento/MagentoVersionUtil.java
@@ -87,6 +87,10 @@ public static boolean compare(final String version1, final String version2) {
return true;
}
+ if (version1.isEmpty()) {
+ return false;
+ }
+
final String[] version1s = version1.split("\\.");
final String[] version2s = version2.split("\\.");
for (int i = 0; i < 2; i++) {
diff --git a/testData/actions/generation/generator/DataModelGenerator/generateDataModel/Sample.php b/testData/actions/generation/generator/DataModelGenerator/generateDataModel/Sample.php
index 50cf49550..f09ef5e6b 100644
--- a/testData/actions/generation/generator/DataModelGenerator/generateDataModel/Sample.php
+++ b/testData/actions/generation/generator/DataModelGenerator/generateDataModel/Sample.php
@@ -1,5 +1,4 @@
+
+
+
diff --git a/testData/actions/generation/generator/QueueConsumerGenerator/generateConsumerXmlFile/queue_consumer.xml b/testData/actions/generation/generator/QueueConsumerGenerator/generateConsumerDbXmlFile/queue_consumer.xml
similarity index 66%
rename from testData/actions/generation/generator/QueueConsumerGenerator/generateConsumerXmlFile/queue_consumer.xml
rename to testData/actions/generation/generator/QueueConsumerGenerator/generateConsumerDbXmlFile/queue_consumer.xml
index ca08e43aa..f7f122ad5 100644
--- a/testData/actions/generation/generator/QueueConsumerGenerator/generateConsumerXmlFile/queue_consumer.xml
+++ b/testData/actions/generation/generator/QueueConsumerGenerator/generateConsumerDbXmlFile/queue_consumer.xml
@@ -1,6 +1,6 @@
-
diff --git a/testData/project/magento2/vendor/magento/module-catalog-graph-ql/Model/Resolver/ImplementsBatchResolverInterface.php b/testData/project/magento2/vendor/magento/module-catalog-graph-ql/Model/Resolver/ImplementsBatchResolverInterface.php
index 0b099ae30..a5f0a14c8 100644
--- a/testData/project/magento2/vendor/magento/module-catalog-graph-ql/Model/Resolver/ImplementsBatchResolverInterface.php
+++ b/testData/project/magento2/vendor/magento/module-catalog-graph-ql/Model/Resolver/ImplementsBatchResolverInterface.php
@@ -3,7 +3,6 @@
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
-declare(strict_types=1);
namespace Magento\CatalogGraphQl\Model\Resolver;
diff --git a/testData/project/magento2/vendor/magento/module-catalog-graph-ql/Model/Resolver/ImplementsBatchServiceContractResolverInterface.php b/testData/project/magento2/vendor/magento/module-catalog-graph-ql/Model/Resolver/ImplementsBatchServiceContractResolverInterface.php
index 88de2502f..37f8002e3 100644
--- a/testData/project/magento2/vendor/magento/module-catalog-graph-ql/Model/Resolver/ImplementsBatchServiceContractResolverInterface.php
+++ b/testData/project/magento2/vendor/magento/module-catalog-graph-ql/Model/Resolver/ImplementsBatchServiceContractResolverInterface.php
@@ -3,7 +3,6 @@
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
-declare(strict_types=1);
namespace Magento\CatalogGraphQl\Model\Resolver;
diff --git a/testData/project/magento2/vendor/magento/module-catalog-graph-ql/Model/Resolver/ImplementsResolverInterface.php b/testData/project/magento2/vendor/magento/module-catalog-graph-ql/Model/Resolver/ImplementsResolverInterface.php
index 5a60d1009..1f2c0c018 100644
--- a/testData/project/magento2/vendor/magento/module-catalog-graph-ql/Model/Resolver/ImplementsResolverInterface.php
+++ b/testData/project/magento2/vendor/magento/module-catalog-graph-ql/Model/Resolver/ImplementsResolverInterface.php
@@ -3,7 +3,6 @@
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
-declare(strict_types=1);
namespace Magento\CatalogGraphQl\Model\Resolver;
diff --git a/tests/com/magento/idea/magento2plugin/actions/generation/generator/MessageQueueClassGeneratorTest.java b/tests/com/magento/idea/magento2plugin/actions/generation/generator/MessageQueueClassGeneratorTest.java
new file mode 100644
index 000000000..84cfc1d77
--- /dev/null
+++ b/tests/com/magento/idea/magento2plugin/actions/generation/generator/MessageQueueClassGeneratorTest.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright © Magento, Inc. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+package com.magento.idea.magento2plugin.actions.generation.generator;
+
+import com.intellij.openapi.project.Project;
+import com.intellij.psi.PsiFile;
+import com.magento.idea.magento2plugin.actions.generation.data.MessageQueueClassData;
+import com.magento.idea.magento2plugin.magento.files.MessageQueueClassPhp;
+
+public class MessageQueueClassGeneratorTest extends BaseGeneratorTestCase {
+ private static final String MODULE_NAME = "Foo_Bar";
+
+ private static final String HANDLER_EXPECTED_DIRECTORY = "src/app/code/Foo/Bar/Queue/Handler";
+ private static final String HANDLER_CLASS_NAME = "MyHandler";
+ private static final String HANDLER_NAMESPACE = "Foo\\Bar\\Queue\\Handler";
+ private static final String HANDLER_PATH = "Queue/Handler";
+ private static final String HANDLER_FQN = "\\Foo\\Bar\\Queue\\Handler\\MyHandler";
+
+ private static final String CONSUMER_EXPECTED_DIRECTORY = "src/app/code/Foo/Bar/Queue/Consumer";
+ private static final String CONSUMER_CLASS_NAME = "MyConsumer";
+ private static final String CONSUMER_NAMESPACE = "Foo\\Bar\\Queue\\Consumer";
+ private static final String CONSUMER_PATH = "Queue/Consumer";
+ private static final String CONSUMER_FQN = "\\Foo\\Bar\\Queue\\Handler\\MyConsumer";
+
+ /**
+ * Test handler class file generation.
+ */
+ public void testGenerateHandler() {
+ final Project project = myFixture.getProject();
+ final MessageQueueClassData messageQueueClassData = new MessageQueueClassData(
+ HANDLER_CLASS_NAME,
+ HANDLER_NAMESPACE,
+ HANDLER_PATH,
+ HANDLER_FQN,
+ MessageQueueClassPhp.Type.HANDLER
+ );
+ final MessageQueueClassGenerator generator;
+ generator = new MessageQueueClassGenerator(
+ messageQueueClassData,
+ MODULE_NAME,
+ project
+ );
+
+ final PsiFile messageQueue = generator.generate("test");
+ final String filePath = this.getFixturePath("MyHandler.php");
+ final PsiFile expectedFile = myFixture.configureByFile(filePath);
+
+ assertGeneratedFileIsCorrect(
+ expectedFile,
+ HANDLER_EXPECTED_DIRECTORY,
+ messageQueue
+ );
+ }
+
+ /**
+ * Test consumer class file generation.
+ */
+ public void testGenerateConsumer() {
+ final Project project = myFixture.getProject();
+ final MessageQueueClassData messageQueueClassData = new MessageQueueClassData(
+ CONSUMER_CLASS_NAME,
+ CONSUMER_NAMESPACE,
+ CONSUMER_PATH,
+ CONSUMER_FQN,
+ MessageQueueClassPhp.Type.CONSUMER
+ );
+ final MessageQueueClassGenerator generator;
+ generator = new MessageQueueClassGenerator(
+ messageQueueClassData,
+ MODULE_NAME,
+ project
+ );
+
+ final PsiFile messageQueue = generator.generate("test");
+ final String filePath = this.getFixturePath("MyConsumer.php");
+ final PsiFile expectedFile = myFixture.configureByFile(filePath);
+
+ assertGeneratedFileIsCorrect(
+ expectedFile,
+ CONSUMER_EXPECTED_DIRECTORY,
+ messageQueue
+ );
+ }
+}
diff --git a/tests/com/magento/idea/magento2plugin/actions/generation/generator/QueueConsumerGeneratorTest.java b/tests/com/magento/idea/magento2plugin/actions/generation/generator/QueueConsumerGeneratorTest.java
index 65613f482..7b2813ed2 100644
--- a/tests/com/magento/idea/magento2plugin/actions/generation/generator/QueueConsumerGeneratorTest.java
+++ b/tests/com/magento/idea/magento2plugin/actions/generation/generator/QueueConsumerGeneratorTest.java
@@ -16,14 +16,16 @@ public class QueueConsumerGeneratorTest extends BaseGeneratorTestCase {
private static final String QUEUE_NAME = "queue.name";
private static final String CONSUMER_TYPE = "Foo\\Bar\\Model\\Consumer";
private static final String MAX_MESSAGES = "100";
- private static final String CONNECTION_NAME = "amqp";
+ private static final String CONNECTION_AMPQ = "amqp";
+ private static final String CONNECTION_DB = "db";
private static final String MODULE_NAME = "Foo_Bar";
private static final String EXPECTED_DIRECTORY = "src/app/code/Foo/Bar/etc";
+ private static final String HANDLER = "Foo/Bar/Handler.php::execute";
/**
- * Tests for generation of queue_consumer.xml file.
+ * Tests for generation of queue_consumer.xml file for the DB connection type.
*/
- public void testGenerateConsumerXmlFile() {
+ public void testGenerateConsumerDbXmlFile() {
final String filePath = this.getFixturePath(QueueConsumerXml.fileName);
final PsiFile expectedFile = myFixture.configureByFile(filePath);
final Project project = myFixture.getProject();
@@ -34,8 +36,34 @@ public void testGenerateConsumerXmlFile() {
QUEUE_NAME,
CONSUMER_TYPE,
MAX_MESSAGES,
- CONNECTION_NAME,
- MODULE_NAME
+ CONNECTION_DB,
+ MODULE_NAME,
+ HANDLER
+ )
+ );
+
+ final PsiFile file = consumerGenerator.generate(NewMessageQueueAction.ACTION_NAME);
+
+ assertGeneratedFileIsCorrect(expectedFile, EXPECTED_DIRECTORY, file);
+ }
+
+ /**
+ * Tests for generation of queue_consumer.xml file for the AMPQ connection type.
+ */
+ public void testGenerateConsumerAmpqXmlFile() {
+ final String filePath = this.getFixturePath(QueueConsumerXml.fileName);
+ final PsiFile expectedFile = myFixture.configureByFile(filePath);
+ final Project project = myFixture.getProject();
+ final QueueConsumerGenerator consumerGenerator = new QueueConsumerGenerator(
+ project,
+ new QueueConsumerData(
+ CONSUMER_NAME,
+ QUEUE_NAME,
+ CONSUMER_TYPE,
+ MAX_MESSAGES,
+ CONNECTION_AMPQ,
+ MODULE_NAME,
+ HANDLER
)
);