Skip to content

Commit bdd7baf

Browse files
Merge pull request #958 from bohdan-harniuk/861-context-dependent-actions
861: Developed context actions group, added generate routes.xml context action
2 parents 9237b26 + c9465c0 commit bdd7baf

File tree

13 files changed

+460
-21
lines changed

13 files changed

+460
-21
lines changed

resources/META-INF/plugin.xml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,15 @@
5656
<add-to-group group-id="PhpGenerateGroup" anchor="last"/>
5757
</group>
5858

59+
<group id="MagentoContextBasedActionsGroup" class="com.intellij.ide.actions.NonEmptyActionGroup" text="Context Actions" popup="false" compact="true" searchable="true">
60+
<separator/>
61+
<!-- Context dependent actions -->
62+
<action id="MagentoCreateRoutesFile" class="com.magento.idea.magento2plugin.actions.context.xml.NewRoutesXmlAction"/>
63+
<!-- Context dependent actions -->
64+
<separator/>
65+
<add-to-group group-id="NewGroup" anchor="before" relative-to-action="NewXml"/>
66+
</group>
67+
5968
<!-- Module file generators -->
6069
<group id="MagentoNewModuleFileGroup" class="com.magento.idea.magento2plugin.actions.groups.NewModuleFileGroup" text="Module File" popup="true">
6170
<action id="MagentoCreateEntity" class="com.magento.idea.magento2plugin.actions.generation.NewEntityAction" />
Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
<?xml version="1.0"?>
22
#parse("XML File Header.xml")
3-
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:App/etc/routes.xsd">
4-
<router id="${ROUTER_ID}">
3+
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:noNamespaceSchemaLocation="urn:magento:framework:App/etc/routes.xsd">
5+
<router id="${ROUTER_ID}">#if (${HAS_ROUTE_DATA})
6+
<route id="${ROUTE_ID}" frontName="${FRONT_NAME}">
7+
<module name="${MODULE_NAME}"/>
8+
</route>
9+
#end
510
</router>
611
</config>

