Skip to content

861: Developed context actions group, added generate routes.xml context action #958

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions resources/META-INF/plugin.xml
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,15 @@
<add-to-group group-id="PhpGenerateGroup" anchor="last"/>
</group>

<group id="MagentoContextBasedActionsGroup" class="com.intellij.ide.actions.NonEmptyActionGroup" text="Context Actions" popup="false" compact="true" searchable="true">
<separator/>
<!-- Context dependent actions -->
<action id="MagentoCreateRoutesFile" class="com.magento.idea.magento2plugin.actions.context.xml.NewRoutesXmlAction"/>
<!-- Context dependent actions -->
<separator/>
<add-to-group group-id="NewGroup" anchor="before" relative-to-action="NewXml"/>
</group>

<!-- Module file generators -->
<group id="MagentoNewModuleFileGroup" class="com.magento.idea.magento2plugin.actions.groups.NewModuleFileGroup" text="Module File" popup="true">
<action id="MagentoCreateEntity" class="com.magento.idea.magento2plugin.actions.generation.NewEntityAction" />
Expand Down
9 changes: 7 additions & 2 deletions resources/fileTemplates/internal/Magento Routes XML.xml.ft
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
<?xml version="1.0"?>
#parse("XML File Header.xml")
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:App/etc/routes.xsd">
<router id="${ROUTER_ID}">
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:framework:App/etc/routes.xsd">
<router id="${ROUTER_ID}">#if (${HAS_ROUTE_DATA})
<route id="${ROUTE_ID}" frontName="${FRONT_NAME}">
<module name="${MODULE_NAME}"/>
</route>
#end
</router>
</config>
33 changes: 31 additions & 2 deletions resources/fileTemplates/internal/Magento Routes XML.xml.html
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,43 @@
<tr>
<td valign="top"><nobr><font face="verdana" size="-2"><b>${ROUTER_ID}</b></font></nobr></td>
<td width="10">&nbsp;</td>
<td width="100%" valign="top"><font face="verdana" size="-1">specifies the name of the router in Magento.
<td width="100%" valign="top"><font face="verdana" size="-1">Specifies the name of the router in Magento.
See the reference tables in the
<a href="https://devdocs.magento.com/guides/v2.4/extension-dev-guide/routing.html#router-class">
Router class section
</a>.
</font>
</td>
</tr>
<tr>
<td valign="top"><nobr><font face="verdana" size="-2"><b>${HAS_ROUTE_DATA}</b></font></nobr></td>
<td width="10">&nbsp;</td>
<td width="100%" valign="top"><font face="verdana" size="-1">Technical value used to enable/disable route information rendering
</font>
</td>
</tr>
<tr>
<td valign="top"><nobr><font face="verdana" size="-2"><b>${ROUTE_ID}</b></font></nobr></td>
<td width="10">&nbsp;</td>Specifies the unique node id for this route in Magento,
is also the first segment of its associated layout handle XML filename: routeId_controller_action.xml
<td width="100%" valign="top"><font face="verdana" size="-1">
</font>
</td>
</tr>
<tr>
<td valign="top"><nobr><font face="verdana" size="-2"><b>${FRONT_NAME}</b></font></nobr></td>
<td width="10">&nbsp;</td>
<td width="100%" valign="top"><font face="verdana" size="-1">Specifies the first segment after the base URL of a request
</font>
</td>
</tr>
<tr>
<td valign="top"><nobr><font face="verdana" size="-2"><b>${MODULE_NAME}</b></font></nobr></td>
<td width="10">&nbsp;</td>
<td width="100%" valign="top"><font face="verdana" size="-1">Specifies the name of your module
</font>
</td>
</tr>
</table>
</body>
</html>
</html>
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
/*
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/

package com.magento.idea.magento2plugin.actions.context;

import com.intellij.ide.fileTemplates.FileTemplate;
import com.intellij.ide.fileTemplates.FileTemplateManager;
import com.intellij.ide.fileTemplates.actions.AttributesDefaults;
import com.intellij.ide.fileTemplates.actions.CreateFromTemplateActionBase;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.actionSystem.DataKey;
import com.intellij.openapi.actionSystem.LangDataKeys;
import com.intellij.openapi.actionSystem.impl.SimpleDataContext;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiDirectory;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.magento.idea.magento2plugin.MagentoIcons;
import com.magento.idea.magento2plugin.magento.files.ModuleFileInterface;
import com.magento.idea.magento2plugin.util.magento.GetMagentoModuleUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

public abstract class AbstractContextAction extends CreateFromTemplateActionBase {

private static final DataKey<AttributesDefaults> ATTRIBUTE_DEFAULTS = DataKey.create(
"attribute.defaults"
);
private final ModuleFileInterface moduleFile;
private DataContext customDataContext;

/**
* Abstract context action constructor.
*
* @param title String
* @param description String
* @param moduleFile ModuleFileInterface
*/
public AbstractContextAction(
final @NotNull String title,
final @NotNull String description,
final @NotNull ModuleFileInterface moduleFile
) {
super(title, description, MagentoIcons.MODULE);
this.moduleFile = moduleFile;
}

