Skip to content

Commit b2374d6

Browse files
authored
Merge pull request #978 from bohdan-harniuk/977-new-system-xml-file-action
977: Added system.xml file in context generation
2 parents 3997a01 + 8f685a9 commit b2374d6

15 files changed

+292
-55
lines changed

resources/META-INF/plugin.xml

+1
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@
6464
<action id="MagentoCreateWebapiFile" class="com.magento.idea.magento2plugin.actions.context.xml.NewWebapiXmlAction"/>
6565
<action id="MagentoCreateAclFile" class="com.magento.idea.magento2plugin.actions.context.xml.NewAclXmlAction"/>
6666
<action id="MagentoCreateConfigFile" class="com.magento.idea.magento2plugin.actions.context.xml.NewConfigXmlAction"/>
67+
<action id="MagentoCreateSystemFile" class="com.magento.idea.magento2plugin.actions.context.xml.NewSystemXmlAction"/>
6768
<!-- Context dependent actions -->
6869
<separator/>
6970
<add-to-group group-id="NewGroup" anchor="before" relative-to-action="NewXml"/>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<?xml version="1.0"?>
2+
#parse("XML File Header.xml")
3+
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Config:etc/system_file.xsd">
5+
<system>
6+
</system>
7+
</config>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<!--
2+
/*
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
-->
7+
<html>
8+
<body>
9+
<table width="100%" border="0" cellpadding="5" cellspacing="0" style="border-collapse: collapse">
10+
<tr>
11+
<td><font face="verdana" size="-1">
12+
The system.xml file allows you to manage the Magento system configuration. Use this topic as a general reference for the system.xml file.
13+
The system.xml file is located under etc/adminhtml/system.xml in a given Magento 2 extension.
14+
</font><br>
15+
</td>
16+
</tr>
17+
<tr>
18+
<td><font face="verdana" size="-1">
19+
Read more about the system.xml in the
20+
<a href="https://devdocs.magento.com/guides/v2.4/config-guide/prod/config-reference-systemxml.html">
21+
DevDocs</a>.
22+
</font><br>
23+
</td>
24+
</tr>
25+
</table>
26+
</body>
27+
</html>

src/com/magento/idea/magento2plugin/actions/context/AbstractContextAction.java

+13
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import com.intellij.psi.PsiFile;
2121
import com.magento.idea.magento2plugin.MagentoIcons;
2222
import com.magento.idea.magento2plugin.magento.files.ModuleFileInterface;
23+
import com.magento.idea.magento2plugin.magento.packages.Package;
2324
import com.magento.idea.magento2plugin.util.magento.GetMagentoModuleUtil;
2425
import org.jetbrains.annotations.NotNull;
2526
import org.jetbrains.annotations.Nullable;
@@ -154,6 +155,18 @@ protected FileTemplate getTemplate(
154155
return template;
155156
}
156157

158+
protected @Nullable PsiDirectory getGlobalScopeDir(final @NotNull PsiDirectory directory) {
159+
PsiDirectory globalScopeDir;
160+
161+
if (Package.moduleBaseAreaDir.equals(directory.getName())) {
162+
globalScopeDir = directory;
163+
} else {
164+
globalScopeDir = directory.getParentDirectory();
165+
}
166+
167+
return globalScopeDir;
168+
}
169+
157170
@Override
158171
public boolean isDumbAware() {
159172
return false;

src/com/magento/idea/magento2plugin/actions/context/xml/NewAclXmlAction.java

+7
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,14 @@ protected boolean isVisible(
3333
final @NotNull PsiDirectory targetDirectory,
3434
final PsiFile targetFile
3535
) {
36+
final PsiDirectory configDir = moduleData.getConfigDir();
37+
38+
if (configDir == null) {
39+
return false;
40+
}
41+
3642
return targetDirectory.getName().equals(Package.moduleBaseAreaDir)
43+
&& targetDirectory.equals(configDir)
3744
&& moduleData.getType().equals(ComponentType.module);
3845
}
3946

src/com/magento/idea/magento2plugin/actions/context/xml/NewConfigXmlAction.java

+7
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,14 @@ protected boolean isVisible(
3333
final @NotNull PsiDirectory targetDirectory,
3434
final PsiFile targetFile
3535
) {
36+
final PsiDirectory configDir = moduleData.getConfigDir();
37+
38+
if (configDir == null) {
39+
return false;
40+
}
41+
3642
return targetDirectory.getName().equals(Package.moduleBaseAreaDir)
43+
&& targetDirectory.equals(configDir)
3744
&& moduleData.getType().equals(ComponentType.module);
3845
}
3946

src/com/magento/idea/magento2plugin/actions/context/xml/NewDiXmlAction.java

+7
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,12 @@ protected boolean isVisible(
3636
final @NotNull PsiDirectory targetDirectory,
3737
final PsiFile targetFile
3838
) {
39+
final PsiDirectory configDir = moduleData.getConfigDir();
40+
final PsiDirectory globalScopeDir = getGlobalScopeDir(targetDirectory);
41+
42+
if (configDir == null || globalScopeDir == null) {
43+
return false;
44+
}
3945
final List<String> allowedDirectories = Arrays.asList(
4046
Package.moduleBaseAreaDir,
4147
Areas.adminhtml.toString(),
@@ -47,6 +53,7 @@ protected boolean isVisible(
4753
);
4854

4955
return allowedDirectories.contains(targetDirectory.getName())
56+
&& globalScopeDir.equals(configDir)
5057
&& moduleData.getType().equals(ComponentType.module);
5158
}
5259

src/com/magento/idea/magento2plugin/actions/context/xml/NewRoutesXmlAction.java

+7
Original file line numberDiff line numberDiff line change
@@ -36,13 +36,20 @@ protected boolean isVisible(
3636
final @NotNull PsiDirectory targetDirectory,
3737
final PsiFile targetFile
3838
) {
39+
final PsiDirectory configDir = moduleData.getConfigDir();
40+
final PsiDirectory globalScopeDir = getGlobalScopeDir(targetDirectory);
41+
42+
if (configDir == null || globalScopeDir == null) {
43+
return false;
44+
}
3945
final List<String> allowedDirectories = Arrays.asList(
4046
Package.moduleBaseAreaDir,
4147
Areas.adminhtml.toString(),
4248
Areas.frontend.toString()
4349
);
4450

4551
return allowedDirectories.contains(targetDirectory.getName())
52+
&& globalScopeDir.equals(configDir)
4653
&& moduleData.getType().equals(ComponentType.module);
4754
}
4855

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
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.ModuleSystemXmlFile;
13+
import com.magento.idea.magento2plugin.magento.packages.Areas;
14+
import com.magento.idea.magento2plugin.magento.packages.ComponentType;
15+
import com.magento.idea.magento2plugin.util.magento.GetMagentoModuleUtil;
16+
import org.jetbrains.annotations.NotNull;
17+
18+
public class NewSystemXmlAction extends AbstractContextAction {
19+
20+
public static final String ACTION_NAME = "Magento 2 System File";
21+
public static final String ACTION_DESCRIPTION = "Create a new Magento 2 system.xml file";
22+
23+
/**
24+
* New system.xml file generation action constructor.
25+
*/
26+
public NewSystemXmlAction() {
27+
super(ACTION_NAME, ACTION_DESCRIPTION, new ModuleSystemXmlFile());
28+
}
29+
30+
@Override
31+
protected boolean isVisible(
32+
final @NotNull GetMagentoModuleUtil.MagentoModuleData moduleData,
33+
final @NotNull PsiDirectory targetDirectory,
34+
final PsiFile targetFile
35+
) {
36+
final PsiDirectory parentDir = targetDirectory.getParentDirectory();
37+
final PsiDirectory configDir = moduleData.getConfigDir();
38+
39+
if (parentDir == null || configDir == null) {
40+
return false;
41+
}
42+
43+
return targetDirectory.getName().equals(Areas.adminhtml.toString())
44+
&& parentDir.equals(configDir)
45+
&& moduleData.getType().equals(ComponentType.module);
46+
}
47+
48+
@Override
49+
protected AttributesDefaults getProperties(
50+
final @NotNull AttributesDefaults defaults,
51+
final @NotNull GetMagentoModuleUtil.MagentoModuleData moduleData,
52+
final PsiDirectory targetDirectory,
53+
final PsiFile targetFile
54+
) {
55+
return defaults;
56+
}
57+
}

