-
Notifications
You must be signed in to change notification settings - Fork 105
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1200 from anzin/1139-add-generator-to-create-obse…
…rver-template 1139: Creating a new observer template
Showing
11 changed files
with
937 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
26 changes: 26 additions & 0 deletions
26
resources/fileTemplates/internal/Magento Module Observer File.php.ft
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
<?php | ||
#parse("PHP File Header.php") | ||
|
||
namespace ${NAMESPACE}; | ||
|
||
use Magento\Framework\Event\ObserverInterface; | ||
use Magento\Framework\Event\Observer; | ||
|
||
/** | ||
* Observes the `${EVENT_NAME}` event. | ||
*/ | ||
class ${CLASS_NAME} implements ObserverInterface | ||
{ | ||
/** | ||
* Observer for ${EVENT_NAME}. | ||
* | ||
* @param Observer $observer | ||
* | ||
* @return void | ||
*/ | ||
public function execute(Observer $observer) | ||
{ | ||
$event = $observer->getEvent(); | ||
// TODO: Implement observer method. | ||
} | ||
} |
49 changes: 49 additions & 0 deletions
49
resources/fileTemplates/internal/Magento Module Observer File.php.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
<!-- | ||
/* | ||
* Copyright © Magento, Inc. All rights reserved. | ||
* See COPYING.txt for license details. | ||
*/ | ||
--> | ||
<html> | ||
<body> | ||
<table width="100%" border="0" cellpadding="5" cellspacing="0" style="border-collapse: collapse"> | ||
<tr> | ||
<td> | ||
<font face="verdana" size="-1">Observers are a certain type of Magento class that can influence | ||
general behavior, performance, or change business logic. Observers are executed whenever the | ||
event they are configured to watch is dispatched by the event manager. | ||
<a href="https://devdocs.magento.com/guides/v2.3/extension-dev-guide/events-and-observers.html"> | ||
Read more</a> about observers. | ||
</font> | ||
</td> | ||
</tr> | ||
<tr> | ||
<td> | ||
<font face="verdana" size="-1">Check out the | ||
<a href="https://devdocs.magento.com/guides/v2.3/ext-best-practices/extension-coding/observers-bp.html"> | ||
Observers best practices</a> to have a clean and professional implementation.</font> | ||
</td> | ||
</tr> | ||
</table> | ||
<table width="100%" border="0" cellpadding="5" cellspacing="0" style="border-collapse: collapse"> | ||
<tr> | ||
<td colspan="3"><font face="verdana" size="-1">Predefined variables explanation:</font></td> | ||
</tr> | ||
<tr> | ||
<td valign="top"><nobr><font face="verdana" size="-2"><b>${NAMESPACE}</b></font></nobr></td> | ||
<td width="10"> </td> | ||
<td width="100%" valign="top"><font face="verdana" size="-1">Namespace for the class.</font></td> | ||
</tr> | ||
<tr> | ||
<td valign="top"><nobr><font face="verdana" size="-2"><b>${CLASS_NAME}</b></font></nobr></td> | ||
<td width="10"> </td> | ||
<td width="100%" valign="top"><font face="verdana" size="-1">Class name.</font></td> | ||
</tr> | ||
<tr> | ||
<td valign="top"><nobr><font face="verdana" size="-2"><b>${EVENT_NAME}</b></font></nobr></td> | ||
<td width="10"> </td> | ||
<td width="100%" valign="top"><font face="verdana" size="-1">The name of the observer for the event definition.</font></td> | ||
</tr> | ||
</table> | ||
</body> | ||
</html> |
62 changes: 62 additions & 0 deletions
62
src/com/magento/idea/magento2plugin/actions/context/php/NewObserverAction.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
/* | ||
* Copyright © Magento, Inc. All rights reserved. | ||
* See COPYING.txt for license details. | ||
*/ | ||
|
||
package com.magento.idea.magento2plugin.actions.context.php; | ||
|
||
import com.intellij.openapi.actionSystem.AnActionEvent; | ||
import com.intellij.psi.PsiDirectory; | ||
import com.intellij.psi.PsiFile; | ||
import com.magento.idea.magento2plugin.actions.context.CustomGeneratorContextAction; | ||
import com.magento.idea.magento2plugin.actions.generation.dialog.NewObserverDialog; | ||
import com.magento.idea.magento2plugin.magento.packages.ComponentType; | ||
import com.magento.idea.magento2plugin.magento.packages.Package; | ||
import com.magento.idea.magento2plugin.util.magento.GetMagentoModuleUtil; | ||
import org.jetbrains.annotations.NotNull; | ||
|
||
public class NewObserverAction extends CustomGeneratorContextAction { | ||
|
||
public static final String ACTION_NAME = "Magento 2 Observer"; | ||
public static final String ACTION_DESCRIPTION = "Create a new Magento 2 Observer"; | ||
public static final String ROOT_DIRECTORY = "Observer"; | ||
|
||
public NewObserverAction() { | ||
super(ACTION_NAME, ACTION_DESCRIPTION); | ||
} | ||
|
||
@Override | ||
public void actionPerformed(final @NotNull AnActionEvent event) { | ||
final GetMagentoModuleUtil.MagentoModuleData moduleData = getModuleData(); | ||
|
||
if (event.getProject() == null || moduleData == null || getDirectory() == null) { | ||
return; | ||
} | ||
final String[] templateData = moduleData.getName().split(Package.vendorModuleNameSeparator); | ||
|
||
if (templateData.length != 2) { //NOPMD | ||
return; | ||
} | ||
|
||
NewObserverDialog.open( | ||
event.getProject(), | ||
getDirectory(), | ||
templateData[0], | ||
templateData[1] | ||
); | ||
} | ||
|
||
@Override | ||
protected boolean isVisible( | ||
final @NotNull GetMagentoModuleUtil.MagentoModuleData moduleData, | ||
final PsiDirectory targetDirectory, | ||
final PsiFile targetFile | ||
) { | ||
if (!moduleData.getType().equals(ComponentType.module) | ||
|| !moduleData.getModuleDir().equals(targetDirectory.getParentDirectory())) { | ||
return false; | ||
} | ||
|
||
return ROOT_DIRECTORY.equals(targetDirectory.getName()); | ||
} | ||
} |
69 changes: 69 additions & 0 deletions
69
src/com/magento/idea/magento2plugin/actions/generation/ModuleObserverData.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
/* | ||
* Copyright © Magento, Inc. All rights reserved. | ||
* See COPYING.txt for license details. | ||
*/ | ||
|
||
package com.magento.idea.magento2plugin.actions.generation; | ||
|
||
import com.intellij.psi.PsiDirectory; | ||
import org.jetbrains.annotations.NotNull; | ||
|
||
public class ModuleObserverData { | ||
|
||
private final String packageName; | ||
private final String moduleName; | ||
private final String classFqn; | ||
private final String evenName; | ||
private final PsiDirectory baseDir; | ||
private final String className; | ||
|
||
/** | ||
* Constructor. | ||
* | ||
* @param packageName String | ||
* @param moduleName String | ||
* @param classFqn String | ||
* @param evenName String | ||
* @param baseDir PsiDirectory | ||
* @param className PsiDirectory | ||
*/ | ||
public ModuleObserverData( | ||
final @NotNull String packageName, | ||
final @NotNull String moduleName, | ||
final @NotNull String classFqn, | ||
final @NotNull String evenName, | ||
final @NotNull PsiDirectory baseDir, | ||
final @NotNull String className | ||
) { | ||
this.packageName = packageName; | ||
this.moduleName = moduleName; | ||
this.classFqn = classFqn; | ||
this.evenName = evenName; | ||
this.baseDir = baseDir; | ||
this.className = className; | ||
} | ||
|
||
public @NotNull String getPackageName() { | ||
return packageName; | ||
} | ||
|
||
public @NotNull String getModuleName() { | ||
return moduleName; | ||
} | ||
|
||
public @NotNull String getClassFqn() { | ||
return classFqn; | ||
} | ||
|
||
public @NotNull PsiDirectory getBaseDir() { | ||
return baseDir; | ||
} | ||
|
||
public @NotNull String getClassName() { | ||
return className; | ||
} | ||
|
||
public @NotNull String getEventName() { | ||
return evenName; | ||
} | ||
} |
184 changes: 184 additions & 0 deletions
184
src/com/magento/idea/magento2plugin/actions/generation/dialog/NewObserverDialog.form
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,184 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="com.magento.idea.magento2plugin.actions.generation.dialog.NewObserverDialog"> | ||
<grid id="1871d" binding="contentPanel" layout-manager="GridLayoutManager" row-count="3" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1"> | ||
<margin top="10" left="10" bottom="10" right="10"/> | ||
<constraints> | ||
<xy x="71" y="78" width="648" height="361"/> | ||
</constraints> | ||
<properties> | ||
<opaque value="true"/> | ||
<preferredSize width="420" height="280"/> | ||
<requestFocusEnabled value="true"/> | ||
</properties> | ||
<border type="none"/> | ||
<children> | ||
<grid id="9ad5" layout-manager="GridLayoutManager" row-count="1" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1"> | ||
<margin top="0" left="0" bottom="0" right="0"/> | ||
<constraints> | ||
<grid row="2" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/> | ||
</constraints> | ||
<properties/> | ||
<border type="none"/> | ||
<children> | ||
<hspacer id="4aa6d"> | ||
<constraints> | ||
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="1" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/> | ||
</constraints> | ||
</hspacer> | ||
<grid id="f892c" layout-manager="GridLayoutManager" row-count="1" column-count="2" same-size-horizontally="true" same-size-vertically="false" hgap="-1" vgap="-1"> | ||
<margin top="0" left="0" bottom="0" right="0"/> | ||
<constraints> | ||
<grid row="0" column="1" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/> | ||
</constraints> | ||
<properties/> | ||
<border type="none"/> | ||
<children> | ||
<component id="1b860" class="javax.swing.JButton" binding="buttonCancel"> | ||
<constraints> | ||
<grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/> | ||
</constraints> | ||
<properties> | ||
<text resource-bundle="magento2/common" key="common.cancel"/> | ||
</properties> | ||
</component> | ||
<component id="20801" class="javax.swing.JButton" binding="buttonOK"> | ||
<constraints> | ||
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/> | ||
</constraints> | ||
<properties> | ||
<text resource-bundle="magento2/common" key="common.ok"/> | ||
</properties> | ||
</component> | ||
</children> | ||
</grid> | ||
</children> | ||
</grid> | ||
<grid id="ad0b1" layout-manager="GridLayoutManager" row-count="8" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1"> | ||
<margin top="0" left="0" bottom="0" right="0"/> | ||
<constraints> | ||
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/> | ||
</constraints> | ||
<properties> | ||
<toolTipText value=""/> | ||
</properties> | ||
<border type="none"/> | ||
<children> | ||
<component id="96659" class="javax.swing.JLabel" binding="directoryStructureLabel"> | ||
<constraints> | ||
<grid row="4" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/> | ||
</constraints> | ||
<properties> | ||
<text value="Directory Path"/> | ||
</properties> | ||
</component> | ||
<component id="58ad9" class="javax.swing.JLabel" binding="evenNamesLabel"> | ||
<constraints> | ||
<grid row="7" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/> | ||
</constraints> | ||
<properties> | ||
<text value="Observer Even Name"/> | ||
</properties> | ||
</component> | ||
<component id="be834" class="javax.swing.JLabel" binding="directoryStructureErrorMessage"> | ||
<constraints> | ||
<grid row="5" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/> | ||
</constraints> | ||
<properties> | ||
<text value=""/> | ||
</properties> | ||
</component> | ||
<component id="f2094" class="javax.swing.JTextField" binding="directoryStructure"> | ||
<constraints> | ||
<grid row="4" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false"> | ||
<preferred-size width="150" height="-1"/> | ||
</grid> | ||
</constraints> | ||
<properties> | ||
<editable value="true"/> | ||
<horizontalAlignment value="2"/> | ||
<text value=""/> | ||
<toolTipText value=""/> | ||
</properties> | ||
</component> | ||
<component id="12752" class="com.magento.idea.magento2plugin.ui.FilteredComboBox" binding="eventName" custom-create="true"> | ||
<constraints> | ||
<grid row="7" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="2" anchor="8" fill="1" indent="0" use-parent-layout="false"> | ||
<preferred-size width="150" height="-1"/> | ||
</grid> | ||
</constraints> | ||
<properties/> | ||
</component> | ||
<component id="e9631" class="javax.swing.JLabel" binding="targetAreaLabel"> | ||
<constraints> | ||
<grid row="6" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/> | ||
</constraints> | ||
<properties> | ||
<text value="Target Area"/> | ||
</properties> | ||
</component> | ||
<component id="ec3f4" class="javax.swing.JComboBox" binding="observerArea" custom-create="true"> | ||
<constraints> | ||
<grid row="6" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="2" anchor="8" fill="1" indent="0" use-parent-layout="false"> | ||
<preferred-size width="150" height="-1"/> | ||
</grid> | ||
</constraints> | ||
<properties/> | ||
</component> | ||
<component id="292c" class="javax.swing.JTextField" binding="className"> | ||
<constraints> | ||
<grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false"> | ||
<preferred-size width="150" height="-1"/> | ||
</grid> | ||
</constraints> | ||
<properties/> | ||
</component> | ||
<component id="ffc6e" class="javax.swing.JTextField" binding="observerName"> | ||
<constraints> | ||
<grid row="2" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false"> | ||
<preferred-size width="150" height="-1"/> | ||
</grid> | ||
</constraints> | ||
<properties/> | ||
</component> | ||
<component id="2c31c" class="javax.swing.JLabel" binding="observerNameLabel"> | ||
<constraints> | ||
<grid row="2" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/> | ||
</constraints> | ||
<properties> | ||
<text value="Observer Name"/> | ||
</properties> | ||
</component> | ||
<component id="662ad" class="javax.swing.JLabel" binding="classNameLabel"> | ||
<constraints> | ||
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/> | ||
</constraints> | ||
<properties> | ||
<text value="Class Name"/> | ||
</properties> | ||
</component> | ||
<component id="5ad39" class="javax.swing.JLabel" binding="observerNameErrorMessage"> | ||
<constraints> | ||
<grid row="3" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/> | ||
</constraints> | ||
<properties> | ||
<text value=""/> | ||
</properties> | ||
</component> | ||
<component id="d30e2" class="javax.swing.JLabel" binding="classNameErrorMessage"> | ||
<constraints> | ||
<grid row="1" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/> | ||
</constraints> | ||
<properties> | ||
<text value=""/> | ||
</properties> | ||
</component> | ||
</children> | ||
</grid> | ||
<vspacer id="ec33f"> | ||
<constraints> | ||
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/> | ||
</constraints> | ||
</vspacer> | ||
</children> | ||
</grid> | ||
</form> |
355 changes: 355 additions & 0 deletions
355
src/com/magento/idea/magento2plugin/actions/generation/dialog/NewObserverDialog.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,355 @@ | ||
/* | ||
* Copyright © Magento, Inc. All rights reserved. | ||
* See COPYING.txt for license details. | ||
*/ | ||
|
||
package com.magento.idea.magento2plugin.actions.generation.dialog; | ||
|
||
import com.intellij.openapi.project.Project; | ||
import com.intellij.openapi.ui.ComboBox; | ||
import com.intellij.openapi.vfs.VirtualFile; | ||
import com.intellij.psi.PsiDirectory; | ||
import com.intellij.psi.PsiFile; | ||
import com.intellij.psi.search.GlobalSearchScope; | ||
import com.intellij.ui.DocumentAdapter; | ||
import com.intellij.util.indexing.FileBasedIndex; | ||
import com.magento.idea.magento2plugin.actions.context.php.NewObserverAction; | ||
import com.magento.idea.magento2plugin.actions.generation.ModuleObserverData; | ||
import com.magento.idea.magento2plugin.actions.generation.data.ObserverEventsXmlData; | ||
import com.magento.idea.magento2plugin.actions.generation.data.ui.ComboBoxItemData; | ||
import com.magento.idea.magento2plugin.actions.generation.dialog.validator.annotation.FieldValidation; | ||
import com.magento.idea.magento2plugin.actions.generation.dialog.validator.annotation.RuleRegistry; | ||
import com.magento.idea.magento2plugin.actions.generation.dialog.validator.rule.DirectoryRule; | ||
import com.magento.idea.magento2plugin.actions.generation.dialog.validator.rule.IdentifierWithColonRule; | ||
import com.magento.idea.magento2plugin.actions.generation.dialog.validator.rule.NotEmptyRule; | ||
import com.magento.idea.magento2plugin.actions.generation.dialog.validator.rule.PhpClassRule; | ||
import com.magento.idea.magento2plugin.actions.generation.generator.ModuleObserverGenerator; | ||
import com.magento.idea.magento2plugin.actions.generation.generator.ObserverEventsXmlGenerator; | ||
import com.magento.idea.magento2plugin.actions.generation.generator.util.DirectoryGenerator; | ||
import com.magento.idea.magento2plugin.lang.roots.MagentoTestSourceFilter; | ||
import com.magento.idea.magento2plugin.magento.files.ModuleObserverFile; | ||
import com.magento.idea.magento2plugin.magento.packages.Areas; | ||
import com.magento.idea.magento2plugin.magento.packages.Package; | ||
import com.magento.idea.magento2plugin.stubs.indexes.EventNameIndex; | ||
import com.magento.idea.magento2plugin.ui.FilteredComboBox; | ||
import com.magento.idea.magento2plugin.util.CamelCaseToSnakeCase; | ||
import java.awt.event.ActionEvent; | ||
import java.awt.event.KeyEvent; | ||
import java.awt.event.WindowAdapter; | ||
import java.awt.event.WindowEvent; | ||
import java.util.ArrayList; | ||
import java.util.Collection; | ||
import java.util.List; | ||
import java.util.Locale; | ||
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.ExcessiveImports", | ||
"PMD.AvoidInstantiatingObjectsInLoops", | ||
"PMD.ReturnEmptyCollectionRatherThanNull" | ||
}) | ||
public class NewObserverDialog extends AbstractDialog { | ||
|
||
private static final String OBSERVER_NAME = "Observer Name"; | ||
private static final String CLASS_NAME = "Class Name"; | ||
private final Project project; | ||
private final PsiDirectory baseDir; | ||
private final String moduleName; | ||
private final String modulePackage; | ||
private JPanel contentPanel; | ||
private JButton buttonOK; | ||
private JButton buttonCancel; | ||
|
||
@FieldValidation(rule = RuleRegistry.NOT_EMPTY, | ||
message = {NotEmptyRule.MESSAGE, OBSERVER_NAME}) | ||
@FieldValidation(rule = RuleRegistry.IDENTIFIER_WITH_COLON, | ||
message = {IdentifierWithColonRule.MESSAGE, OBSERVER_NAME}) | ||
private JTextField observerName; | ||
@FieldValidation(rule = RuleRegistry.NOT_EMPTY, | ||
message = {NotEmptyRule.MESSAGE, CLASS_NAME}) | ||
@FieldValidation(rule = RuleRegistry.PHP_CLASS, | ||
message = {PhpClassRule.MESSAGE, CLASS_NAME}) | ||
private JTextField className; | ||
private JTextField directoryStructure; | ||
private FilteredComboBox eventName; | ||
private JComboBox<ComboBoxItemData> observerArea; | ||
private JLabel observerNameLabel;// NOPMD | ||
private JLabel observerNameErrorMessage;// NOPMD | ||
private JLabel classNameLabel;// NOPMD | ||
private JLabel classNameErrorMessage;// NOPMD | ||
private JLabel directoryStructureLabel;// NOPMD | ||
private JLabel directoryStructureErrorMessage;// NOPMD | ||
private JLabel evenNamesLabel;// NOPMD | ||
private JLabel targetAreaLabel;// NOPMD | ||
|
||
/** | ||
* Constructor. | ||
* | ||
* @param project Project | ||
* @param directory PsiDirectory | ||
* @param modulePackage String | ||
* @param moduleName String | ||
*/ | ||
public NewObserverDialog( | ||
final Project project, | ||
final PsiDirectory directory, | ||
final String modulePackage, | ||
final String moduleName | ||
) { | ||
super(); | ||
|
||
this.project = project; | ||
this.baseDir = directory; | ||
this.modulePackage = modulePackage; | ||
this.moduleName = moduleName; | ||
|
||
setContentPane(contentPanel); | ||
setModal(true); | ||
setTitle(NewObserverAction.ACTION_DESCRIPTION); | ||
getRootPane().setDefaultButton(buttonOK); | ||
|
||
buttonOK.addActionListener((final ActionEvent event) -> onOK()); | ||
buttonCancel.addActionListener((final ActionEvent event) -> onCancel()); | ||
|
||
// call onCancel() when cross is clicked | ||
setDefaultCloseOperation(DO_NOTHING_ON_CLOSE); | ||
addWindowListener(new WindowAdapter() { | ||
@Override | ||
public void windowClosing(final WindowEvent event) { | ||
onCancel(); | ||
} | ||
}); | ||
|
||
// call onCancel() on ESCAPE | ||
contentPanel.registerKeyboardAction( | ||
(final ActionEvent event) -> onCancel(), | ||
KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), | ||
JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT | ||
); | ||
|
||
className.getDocument().addDocumentListener(new DocumentAdapter() { | ||
@SuppressWarnings("PMD.AccessorMethodGeneration") | ||
@Override | ||
public void textChanged(final @NotNull DocumentEvent event) { | ||
autoCompleteObserverName(); | ||
} | ||
}); | ||
|
||
addComponentListener( | ||
new FocusOnAFieldListener(() -> className.requestFocusInWindow()) | ||
); | ||
} | ||
|
||
/** | ||
* Open dialog. | ||
* | ||
* @param project Project | ||
* @param directory PsiDirectory | ||
*/ | ||
public static void open( | ||
final Project project, | ||
final PsiDirectory directory, | ||
final String modulePackage, | ||
final String moduleName | ||
) { | ||
final NewObserverDialog dialog = new NewObserverDialog( | ||
project, | ||
directory, | ||
modulePackage, | ||
moduleName | ||
); | ||
dialog.pack(); | ||
dialog.centerDialog(dialog); | ||
dialog.setVisible(true); | ||
} | ||
|
||
private String getModuleName() { | ||
return modulePackage.concat(Package.fqnSeparator).concat(moduleName); | ||
} | ||
|
||
public String getObserverName() { | ||
return observerName.getText().trim(); | ||
} | ||
|
||
public String getClassName() { | ||
return className.getText().trim(); | ||
} | ||
|
||
public String getEvenName() { | ||
return eventName.getSelectedItem().toString(); | ||
} | ||
|
||
public String getObserverArea() { | ||
return this.observerArea.getSelectedItem().toString(); | ||
} | ||
|
||
public String getDirectoryStructure() { | ||
return directoryStructure.getText().trim(); | ||
} | ||
|
||
protected void onOK() { | ||
if (validateFields()) { | ||
PsiDirectory observerDirectory = baseDir; | ||
|
||
if (!getDirectoryStructure().isEmpty()) { | ||
observerDirectory = DirectoryGenerator.getInstance().findOrCreateSubdirectories( | ||
baseDir, | ||
getDirectoryStructure() | ||
); | ||
} | ||
new ModuleObserverGenerator( | ||
new ModuleObserverData( | ||
modulePackage, | ||
moduleName, | ||
getObserverClassFqn(), | ||
getEvenName(), | ||
observerDirectory, | ||
ModuleObserverFile.resolveClassNameFromInput(getClassName()) | ||
), | ||
project | ||
).generate(NewObserverAction.ACTION_NAME, true); | ||
|
||
new ObserverEventsXmlGenerator( | ||
new ObserverEventsXmlData( | ||
getObserverArea(), | ||
getModuleName().replace( | ||
Package.fqnSeparator, | ||
Package.vendorModuleNameSeparator | ||
), | ||
getEvenName(), | ||
getObserverName(), | ||
getObserverClassFqn().concat(Package.fqnSeparator).concat( | ||
ModuleObserverFile.resolveClassNameFromInput(getClassName()) | ||
) | ||
), | ||
project | ||
).generate(NewObserverAction.ACTION_NAME); | ||
exit(); | ||
} | ||
} | ||
|
||
private boolean validateFields() { | ||
final PsiFile[] directoryFiles = getDirectoryFiles(baseDir); | ||
|
||
if (directoryFiles != null) { | ||
for (final PsiFile file : directoryFiles) { | ||
final String className = ModuleObserverFile.resolveClassNameFromInput( | ||
getClassName() | ||
); | ||
if (file.getName().equals(className + ModuleObserverFile.EXTENSION)) { | ||
showErrorMessage( | ||
fieldsValidationsList.get(1).getField(), | ||
"Class name " + className + " already exist." | ||
); | ||
|
||
return false; | ||
} | ||
} | ||
} | ||
if (!getDirectoryStructure().isEmpty() | ||
&& !DirectoryRule.getInstance().check(getDirectoryStructure()) | ||
) { | ||
showErrorMessage( | ||
this.getClass().getDeclaredFields()[11], | ||
"The Directory Path field does not contain a valid directory." | ||
); | ||
|
||
return false; | ||
} | ||
|
||
return validateFormFields(); | ||
} | ||
|
||
private PsiFile[] getDirectoryFiles(final PsiDirectory targetDirectory) { | ||
PsiDirectory directory = targetDirectory; | ||
|
||
if (!getDirectoryStructure().isEmpty()) { | ||
final String[] directories = getDirectoryStructure().split(Package.V_FILE_SEPARATOR); | ||
|
||
for (final String dir : directories) { | ||
final PsiDirectory subdirectory = directory.findSubdirectory(dir); | ||
|
||
if (subdirectory == null) { | ||
return null; | ||
} | ||
|
||
directory = subdirectory; | ||
} | ||
} | ||
|
||
return directory.getFiles(); | ||
} | ||
|
||
private String getObserverClassFqn() { | ||
final String folderStructureFqn = getDirectoryStructure().replace( | ||
Package.V_FILE_SEPARATOR, Package.fqnSeparator | ||
); | ||
String folderFqn = NewObserverAction.ROOT_DIRECTORY; | ||
|
||
if (!folderStructureFqn.isEmpty()) { | ||
folderFqn = folderFqn.concat(Package.fqnSeparator).concat(folderStructureFqn); | ||
} | ||
|
||
return getModuleName().concat(Package.fqnSeparator).concat(folderFqn); | ||
} | ||
|
||
private void autoCompleteObserverName() { | ||
final String className = getClassName(); | ||
|
||
if (className.isEmpty()) { | ||
return; | ||
} | ||
final String modifiedClassName = ModuleObserverFile.resolveClassNameFromInput(className); | ||
final String classNameInSnakeCase = CamelCaseToSnakeCase.getInstance() | ||
.convert(modifiedClassName); | ||
|
||
final String modulePackageModified = modulePackage.substring(0, 1) | ||
.toLowerCase(Locale.getDefault()) + modulePackage.substring(1); | ||
final String moduleNameModified = moduleName.substring(0, 1) | ||
.toLowerCase(Locale.getDefault()) + moduleName.substring(1); | ||
|
||
observerName.setText( | ||
modulePackageModified + "_" + moduleNameModified + "_" + classNameInSnakeCase | ||
); | ||
} | ||
|
||
@SuppressWarnings({"PMD.UnusedPrivateMethod"}) | ||
private void createUIComponents() { | ||
observerArea = new ComboBox<>(); | ||
|
||
for (final Areas areaEntry : Areas.values()) { | ||
observerArea.addItem(new ComboBoxItemData(areaEntry.toString(), areaEntry.toString())); | ||
} | ||
final Collection<String> events = FileBasedIndex.getInstance().getAllKeys( | ||
EventNameIndex.KEY, project | ||
); | ||
// Filter all events declared only for tests. | ||
events.removeIf(event -> { | ||
final Collection<VirtualFile> files = FileBasedIndex.getInstance() | ||
.getContainingFiles( | ||
EventNameIndex.KEY, | ||
event, | ||
GlobalSearchScope.allScope(project) | ||
); | ||
final List<VirtualFile> realObservers = new ArrayList<>(); | ||
|
||
for (final VirtualFile file : files) { | ||
if (!MagentoTestSourceFilter.isTestSources(file, project)) { | ||
realObservers.add(file); | ||
} | ||
} | ||
|
||
return realObservers.isEmpty(); | ||
}); | ||
this.eventName = new FilteredComboBox(new ArrayList<>(events)); | ||
} | ||
} |
66 changes: 66 additions & 0 deletions
66
...com/magento/idea/magento2plugin/actions/generation/generator/ModuleObserverGenerator.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
/* | ||
* 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.ModuleObserverData; | ||
import com.magento.idea.magento2plugin.actions.generation.generator.util.FileFromTemplateGenerator; | ||
import com.magento.idea.magento2plugin.magento.files.ModuleObserverFile; | ||
import java.util.Properties; | ||
import org.jetbrains.annotations.NotNull; | ||
|
||
public class ModuleObserverGenerator extends FileGenerator { | ||
|
||
private final ModuleObserverData moduleObserverData; | ||
private final FileFromTemplateGenerator fileFromTemplateGenerator; | ||
|
||
/** | ||
* Construct generator. | ||
* | ||
* @param moduleObserverData ModuleObserverData | ||
* @param project Project | ||
*/ | ||
public ModuleObserverGenerator( | ||
final @NotNull ModuleObserverData moduleObserverData, | ||
final Project project | ||
) { | ||
super(project); | ||
this.moduleObserverData = moduleObserverData; | ||
this.fileFromTemplateGenerator = new FileFromTemplateGenerator(project); | ||
} | ||
|
||
/** | ||
* Generate file. | ||
* | ||
* @param actionName String | ||
* | ||
* @return PsiFile | ||
*/ | ||
@Override | ||
public PsiFile generate(final String actionName) { | ||
return fileFromTemplateGenerator.generate( | ||
new ModuleObserverFile(moduleObserverData.getClassName()), | ||
getAttributes(), | ||
moduleObserverData.getBaseDir(), | ||
actionName | ||
); | ||
} | ||
|
||
/** | ||
* Fill template properties. | ||
* | ||
* @param attributes Properties | ||
*/ | ||
@Override | ||
protected void fillAttributes(final Properties attributes) { | ||
attributes.setProperty("CLASS_NAME", ModuleObserverFile.resolveClassNameFromInput( | ||
moduleObserverData.getClassName() | ||
)); | ||
attributes.setProperty("NAMESPACE", moduleObserverData.getClassFqn()); | ||
attributes.setProperty("EVENT_NAME", moduleObserverData.getEventName()); | ||
} | ||
} |
59 changes: 59 additions & 0 deletions
59
src/com/magento/idea/magento2plugin/magento/files/ModuleObserverFile.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
/* | ||
* 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; | ||
import org.jetbrains.annotations.NotNull; | ||
|
||
public class ModuleObserverFile implements ModuleFileInterface { | ||
|
||
public static final String FILE_SUFFIX = "Observer"; | ||
public static final String EXTENSION = ".php"; | ||
public static final String TEMPLATE = "Magento Module Observer File"; | ||
private final String className; | ||
|
||
public ModuleObserverFile( | ||
final @NotNull String className | ||
) { | ||
this.className = resolveClassNameFromInput(className); | ||
} | ||
|
||
/** | ||
* Resolve class name from user input. | ||
* | ||
* @param input String | ||
* | ||
* @return String | ||
*/ | ||
public static String resolveClassNameFromInput(final String input) { | ||
if (input.length() <= FILE_SUFFIX.length()) { | ||
return input + FILE_SUFFIX; | ||
} | ||
final String suffix = input.substring(input.length() - FILE_SUFFIX.length()); | ||
|
||
if (FILE_SUFFIX.equals(suffix)) { | ||
return input; | ||
} else { | ||
return input + FILE_SUFFIX; | ||
} | ||
} | ||
|
||
@Override | ||
public String getFileName() { | ||
return className + EXTENSION; | ||
} | ||
|
||
@Override | ||
public String getTemplate() { | ||
return TEMPLATE; | ||
} | ||
|
||
@Override | ||
public Language getLanguage() { | ||
return PhpLanguage.INSTANCE; | ||
} | ||
} |
25 changes: 25 additions & 0 deletions
25
...ration/generator/ModuleObserverGenerator/generateModuleObserverFile/TestClassObserver.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
<?php | ||
|
||
namespace Foo\Bar\Observer; | ||
|
||
use Magento\Framework\Event\ObserverInterface; | ||
use Magento\Framework\Event\Observer; | ||
|
||
/** | ||
* Observes the `test_event_name` event. | ||
*/ | ||
class TestClassObserver implements ObserverInterface | ||
{ | ||
/** | ||
* Observer for test_event_name. | ||
* | ||
* @param Observer $observer | ||
* | ||
* @return void | ||
*/ | ||
public function execute(Observer $observer) | ||
{ | ||
$event = $observer->getEvent(); | ||
// TODO: Implement observer method. | ||
} | ||
} |
41 changes: 41 additions & 0 deletions
41
...magento/idea/magento2plugin/actions/generation/generator/ModuleObserverGeneratorTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
/* | ||
* Copyright © Magento, Inc. All rights reserved. | ||
* See COPYING.txt for license details. | ||
*/ | ||
|
||
package com.magento.idea.magento2plugin.actions.generation.generator; | ||
|
||
import com.intellij.psi.PsiFile; | ||
import com.magento.idea.magento2plugin.actions.generation.ModuleObserverData; | ||
import com.magento.idea.magento2plugin.magento.files.ModuleObserverFile; | ||
|
||
public final class ModuleObserverGeneratorTest extends BaseGeneratorTestCase { | ||
|
||
private static final String CLASS_NAME = "TestClassObserver"; | ||
|
||
/** | ||
* Test module README.md file generation. | ||
*/ | ||
public void testGenerateModuleObserverFile() { | ||
final PsiFile expectedFile = myFixture.configureByFile( | ||
getFixturePath(CLASS_NAME + ModuleObserverFile.EXTENSION) | ||
); | ||
final ModuleObserverGenerator generator = new ModuleObserverGenerator( | ||
new ModuleObserverData( | ||
"Foo", | ||
"Bar", | ||
"Foo\\Bar\\Observer", | ||
"test_event_name", | ||
getProjectDirectory(), | ||
CLASS_NAME | ||
), | ||
myFixture.getProject() | ||
); | ||
final PsiFile generatedFile = generator.generate("test"); | ||
|
||
assertGeneratedFileIsCorrect( | ||
expectedFile, | ||
generatedFile | ||
); | ||
} | ||
} |