@Override
public void update(final @NotNull AnActionEvent event) {
event.getPresentation().setEnabled(false);
event.getPresentation().setVisible(false);

final Project project = event.getProject();

if (project == null) {
return;
}
final DataContext context = event.getDataContext();
final PsiElement targetElement = LangDataKeys.PSI_ELEMENT.getData(context);

if (targetElement == null) {
return;
}
PsiDirectory targetDirectory = null;
PsiFile targetFile = null;

if (targetElement instanceof PsiDirectory) {
targetDirectory = (PsiDirectory) targetElement;
} else if (targetElement instanceof PsiFile) {
targetFile = (PsiFile) targetElement;
targetDirectory = targetFile.getContainingDirectory();
}

if (targetDirectory == null) {
return;
}
final GetMagentoModuleUtil.MagentoModuleData moduleData = GetMagentoModuleUtil
.getByContext(targetDirectory, project);

if (moduleData == null
|| moduleData.getName() == null
|| !isVisible(moduleData, targetDirectory, targetFile)) {
return;
}
customDataContext = SimpleDataContext
.builder()
.add(
ATTRIBUTE_DEFAULTS,
getProperties(
new AttributesDefaults(),
moduleData,
targetDirectory,
targetFile
)
)
.build();

event.getPresentation().setEnabled(true);
event.getPresentation().setVisible(true);
}

/**
* Implement check if an action should be shown in the context defined by the module,
* target directory or target file.
*
* @param moduleData GetMagentoModuleUtil.MagentoModuleData
* @param targetDirectory PsiDirectory
* @param targetFile PsiFile
*
* @return boolean
*/
protected abstract boolean isVisible(
final @NotNull GetMagentoModuleUtil.MagentoModuleData moduleData,
final PsiDirectory targetDirectory,
final PsiFile targetFile
);

/**
* Implement to populate used in the target template variables.
*
* @param defaults AttributesDefaults
* @param moduleData GetMagentoModuleUtil.MagentoModuleData
* @param targetDirectory PsiDirectory
* @param targetFile PsiFile
*
* @return AttributesDefaults
*/
protected abstract AttributesDefaults getProperties(
final @NotNull AttributesDefaults defaults,
final @NotNull GetMagentoModuleUtil.MagentoModuleData moduleData,
final PsiDirectory targetDirectory,
final PsiFile targetFile
);

@Override
protected @Nullable AttributesDefaults getAttributesDefaults(
final @NotNull DataContext dataContext
) {
return customDataContext.getData(ATTRIBUTE_DEFAULTS);
}

@Override
protected FileTemplate getTemplate(
final @NotNull Project project,
final @NotNull PsiDirectory directory
) {
final FileTemplateManager manager = FileTemplateManager.getInstance(project);
final FileTemplate template = manager.findInternalTemplate(moduleFile.getTemplate());
template.setFileName(moduleFile.getFileName());

return template;
}