src/com/magento/idea/magento2plugin/actions/context/xml/NewWebapiXmlAction.java

+7
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,14 @@ protected boolean isVisible(
3333
final @NotNull PsiDirectory targetDirectory,
3434
final PsiFile targetFile
3535
) {
36+
final PsiDirectory configDir = moduleData.getConfigDir();
37+
38+
if (configDir == null) {
39+
return false;
40+
}
41+
3642
return targetDirectory.getName().equals(Package.moduleBaseAreaDir)
43+
&& targetDirectory.equals(configDir)
3744
&& moduleData.getType().equals(ComponentType.module);
3845
}
3946

src/com/magento/idea/magento2plugin/completion/xml/XmlCompletionContributor.java

+7-7
Original file line numberDiff line numberDiff line change
@@ -154,24 +154,24 @@ public XmlCompletionContributor() {
154154

155155
// <source_model>php class completion</source_model> in system.xml files.
156156
extend(CompletionType.BASIC, PlatformPatterns.psiElement(XmlTokenType.XML_DATA_CHARACTERS)
157-
.inside(XmlPatterns.xmlTag().withName(ModuleSystemXml.XML_TAG_SOURCE_MODEL)
158-
.withParent(XmlPatterns.xmlTag().withName(ModuleSystemXml.FIELD_ELEMENT_NAME))
159-
).inFile(XmlPatterns.xmlFile().withName(StandardPatterns.string().matches(ModuleSystemXml.FILE_NAME))),
157+
.inside(XmlPatterns.xmlTag().withName(ModuleSystemXmlFile.XML_TAG_SOURCE_MODEL)
158+
.withParent(XmlPatterns.xmlTag().withName(ModuleSystemXmlFile.FIELD_ELEMENT_NAME))
159+
).inFile(XmlPatterns.xmlFile().withName(StandardPatterns.string().matches(ModuleSystemXmlFile.FILE_NAME))),
160160
new PhpClassCompletionProvider()
161161
);
162162

163163
// <frontend_model>completion</frontend_model>
164164
extend(CompletionType.BASIC,
165165
PlatformPatterns.psiElement(XmlTokenType.XML_DATA_CHARACTERS)
166-
.inside(XmlPatterns.xmlTag().withName(ModuleSystemXml.XML_TAG_FRONTEND_MODEL)),
166+
.inside(XmlPatterns.xmlTag().withName(ModuleSystemXmlFile.XML_TAG_FRONTEND_MODEL)),
167167
new PhpClassCompletionProvider()
168168
);
169169

170170
// <backend_model>completion</backend_model> in system.xml
171171
extend(CompletionType.BASIC, PlatformPatterns.psiElement(XmlTokenType.XML_DATA_CHARACTERS)
172-
.inside(XmlPatterns.xmlTag().withName(ModuleSystemXml.XML_TAG_BACKEND_MODEL)
173-
.withParent(XmlPatterns.xmlTag().withName(ModuleSystemXml.FIELD_ELEMENT_NAME))
174-
).inFile(XmlPatterns.xmlFile().withName(StandardPatterns.string().matches(ModuleSystemXml.FILE_NAME))),
172+
.inside(XmlPatterns.xmlTag().withName(ModuleSystemXmlFile.XML_TAG_BACKEND_MODEL)
173+
.withParent(XmlPatterns.xmlTag().withName(ModuleSystemXmlFile.FIELD_ELEMENT_NAME))
174+
).inFile(XmlPatterns.xmlFile().withName(StandardPatterns.string().matches(ModuleSystemXmlFile.FILE_NAME))),
175175
new PhpClassCompletionProvider()
176176
);
177177

src/com/magento/idea/magento2plugin/magento/files/ModuleSystemXml.java src/com/magento/idea/magento2plugin/magento/files/ModuleSystemXmlFile.java

+23-1
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,34 @@
22
* Copyright © Magento, Inc. All rights reserved.
33
* See COPYING.txt for license details.
44
*/
5+
56
package com.magento.idea.magento2plugin.magento.files;
67

7-
public class ModuleSystemXml {
8+
import com.intellij.lang.Language;
9+
import com.intellij.lang.xml.XMLLanguage;
10+
11+
public final class ModuleSystemXmlFile implements ModuleFileInterface {
12+
813
public static final String FILE_NAME = "system.xml";
14+
public static final String TEMPLATE = "Magento System XML";
15+
916
public static final String FIELD_ELEMENT_NAME = "field";
1017
public static final String XML_TAG_SOURCE_MODEL = "source_model";
1118
public static final String XML_TAG_FRONTEND_MODEL = "frontend_model";
1219
public static final String XML_TAG_BACKEND_MODEL = "backend_model";
20+
21+
@Override
22+
public String getFileName() {
23+
return FILE_NAME;
24+
}
25+
26+
@Override
27+
public String getTemplate() {
28+
return TEMPLATE;
29+
}
30+
31+
@Override
32+
public Language getLanguage() {
33+
return XMLLanguage.INSTANCE;
34+
}
1335
}

src/com/magento/idea/magento2plugin/util/magento/GetMagentoModuleUtil.java

+34-2
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,10 @@
1616
import com.jetbrains.php.lang.psi.elements.impl.ClassConstImpl;
1717
import com.magento.idea.magento2plugin.magento.files.RegistrationPhp;
1818
import com.magento.idea.magento2plugin.magento.packages.ComponentType;
19+
import com.magento.idea.magento2plugin.magento.packages.Package;
1920
import java.util.Collection;
2021
import org.jetbrains.annotations.NotNull;
22+
import org.jetbrains.annotations.Nullable;
2123

2224
public final class GetMagentoModuleUtil {
2325

@@ -46,6 +48,9 @@ public static MagentoModuleData getByContext(
4648
if (registrationFile == null) {
4749
return null;
4850
}
51+
final PsiDirectory configDir = registrationFile
52+
.getContainingDirectory()
53+
.findSubdirectory(Package.moduleBaseAreaDir);
4954
final Collection<MethodReference> methodReferences = PsiTreeUtil.findChildrenOfType(
5055
registrationFile,
5156
MethodReference.class
@@ -71,7 +76,7 @@ public static MagentoModuleData getByContext(
7176
return null;
7277
}
7378

74-
return new MagentoModuleData(name, resolvedType);
79+
return new MagentoModuleData(name, resolvedType, configDir);
7580
}
7681

7782
return null;
@@ -124,13 +129,36 @@ public static class MagentoModuleData {
124129

125130
private final String name;
126131
private final ComponentType type;
127-
132+
private final PsiDirectory configDir;
133+
134+
/**
135+
* Default constructor.
136+
*
137+
* @param name String
138+
* @param type ComponentType
139+
*/
128140
public MagentoModuleData(
129141
final @NotNull String name,
130142
final @NotNull ComponentType type
143+
) {
144+
this(name, type, null);
145+
}
146+
147+
/**
148+
* Constructor with a config directory specified.
149+
*
150+
* @param name String
151+
* @param type ComponentType
152+
* @param configDir PsiDirectory
153+
*/
154+
public MagentoModuleData(
155+
final @NotNull String name,
156+
final @NotNull ComponentType type,
157+
final @Nullable PsiDirectory configDir
131158
) {
132159
this.name = name;
133160
this.type = type;
161+
this.configDir = configDir;
134162
}
135163

136164
public String getName() {
@@ -140,5 +168,9 @@ public String getName() {
140168
public ComponentType getType() {
141169
return type;
142170
}
171+
172+
public @Nullable PsiDirectory getConfigDir() {
173+
return configDir;
174+
}
143175
}
144176
}

0 commit comments

Comments
 (0)