resources/fileTemplates/internal/Magento Routes XML.xml.html

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,14 +30,43 @@
3030
<tr>
3131
<td valign="top"><nobr><font face="verdana" size="-2"><b>${ROUTER_ID}</b></font></nobr></td>
3232
<td width="10">&nbsp;</td>
33-
<td width="100%" valign="top"><font face="verdana" size="-1">specifies the name of the router in Magento.
33+
<td width="100%" valign="top"><font face="verdana" size="-1">Specifies the name of the router in Magento.
3434
See the reference tables in the
3535
<a href="https://devdocs.magento.com/guides/v2.4/extension-dev-guide/routing.html#router-class">
3636
Router class section
3737
</a>.
3838
</font>
3939
</td>
4040
</tr>
41+
<tr>
42+
<td valign="top"><nobr><font face="verdana" size="-2"><b>${HAS_ROUTE_DATA}</b></font></nobr></td>
43+
<td width="10">&nbsp;</td>
44+
<td width="100%" valign="top"><font face="verdana" size="-1">Technical value used to enable/disable route information rendering
45+
</font>
46+
</td>
47+
</tr>
48+
<tr>
49+
<td valign="top"><nobr><font face="verdana" size="-2"><b>${ROUTE_ID}</b></font></nobr></td>
50+
<td width="10">&nbsp;</td>Specifies the unique node id for this route in Magento,
51+
is also the first segment of its associated layout handle XML filename: routeId_controller_action.xml
52+
<td width="100%" valign="top"><font face="verdana" size="-1">
53+
</font>
54+
</td>
55+
</tr>
56+
<tr>
57+
<td valign="top"><nobr><font face="verdana" size="-2"><b>${FRONT_NAME}</b></font></nobr></td>
58+
<td width="10">&nbsp;</td>
59+
<td width="100%" valign="top"><font face="verdana" size="-1">Specifies the first segment after the base URL of a request
60+
</font>
61+
</td>
62+
</tr>
63+
<tr>
64+
<td valign="top"><nobr><font face="verdana" size="-2"><b>${MODULE_NAME}</b></font></nobr></td>
65+
<td width="10">&nbsp;</td>
66+
<td width="100%" valign="top"><font face="verdana" size="-1">Specifies the name of your module
67+
</font>
68+
</td>
69+
</tr>
4170
</table>
4271
</body>
43-
</html>
72+
</html>
Lines changed: 161 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,161 @@
1+
/*
2+
* Copyright © Magento, Inc. All rights reserved.
3+
* See COPYING.txt for license details.
4+
*/
5+
6+
package com.magento.idea.magento2plugin.actions.context;
7+
8+
import com.intellij.ide.fileTemplates.FileTemplate;
9+
import com.intellij.ide.fileTemplates.FileTemplateManager;
10+
import com.intellij.ide.fileTemplates.actions.AttributesDefaults;
11+
import com.intellij.ide.fileTemplates.actions.CreateFromTemplateActionBase;
12+
import com.intellij.openapi.actionSystem.AnActionEvent;
13+
import com.intellij.openapi.actionSystem.DataContext;
14+
import com.intellij.openapi.actionSystem.DataKey;
15+
import com.intellij.openapi.actionSystem.LangDataKeys;
16+
import com.intellij.openapi.actionSystem.impl.SimpleDataContext;
17+
import com.intellij.openapi.project.Project;
18+
import com.intellij.psi.PsiDirectory;
19+
import com.intellij.psi.PsiElement;
20+
import com.intellij.psi.PsiFile;
21+
import com.magento.idea.magento2plugin.MagentoIcons;
22+
import com.magento.idea.magento2plugin.magento.files.ModuleFileInterface;
23+
import com.magento.idea.magento2plugin.util.magento.GetMagentoModuleUtil;
24+
import org.jetbrains.annotations.NotNull;
25+
import org.jetbrains.annotations.Nullable;
26+
27+
public abstract class AbstractContextAction extends CreateFromTemplateActionBase {
28+
29+
private static final DataKey<AttributesDefaults> ATTRIBUTE_DEFAULTS = DataKey.create(
30+
"attribute.defaults"
31+
);
32+
private final ModuleFileInterface moduleFile;
33+
private DataContext customDataContext;
34+
35+
/**
36+
* Abstract context action constructor.
37+
*
38+
* @param title String
39+
* @param description String
40+
* @param moduleFile ModuleFileInterface
41+
*/
42+
public AbstractContextAction(
43+
final @NotNull String title,
44+
final @NotNull String description,
45+
final @NotNull ModuleFileInterface moduleFile
46+
) {
47+
super(title, description, MagentoIcons.MODULE);
48+
this.moduleFile = moduleFile;
49+
}
50+
51+
@Override
52+
public void update(final @NotNull AnActionEvent event) {
53+
event.getPresentation().setEnabled(false);
54+
event.getPresentation().setVisible(false);
55+
56+
final Project project = event.getProject();
57+
58+
if (project == null) {
59+
return;
60+
}
61+
final DataContext context = event.getDataContext();
62+
final PsiElement targetElement = LangDataKeys.PSI_ELEMENT.getData(context);
63+
64+
if (targetElement == null) {
65+
return;
66+
}
67+
PsiDirectory targetDirectory = null;
68+
PsiFile targetFile = null;
69+
70+
if (targetElement instanceof PsiDirectory) {
71+
targetDirectory = (PsiDirectory) targetElement;
72+
} else if (targetElement instanceof PsiFile) {
73+
targetFile = (PsiFile) targetElement;
74+
targetDirectory = targetFile.getContainingDirectory();
75+
}
76+
77+
if (targetDirectory == null) {
78+
return;
79+
}
80+
final GetMagentoModuleUtil.MagentoModuleData moduleData = GetMagentoModuleUtil
81+
.getByContext(targetDirectory, project);
82+
83+
if (moduleData == null
84+
|| moduleData.getName() == null
85+
|| !isVisible(moduleData, targetDirectory, targetFile)) {
86+
return;
87+
}
88+
customDataContext = SimpleDataContext
89+
.builder()
90+
.add(
91+
ATTRIBUTE_DEFAULTS,
92+
getProperties(
93+
new AttributesDefaults(),
94+
moduleData,
95+
targetDirectory,
96+
targetFile
97+
)
98+
)
99+
.build();
100+
101+
event.getPresentation().setEnabled(true);
102+
event.getPresentation().setVisible(true);
103+
}
104+
105+
/**
106+
* Implement check if an action should be shown in the context defined by the module,
107+
* target directory or target file.
108+
*
109+
* @param moduleData GetMagentoModuleUtil.MagentoModuleData
110+
* @param targetDirectory PsiDirectory
111+
* @param targetFile PsiFile
112+
*
113+
* @return boolean
114+
*/
115+
protected abstract boolean isVisible(
116+
final @NotNull GetMagentoModuleUtil.MagentoModuleData moduleData,
117+
final PsiDirectory targetDirectory,
118+
final PsiFile targetFile
119+
);
120+
121+
/**
122+
* Implement to populate used in the target template variables.
123+
*
124+
* @param defaults AttributesDefaults
125+
* @param moduleData GetMagentoModuleUtil.MagentoModuleData
126+
* @param targetDirectory PsiDirectory
127+
* @param targetFile PsiFile
128+
*
129+
* @return AttributesDefaults
130+
*/
131+
protected abstract AttributesDefaults getProperties(
132+
final @NotNull AttributesDefaults defaults,
133+
final @NotNull GetMagentoModuleUtil.MagentoModuleData moduleData,
134+
final PsiDirectory targetDirectory,
135+
final PsiFile targetFile
136+
);
137+
138+
@Override
139+
protected @Nullable AttributesDefaults getAttributesDefaults(
140+
final @NotNull DataContext dataContext
141+
) {
142+
return customDataContext.getData(ATTRIBUTE_DEFAULTS);
143+
}
144+
145+
@Override
146+
protected FileTemplate getTemplate(
147+
final @NotNull Project project,
148+
final @NotNull PsiDirectory directory
149+
) {
150+
final FileTemplateManager manager = FileTemplateManager.getInstance(project);
151+
final FileTemplate template = manager.findInternalTemplate(moduleFile.getTemplate());
152+
template.setFileName(moduleFile.getFileName());
153+
154+
return template;
155+
}
156+
157+
@Override
158+
public boolean isDumbAware() {
159+
return false;
160+
}
161+
}
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
/*
2+
* Copyright © Magento, Inc. All rights reserved.
3+
* See COPYING.txt for license details.
4+
*/
5+
6+
package com.magento.idea.magento2plugin.actions.context.xml;
7+
8+
import com.intellij.ide.fileTemplates.actions.AttributesDefaults;
9+
import com.intellij.psi.PsiDirectory;
10+
import com.intellij.psi.PsiFile;
11+
import com.magento.idea.magento2plugin.actions.context.AbstractContextAction;
12+
import com.magento.idea.magento2plugin.magento.files.RoutesXml;
13+
import com.magento.idea.magento2plugin.magento.packages.Areas;
14+
import com.magento.idea.magento2plugin.magento.packages.ComponentType;
15+
import com.magento.idea.magento2plugin.magento.packages.Package;
16+
import com.magento.idea.magento2plugin.util.magento.GetMagentoModuleUtil;
17+
import java.util.Arrays;
18+
import java.util.List;
19+
import org.jetbrains.annotations.NotNull;
20+
21+
public class NewRoutesXmlAction extends AbstractContextAction {
22+
23+
public static final String ACTION_NAME = "Magento 2 Routes File";
24+
public static final String ACTION_DESCRIPTION = "Create a new Magento 2 routes.xml file";
25+
26+
/**
27+
* New routes.xml file generation action constructor.
28+
*/
29+
public NewRoutesXmlAction() {
30+
super(ACTION_NAME, ACTION_DESCRIPTION, new RoutesXml());
31+
}
32+
33+
@Override
34+
protected boolean isVisible(
35+
final @NotNull GetMagentoModuleUtil.MagentoModuleData moduleData,
36+
final @NotNull PsiDirectory targetDirectory,
37+
final PsiFile targetFile
38+
) {
39+
final List<String> allowedDirectories = Arrays.asList(
40+
Package.moduleBaseAreaDir,
41+
Areas.adminhtml.toString(),
42+
Areas.frontend.toString()
43+
);
44+
45+
return allowedDirectories.contains(targetDirectory.getName())
46+
&& moduleData.getType().equals(ComponentType.module);
47+
}
48+
49+
@Override
50+
protected AttributesDefaults getProperties(
51+
final @NotNull AttributesDefaults defaults,
52+
final @NotNull GetMagentoModuleUtil.MagentoModuleData moduleData,
53+
final PsiDirectory targetDirectory,
54+
final PsiFile targetFile
55+
) {
56+
defaults.addPredefined("HAS_ROUTE_DATA", String.valueOf(true));
57+
defaults.addPredefined("MODULE_NAME", moduleData.getName());
58+
59+
if (Areas.adminhtml.toString().equals(targetDirectory.getName())) {
60+
defaults.addPredefined("ROUTER_ID", RoutesXml.ROUTER_ID_ADMIN);
61+
} else if (Package.moduleBaseAreaDir.equals(targetDirectory.getName())
62+
|| Areas.frontend.toString().equals(targetDirectory.getName())) {
63+
defaults.addPredefined("ROUTER_ID", RoutesXml.ROUTER_ID_STANDARD);
64+
}
65+
66+
return defaults;
67+
}
68+
}