@Override
public boolean isDumbAware() {
return false;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
/*
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/

package com.magento.idea.magento2plugin.actions.context.xml;

import com.intellij.ide.fileTemplates.actions.AttributesDefaults;
import com.intellij.psi.PsiDirectory;
import com.intellij.psi.PsiFile;
import com.magento.idea.magento2plugin.actions.context.AbstractContextAction;
import com.magento.idea.magento2plugin.magento.files.RoutesXml;
import com.magento.idea.magento2plugin.magento.packages.Areas;
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 java.util.Arrays;
import java.util.List;
import org.jetbrains.annotations.NotNull;

public class NewRoutesXmlAction extends AbstractContextAction {

public static final String ACTION_NAME = "Magento 2 Routes File";
public static final String ACTION_DESCRIPTION = "Create a new Magento 2 routes.xml file";

/**
* New routes.xml file generation action constructor.
*/
public NewRoutesXmlAction() {
super(ACTION_NAME, ACTION_DESCRIPTION, new RoutesXml());
}

@Override
protected boolean isVisible(
final @NotNull GetMagentoModuleUtil.MagentoModuleData moduleData,
final @NotNull PsiDirectory targetDirectory,
final PsiFile targetFile
) {
final List<String> allowedDirectories = Arrays.asList(
Package.moduleBaseAreaDir,
Areas.adminhtml.toString(),
Areas.frontend.toString()
);

return allowedDirectories.contains(targetDirectory.getName())
&& moduleData.getType().equals(ComponentType.module);
}

@Override
protected AttributesDefaults getProperties(
final @NotNull AttributesDefaults defaults,
final @NotNull GetMagentoModuleUtil.MagentoModuleData moduleData,
final PsiDirectory targetDirectory,
final PsiFile targetFile
) {
defaults.addPredefined("HAS_ROUTE_DATA", String.valueOf(true));
defaults.addPredefined("MODULE_NAME", moduleData.getName());

if (Areas.adminhtml.toString().equals(targetDirectory.getName())) {
defaults.addPredefined("ROUTER_ID", RoutesXml.ROUTER_ID_ADMIN);
} else if (Package.moduleBaseAreaDir.equals(targetDirectory.getName())
|| Areas.frontend.toString().equals(targetDirectory.getName())) {
defaults.addPredefined("ROUTER_ID", RoutesXml.ROUTER_ID_STANDARD);
}

return defaults;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,13 @@
import org.jetbrains.annotations.NotNull;

public class OverrideInThemeAction extends DumbAwareAction {
public static String actionName = "Override this template in a project theme";
public static String actionDescription = "Override in project theme";

public static final String ACTION_NAME = "Override this template in a project theme";
public static final String ACTION_DESCRIPTION = "Override in project theme";
private PsiFile psiFile;

public OverrideInThemeAction() {
super(actionName, actionDescription, MagentoIcons.MODULE);
super(ACTION_NAME, ACTION_DESCRIPTION, MagentoIcons.MODULE);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ public OverrideInThemeDialog(final @NotNull Project project, final PsiFile psiFi

setContentPane(contentPane);
setModal(true);
setTitle(OverrideInThemeAction.actionDescription);
setTitle(OverrideInThemeAction.ACTION_DESCRIPTION);
getRootPane().setDefaultButton(buttonOK);
fillThemeOptions();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ public RoutesXmlGenerator(
* @return PsiFile
*/
@Override
@SuppressWarnings("PMD.CognitiveComplexity")
public PsiFile generate(final String actionName) {
final XmlFile routesXml = (XmlFile) findOrCreateRoutesXml.execute(
actionName,
Expand All @@ -71,8 +72,8 @@ public PsiFile generate(final String actionName) {
routerTag.setAttribute(
"id",
routesXmlData.getArea().equals(Areas.frontend.toString())
? RoutesXml.routerIdStandart
: RoutesXml.routerIdAdmin
? RoutesXml.ROUTER_ID_STANDARD
: RoutesXml.ROUTER_ID_ADMIN
);
}
@NotNull final XmlTag[] buttonsTags = routerTag.findSubTags("route");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,8 @@ private Areas getArea(final String area) {
private Properties getAttributes(final String area) {
final Properties attributes = new Properties();
attributes.setProperty("ROUTER_ID", area.equals(Areas.frontend.toString())
? RoutesXml.routerIdStandart
: RoutesXml.routerIdAdmin
? RoutesXml.ROUTER_ID_STANDARD
: RoutesXml.ROUTER_ID_ADMIN
);
return attributes;
}
Expand Down
13 changes: 7 additions & 6 deletions src/com/magento/idea/magento2plugin/magento/files/RoutesXml.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,20 @@
import com.intellij.lang.xml.XMLLanguage;

public class RoutesXml implements ModuleFileInterface {
public static String fileName = "routes.xml";
public static String template = "Magento Routes XML";
public static String routerIdStandart = "standart";
public static String routerIdAdmin = "admin";

public static final String FILE_NAME = "routes.xml";
public static final String TEMPLATE = "Magento Routes XML";
public static final String ROUTER_ID_STANDARD = "standard";
public static final String ROUTER_ID_ADMIN = "admin";

@Override
public String getFileName() {
return fileName;
return FILE_NAME;
}

@Override
public String getTemplate() {
return template;
return TEMPLATE;
}

@Override
Expand Down
Loading