Skip to content

Commit e872d63

Browse files
Merge branch '4.4.0-develop' of github.com:magento/magento2-phpstorm-plugin into 1016-generation-of-readme-file-option
2 parents aa6f920 + 8ecd5c9 commit e872d63

File tree

25 files changed

+1637
-87
lines changed

25 files changed

+1637
-87
lines changed

resources/META-INF/plugin.xml

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -178,8 +178,11 @@
178178
<projectService serviceImplementation="com.magento.idea.magento2plugin.project.Settings"/>
179179
<projectService serviceImplementation="com.magento.idea.magento2uct.settings.UctSettingsService"/>
180180

181-
<completion.contributor language="XML" implementationClass="com.magento.idea.magento2plugin.completion.xml.XmlCompletionContributor" id="xml" />
182-
<completion.contributor language="PHP" implementationClass="com.magento.idea.magento2plugin.completion.php.PhpCompletionContributor" id="php" />
181+
<completion.contributor language="XML" implementationClass="com.magento.idea.magento2plugin.completion.xml.XmlCompletionContributor" id="xml"/>
182+
<completion.contributor language="PHP" implementationClass="com.magento.idea.magento2plugin.completion.php.PhpCompletionContributor" id="php"/>
183+
184+
<completion.contributor language="XML" implementationClass="com.magento.idea.magento2plugin.completion.xml.SystemConfigurationContributor" id="magentoSystemConfiguration"/>
185+
<xml.tagNameProvider implementation="com.magento.idea.magento2plugin.completion.provider.xml.ConfigXmlTagNameProvider"/>
183186

184187
<psi.referenceContributor language="XML" implementation="com.magento.idea.magento2plugin.reference.xml.XmlReferenceContributor"/>
185188
<psi.referenceContributor language="PHP" implementation="com.magento.idea.magento2plugin.reference.php.PhpReferenceContributor"/>
@@ -209,6 +212,9 @@
209212
<fileBasedIndex implementation="com.magento.idea.magento2plugin.stubs.indexes.xml.DeclarativeSchemaElementsIndex" />
210213
<fileBasedIndex implementation="com.magento.idea.magento2plugin.stubs.indexes.xml.UIComponentIndex" />
211214
<fileBasedIndex implementation="com.magento.idea.magento2plugin.stubs.indexes.xml.ProductTypeIndex" />
215+
<fileBasedIndex implementation="com.magento.idea.magento2plugin.stubs.indexes.xml.SystemXmlSectionIndex" />
216+
<fileBasedIndex implementation="com.magento.idea.magento2plugin.stubs.indexes.xml.SystemXmlGroupIndex" />
217+
<fileBasedIndex implementation="com.magento.idea.magento2plugin.stubs.indexes.xml.SystemXmlFieldIndex" />
212218

213219
<codeInsight.lineMarkerProvider language="PHP" implementationClass="com.magento.idea.magento2plugin.linemarker.php.PluginLineMarkerProvider"/>
214220
<codeInsight.lineMarkerProvider language="PHP" implementationClass="com.magento.idea.magento2plugin.linemarker.php.PluginTargetLineMarkerProvider"/>