src/com/magento/idea/magento2plugin/actions/generation/OverrideInThemeAction.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,13 @@
2121
import org.jetbrains.annotations.NotNull;
2222

2323
public class OverrideInThemeAction extends DumbAwareAction {
24-
public static String actionName = "Override this template in a project theme";
25-
public static String actionDescription = "Override in project theme";
24+
25+
public static final String ACTION_NAME = "Override this template in a project theme";
26+
public static final String ACTION_DESCRIPTION = "Override in project theme";
2627
private PsiFile psiFile;
2728

2829
public OverrideInThemeAction() {
29-
super(actionName, actionDescription, MagentoIcons.MODULE);
30+
super(ACTION_NAME, ACTION_DESCRIPTION, MagentoIcons.MODULE);
3031
}
3132

3233
/**

src/com/magento/idea/magento2plugin/actions/generation/dialog/OverrideInThemeDialog.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ public OverrideInThemeDialog(final @NotNull Project project, final PsiFile psiFi
5858

5959
setContentPane(contentPane);
6060
setModal(true);
61-
setTitle(OverrideInThemeAction.actionDescription);
61+
setTitle(OverrideInThemeAction.ACTION_DESCRIPTION);
6262
getRootPane().setDefaultButton(buttonOK);
6363
fillThemeOptions();
6464

src/com/magento/idea/magento2plugin/actions/generation/generator/RoutesXmlGenerator.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ public RoutesXmlGenerator(
4949
* @return PsiFile
5050
*/
5151
@Override
52+
@SuppressWarnings("PMD.CognitiveComplexity")
5253
public PsiFile generate(final String actionName) {
5354
final XmlFile routesXml = (XmlFile) findOrCreateRoutesXml.execute(
5455
actionName,
@@ -71,8 +72,8 @@ public PsiFile generate(final String actionName) {
7172
routerTag.setAttribute(
7273
"id",
7374
routesXmlData.getArea().equals(Areas.frontend.toString())
74-
? RoutesXml.routerIdStandart
75-
: RoutesXml.routerIdAdmin
75+
? RoutesXml.ROUTER_ID_STANDARD
76+
: RoutesXml.ROUTER_ID_ADMIN
7677
);
7778
}
7879
@NotNull final XmlTag[] buttonsTags = routerTag.findSubTags("route");

src/com/magento/idea/magento2plugin/actions/generation/generator/util/FindOrCreateRoutesXml.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,8 +73,8 @@ private Areas getArea(final String area) {
7373
private Properties getAttributes(final String area) {
7474
final Properties attributes = new Properties();
7575
attributes.setProperty("ROUTER_ID", area.equals(Areas.frontend.toString())
76-
? RoutesXml.routerIdStandart
77-
: RoutesXml.routerIdAdmin
76+
? RoutesXml.ROUTER_ID_STANDARD
77+
: RoutesXml.ROUTER_ID_ADMIN
7878
);
7979
return attributes;
8080
}

src/com/magento/idea/magento2plugin/magento/files/RoutesXml.java

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,19 +9,20 @@
99
import com.intellij.lang.xml.XMLLanguage;
1010

1111
public class RoutesXml implements ModuleFileInterface {
12-
public static String fileName = "routes.xml";
13-
public static String template = "Magento Routes XML";
14-
public static String routerIdStandart = "standart";
15-
public static String routerIdAdmin = "admin";
12+
13+
public static final String FILE_NAME = "routes.xml";
14+
public static final String TEMPLATE = "Magento Routes XML";
15+
public static final String ROUTER_ID_STANDARD = "standard";
16+
public static final String ROUTER_ID_ADMIN = "admin";
1617

1718
@Override
1819
public String getFileName() {
19-
return fileName;
20+
return FILE_NAME;
2021
}
2122

2223
@Override
2324
public String getTemplate() {
24-
return template;
25+
return TEMPLATE;
2526
}
2627

2728
@Override

0 commit comments

Comments
 (0)