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 @@ [![Version](http://phpstorm.espend.de/badge/8024/version)](https://plugins.jetbrains.com/plugin/8024) [![Downloads](http://phpstorm.espend.de/badge/8024/downloads)](https://plugins.jetbrains.com/plugin/8024) ![merge-chance-badge](https://img.shields.io/endpoint?url=https%3A%2F%2Fmerge-chance.info%2Fbadge%3Frepo%3Dmagento/magento2-phpstorm-plugin) +[![Made With Love](https://img.shields.io/badge/Made%20With-Love-orange.svg)](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 @@
- + - + - - + @@ -20,28 +19,6 @@ - - - - - - - - - - - - - - - - - - - - - - @@ -65,145 +42,128 @@ - + - + - + + - + - + - - - - - - - + - + - + - + - + - + + + - + - + - + + + - + + - + - + + + - - - + + + + - + - + + + - + - + - + - - - - - - - - - - - - - - - - - + - - - + - + + + - + - - - - - - - - - + + + - + - + - + - - - + - + + + - + - + - + - + - + @@ -214,7 +174,7 @@ - + @@ -252,6 +212,108 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 ) );