src/com/magento/idea/magento2plugin/actions/comparator/CompareTemplateAction.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,8 @@ public CompareTemplateAction() {
4949
*
5050
* @param event AnActionEvent
5151
*/
52-
@SuppressWarnings("PMD.NPathComplexity")
5352
@Override
53+
@SuppressWarnings({"PMD.CyclomaticComplexity", "PMD.NPathComplexity"})
5454
public void update(final @NotNull AnActionEvent event) {
5555
setStatus(event, false);
5656
final Project project = event.getData(PlatformDataKeys.PROJECT);
@@ -83,6 +83,9 @@ public void update(final @NotNull AnActionEvent event) {
8383
}
8484
final String originalModuleName = getOriginalModuleName(project, psiFile);
8585

86+
if (originalModuleName == null) {
87+
return;
88+
}
8689
final PsiDirectory originalModuleDirectory =
8790
new ModuleIndex(project).getModuleDirectoryByModuleName(originalModuleName);
8891

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,10 @@ public OverrideClassByAPreferenceAction() {
3838
public void update(final AnActionEvent event) {
3939
targetClass = null;// NOPMD
4040
final Project project = event.getData(PlatformDataKeys.PROJECT);
41+
42+
if (project == null) {
43+
return;
44+
}
4145
if (Settings.isEnabled(project)) {
4246
final Pair<PsiFile, PhpClass> pair = this.findPhpClass(event);
4347
final PsiFile psiFile = pair.getFirst();

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

Lines changed: 4 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,11 @@
1111
import com.magento.idea.magento2plugin.actions.context.xml.NewLayoutXmlAction;
1212
import com.magento.idea.magento2plugin.actions.generation.data.LayoutXmlData;
1313
import com.magento.idea.magento2plugin.actions.generation.data.ui.ComboBoxItemData;
14-
import com.magento.idea.magento2plugin.actions.generation.dialog.util.DialogFieldErrorUtil;
1514
import com.magento.idea.magento2plugin.actions.generation.dialog.validator.annotation.FieldValidation;
1615
import com.magento.idea.magento2plugin.actions.generation.dialog.validator.annotation.RuleRegistry;
1716
import com.magento.idea.magento2plugin.actions.generation.dialog.validator.rule.IdentifierRule;
1817
import com.magento.idea.magento2plugin.actions.generation.dialog.validator.rule.NotEmptyRule;
1918
import com.magento.idea.magento2plugin.actions.generation.generator.LayoutXmlTemplateGenerator;
20-
import com.magento.idea.magento2plugin.bundles.ValidatorBundle;
2119
import com.magento.idea.magento2plugin.magento.packages.Areas;
2220
import com.magento.idea.magento2plugin.util.magento.GetModuleNameByDirectoryUtil;
2321
import java.awt.event.KeyEvent;
@@ -122,7 +120,7 @@ public static void open(
122120
* Fire generation process if all fields are valid.
123121
*/
124122
private void onOK() {
125-
if (validateFormFields() && isUnderscoreCorrect()) {
123+
if (validateFormFields()) {
126124
final String[] layoutNameParts = getLayoutNameParts();
127125
new LayoutXmlTemplateGenerator(
128126
new LayoutXmlData(
@@ -188,51 +186,11 @@ private String[] getLayoutNameParts() {
188186
actionName = layoutNameParts[2];
189187
}
190188

191-
return new String[]{routeName, controllerName, actionName};
192-
}
193-
194-
/**
195-
* Check is count of underscore is correct in layout name.
196-
*
197-
* @return boolean
198-
*/
199-
private boolean isUnderscoreCorrect() {
200-
final String name = layoutName.getText().trim();
201-
202-
if (name.contains("_")) {
203-
final int count = countUnderscore(name);
204-
205-
if (count != 0 && count != 2) {
206-
DialogFieldErrorUtil.showErrorMessageForField(
207-
layoutName,
208-
layoutNameErrorMessage,
209-
new ValidatorBundle()
210-
.message("validator.layoutNameUnderscoreQtyInvalid")
211-
);
212-
213-
return false;
214-
}
189+
if (layoutNameParts.length == 2 || layoutNameParts.length > 3) { // NOPMD
190+
routeName = layoutName.getText().trim();
215191
}
216192

217-
return true;
218-
}
219-
220-
/**
221-
* Count underscore symbols in string.
222-
*
223-
* @param name String
224-
* @return int
225-
*/
226-
private int countUnderscore(final String name) {
227-
int count = 0;
228-
229-
for (int i = 0; i < name.length(); i++) {
230-
if (name.charAt(i) == '_') { //NOPMD
231-
count++;
232-
}
233-
}
234-
235-
return count;
193+
return new String[]{routeName, controllerName, actionName};
236194
}
237195

238196
/**
Lines changed: 230 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,230 @@
1+
/*
2+
* Copyright © Magento, Inc. All rights reserved.
3+
* See COPYING.txt for license details.
4+
*/
5+
6+
package com.magento.idea.magento2plugin.completion.provider.xml;
7+
8+
import static com.magento.idea.magento2plugin.magento.files.ModuleConfigXmlFile.FILE_NAME;
9+
import static com.magento.idea.magento2plugin.magento.files.ModuleConfigXmlFile.ROOT_TAG_NAME;
10+
11+
import com.intellij.codeInsight.lookup.LookupElement;
12+
import com.intellij.openapi.project.Project;
13+
import com.intellij.psi.xml.XmlFile;
14+
import com.intellij.psi.xml.XmlTag;
15+
import com.intellij.xml.XmlTagNameProvider;
16+
import com.magento.idea.magento2plugin.project.Settings;
17+
import java.util.ArrayList;
18+
import java.util.Collections;
19+
import java.util.List;
20+
import org.jetbrains.annotations.NotNull;
21+
import org.jetbrains.annotations.Nullable;
22+
23+
public class ConfigXmlTagNameProvider implements XmlTagNameProvider {
24+
25+
@Override
26+
public void addTagNameVariants(
27+
final List<LookupElement> elements,
28+
final @NotNull XmlTag tag,
29+
final String prefix
30+
) {
31+
if (!Settings.isEnabled(tag.getProject()) || !validate(tag)) {
32+
return;
33+
}
34+
final int tagDepth = getTagDepth(tag);
35+
36+
if (tagDepth == -1) {
37+
return;
38+
}
39+
final ConfigTagScope tagScope = getTagScope(tag);
40+
41+
if (tagScope == null) {
42+
return;
43+
}
44+
final ConfigTagTypeByScopedDepth configType = ConfigTagTypeByScopedDepth
45+
.getTagTypeByScopeAndDepth(tagDepth, tagScope);
46+
47+
if (configType == null) {
48+
return;
49+
}
50+
final String indexKey = configType.getConfigPath(tag);
51+
final String phrase = indexKey.isEmpty() ? prefix : indexKey + "." + prefix;
52+
53+
elements.addAll(configType.makeCompletion(phrase, tag.getProject()));
54+
}
55+
56+
private boolean validate(final @NotNull XmlTag tag) {
57+
if (!(tag.getContainingFile() instanceof XmlFile)) {
58+
return false;
59+
}
60+
final XmlFile file = (XmlFile) tag.getContainingFile();
61+
final XmlTag rootTag = file.getRootTag();
62+
63+
if (!FILE_NAME.equals(file.getName())
64+
|| rootTag == null
65+
|| !ROOT_TAG_NAME.equals(rootTag.getName())) {
66+
return false;
67+
}
68+
final int tagDepth = getTagDepth(tag);
69+
70+
return tagDepth >= 2 && tagDepth <= 5;
71+
}
72+
73+
private int getTagDepth(final @NotNull XmlTag tag) {
74+
if (!(tag.getContainingFile() instanceof XmlFile)) {
75+
return -1;
76+
}
77+
final XmlFile file = (XmlFile) tag.getContainingFile();
78+
final XmlTag rootTag = file.getRootTag();
79+
80+
if (rootTag == null) {
81+
return -1;
82+
}
83+
int depth = 0;
84+
XmlTag iterable = tag;
85+
86+
while (!iterable.equals(rootTag)) {
87+
depth++;
88+
iterable = iterable.getParentTag();
89+
90+
if (iterable == null) {
91+
break;
92+
}
93+
}
94+
95+
return depth;
96+
}
97+
98+
private @Nullable ConfigTagScope getTagScope(final @NotNull XmlTag tag) {
99+
if (!(tag.getContainingFile() instanceof XmlFile)) {
100+
return null;
101+
}
102+
final XmlFile file = (XmlFile) tag.getContainingFile();
103+
final XmlTag rootTag = file.getRootTag();
104+
105+
if (rootTag == null) {
106+
return null;
107+
}
108+
XmlTag scopeTag = null;
109+
XmlTag iterable = tag;
110+
111+
while (!iterable.equals(rootTag)) {
112+
scopeTag = iterable;
113+
iterable = iterable.getParentTag();
114+
115+
if (iterable == null) {
116+
break;
117+
}
118+
}
119+
120+
if (scopeTag == null) {
121+
return null;
122+
}
123+
124+
return ConfigTagScope.getScopeByTagName(scopeTag.getName());
125+
}
126+
127+
private enum ConfigTagTypeByScopedDepth {
128+
129+
SECTION(2, 3, 3, 0),
130+
GROUP(3, 4, 4, 1),
131+
FIELD(4, 5, 5, 2);
132+
133+
private final int defaultScope;
134+
private final int websitesScope;
135+
private final int storesScope;
136+
private final int fallbackDepth;
137+
138+
ConfigTagTypeByScopedDepth(
139+
final int defaultScope,
140+
final int websitesScope,
141+
final int storesScope,
142+
final int fallbackDepth
143+
) {
144+
this.defaultScope = defaultScope;
145+
this.websitesScope = websitesScope;
146+
this.storesScope = storesScope;
147+
this.fallbackDepth = fallbackDepth;
148+
}
149+
150+
public static ConfigTagTypeByScopedDepth getTagTypeByScopeAndDepth(
151+
final int depth,
152+
final ConfigTagScope scope
153+
) {
154+
for (final ConfigTagTypeByScopedDepth tagType : ConfigTagTypeByScopedDepth.values()) {
155+
int depthForScope = -1;
156+
157+
if (ConfigTagScope.DEFAULT.equals(scope)) {
158+
depthForScope = tagType.defaultScope;
159+
} else if (ConfigTagScope.WEBSITES.equals(scope)) {
160+
depthForScope = tagType.websitesScope;
161+
} else if (ConfigTagScope.STORES.equals(scope)) {
162+
depthForScope = tagType.storesScope;
163+
}
164+
165+
if (depth == depthForScope) {
166+
return tagType;
167+
}
168+
}
169+
170+
return null;
171+
}
172+
173+
public @NotNull String getConfigPath(final @NotNull XmlTag tag) {
174+
final List<String> parts = new ArrayList<>();
175+
XmlTag iterable = tag.getParentTag();
176+
177+
for (int i = 0; i < fallbackDepth; i++) {
178+
if (iterable != null) {
179+
parts.add(iterable.getName());
180+
iterable = iterable.getParentTag();
181+
}
182+
}
183+
184+
if (parts.isEmpty()) {
185+
return "";
186+
}
187+
Collections.reverse(parts);
188+
189+
return String.join(".", parts);
190+
}
191+
192+
public List<LookupElement> makeCompletion(
193+
final @NotNull String phrase,
194+
final @NotNull Project project
195+
) {
196+
if (this.equals(ConfigTagTypeByScopedDepth.SECTION)) {
197+
return SectionNameCompletionProvider.makeCompletion(phrase, project);
198+
} else if (this.equals(ConfigTagTypeByScopedDepth.GROUP)) {
199+
return GroupNameCompletionProvider.makeCompletion(phrase, project);
200+
} else if (this.equals(ConfigTagTypeByScopedDepth.FIELD)) {
201+
return FieldNameCompletionProvider.makeCompletion(phrase, project);
202+
}
203+
204+
return new ArrayList<>();
205+
}
206+
}
207+
208+
private enum ConfigTagScope {
209+
210+
DEFAULT("default"),
211+
WEBSITES("websites"),
212+
STORES("stores");
213+
214+
private final String scopeTagName;
215+
216+
ConfigTagScope(final String scopeTagName) {
217+
this.scopeTagName = scopeTagName;
218+
}
219+
220+
public static ConfigTagScope getScopeByTagName(final @NotNull String tagName) {
221+
for (final ConfigTagScope scope : ConfigTagScope.values()) {
222+
if (tagName.equals(scope.scopeTagName)) {
223+
return scope;
224+
}
225+
}
226+
227+
return null;
228+
}
229+
}
230+
}

0 commit comments

Comments
 (0)