diff --git a/CHANGELOG.md b/CHANGELOG.md index e261f4f46..ab3480a50 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,49 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0). ## 4.4.0 +### Added + +- Code generation of a Data Patch file with a Customer EAV attribute [#583](https://github.com/magento/magento2-phpstorm-plugin/pull/583) +- Code generation of a Data Patch file with a Product EAV attribute [#527](https://github.com/magento/magento2-phpstorm-plugin/pull/527) +- Code generation of a Data Patch file with a Category EAV attribute [#569](https://github.com/magento/magento2-phpstorm-plugin/pull/569) +- Code generation of Readme file [#1133](https://github.com/magento/magento2-phpstorm-plugin/pull/1133) +- Code generation of GraphQl schema file [#1123](https://github.com/magento/magento2-phpstorm-plugin/pull/1123) +- Optional generation of Readme file during the creation of a new module [#1110](https://github.com/magento/magento2-phpstorm-plugin/pull/1110) +- Code completion for `system.xml` and `config.xml` [#1077](https://github.com/magento/magento2-phpstorm-plugin/pull/1077) +- Added easier navigation through plugins [#1121](https://github.com/magento/magento2-phpstorm-plugin/pull/1121) +- Added inspection to check if type attr value in the virtual type tag attribute value exists [#1176](https://github.com/magento/magento2-phpstorm-plugin/pull/1176) +- Added checks and detailed error messages during plugin activation [#1181](https://github.com/magento/magento2-phpstorm-plugin/pull/1181) + +### Fixed + +- Fixed NullPointerException at ObserverDeclarationInspection.java:188 [#1143](https://github.com/magento/magento2-phpstorm-plugin/issues/1143) +- Fixed IncorrectOperationException: Rebind cannot be performed for class PolyVariantReferenceBase [#1173](https://github.com/magento/magento2-phpstorm-plugin/pull/1173) +- Fixed create an observer for an event doesn't work through the context menu [#1166](https://github.com/magento/magento2-phpstorm-plugin/pull/1166) +- Fixed IOException: Invalid file name at ReportBuilder [#1154](https://github.com/magento/magento2-phpstorm-plugin/pull/1154) +- Fixed IllegalArgumentException in NewModuleAction class [#1150](https://github.com/magento/magento2-phpstorm-plugin/pull/1150) +- Fixed null data in ModuleIndex class [#1132](https://github.com/magento/magento2-phpstorm-plugin/pull/1132) +- Fixed StringIndexOutOfBoundsException: GitHubNewIssueBodyBuilderUtil [#1130](https://github.com/magento/magento2-phpstorm-plugin/pull/1130) +- Fixed ArrayIndexOutOfBoundsException: Index 1 out of bounds for length 0 in OverrideClassByAPreferenceDialog [#1129](https://github.com/magento/magento2-phpstorm-plugin/pull/1129) +- Fixed PatternSyntaxException: MagentoBasePathUtil.isMagentoFolderValid:35 for Windows styled dir path separator [#1126](https://github.com/magento/magento2-phpstorm-plugin/pull/1126) +- Fixed NullPointerException in the OverrideTemplateInThemeAction.isOverrideAllowed for virtualFile.getCanonicalPath() [#1125](https://github.com/magento/magento2-phpstorm-plugin/pull/1125) +- Fixed IllegalArgumentException: Argument for @NotNull parameter 'dataKey' must not be null in CompareTemplateAction [#1117](https://github.com/magento/magento2-phpstorm-plugin/pull/1117) +- Fixed argument for @NotNull parameter 'project' must not be null in the OverrideClassByAPreferenceAction [#1116](https://github.com/magento/magento2-phpstorm-plugin/pull/1116) +- Fixed New layout action doesn't accept valid layout names [#1114](https://github.com/magento/magento2-phpstorm-plugin/pull/1114) + +## 4.3.1 + +### Changed + +- Added raw plugin verifier configuration in [#1065](https://github.com/magento/magento2-phpstorm-plugin/pull/1065) + +### Fixed + +- Fixed bug with the file separator on Windows OS (while saving plugin settings) in [#1062](https://github.com/magento/magento2-phpstorm-plugin/pull/1062) +- Fixed bug with wrong text range for FilePathReferenceProvider.getReferencesByElement in [#1063](https://github.com/magento/magento2-phpstorm-plugin/pull/1063) +- Fixed module files action group is accessible from the theme context in [#1064](https://github.com/magento/magento2-phpstorm-plugin/pull/1064) +- Fixed bug with directory index is already disposed for Project in AllFilesExceptTestsScope.contains in [#1080](https://github.com/magento/magento2-phpstorm-plugin/pull/1080) +- Fixed bug with DumbService cannot be created because container is already disposed in MagentoComponentManager.getComponents in [#1081](https://github.com/magento/magento2-phpstorm-plugin/pull/1081) + ## 4.3.0 ### Added diff --git a/src/com/magento/idea/magento2plugin/actions/context/AbstractContextAction.java b/src/com/magento/idea/magento2plugin/actions/context/AbstractContextAction.java index d54bbaa75..47c826a48 100644 --- a/src/com/magento/idea/magento2plugin/actions/context/AbstractContextAction.java +++ b/src/com/magento/idea/magento2plugin/actions/context/AbstractContextAction.java @@ -20,7 +20,9 @@ import com.intellij.psi.PsiFile; import com.magento.idea.magento2plugin.MagentoIcons; import com.magento.idea.magento2plugin.magento.files.ModuleFileInterface; +import com.magento.idea.magento2plugin.magento.packages.ComponentType; import com.magento.idea.magento2plugin.magento.packages.Package; +import com.magento.idea.magento2plugin.project.Settings; import com.magento.idea.magento2plugin.util.magento.GetMagentoModuleUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -50,13 +52,14 @@ public AbstractContextAction( } @Override + @SuppressWarnings({"PMD.CyclomaticComplexity", "PMD.NPathComplexity"}) public void update(final @NotNull AnActionEvent event) { event.getPresentation().setEnabled(false); event.getPresentation().setVisible(false); final Project project = event.getProject(); - if (project == null) { + if (project == null || !Settings.isEnabled(project)) { return; } final DataContext context = event.getDataContext(); @@ -86,6 +89,12 @@ public void update(final @NotNull AnActionEvent event) { || !isVisible(moduleData, targetDirectory, targetFile)) { return; } + + if (moduleData.getType().equals(ComponentType.module) + && !GetMagentoModuleUtil.isEditableModule(moduleData)) { + return; + } + customDataContext = SimpleDataContext .builder() .add( diff --git a/src/com/magento/idea/magento2plugin/actions/groups/NewModuleFileGroup.java b/src/com/magento/idea/magento2plugin/actions/groups/NewModuleFileGroup.java index e97d29bf0..e96f568d0 100644 --- a/src/com/magento/idea/magento2plugin/actions/groups/NewModuleFileGroup.java +++ b/src/com/magento/idea/magento2plugin/actions/groups/NewModuleFileGroup.java @@ -16,6 +16,7 @@ import com.magento.idea.magento2plugin.actions.generation.util.IsClickedDirectoryInsideProject; import com.magento.idea.magento2plugin.indexes.ModuleIndex; import com.magento.idea.magento2plugin.project.Settings; +import com.magento.idea.magento2plugin.util.magento.GetMagentoModuleUtil; import com.magento.idea.magento2plugin.util.magento.GetModuleNameByDirectoryUtil; import javax.swing.Icon; import org.jetbrains.annotations.NotNull; @@ -62,7 +63,8 @@ public void update(final AnActionEvent event) { final PsiDirectory moduleDirectory = new ModuleIndex(project) .getModuleDirectoryByModuleName(moduleName); - if (moduleDirectory != null) { + if (moduleDirectory != null + && GetMagentoModuleUtil.isDirectoryInEditableModule(moduleDirectory)) { event.getPresentation().setVisible(true); return; } diff --git a/src/com/magento/idea/magento2plugin/lang/psi/search/AllFilesExceptTestsScope.java b/src/com/magento/idea/magento2plugin/lang/psi/search/AllFilesExceptTestsScope.java index 99e523820..d4d8b5f36 100644 --- a/src/com/magento/idea/magento2plugin/lang/psi/search/AllFilesExceptTestsScope.java +++ b/src/com/magento/idea/magento2plugin/lang/psi/search/AllFilesExceptTestsScope.java @@ -16,33 +16,14 @@ public final class AllFilesExceptTestsScope extends GlobalSearchScope { public static final String SCOPE_NAME = "All Files Except Tests"; - private static AllFilesExceptTestsScope instance; private final Project project; - /** - * Get search scope instance. - * - * @param project Project - * - * @return AllFilesExceptTestsScope - */ - @SuppressWarnings("PMD.AvoidSynchronizedAtMethodLevel") - public static synchronized AllFilesExceptTestsScope getInstance( - final @Nullable Project project - ) { - if (instance == null) { - instance = new AllFilesExceptTestsScope(project); - } - - return instance; - } - /** * Magento search scope constructor. * * @param project Project */ - private AllFilesExceptTestsScope(final @Nullable Project project) { + public AllFilesExceptTestsScope(final @Nullable Project project) { super(project); this.project = project; } diff --git a/src/com/magento/idea/magento2plugin/lang/psi/search/MagentoSearchScopesProvider.java b/src/com/magento/idea/magento2plugin/lang/psi/search/MagentoSearchScopesProvider.java index 7e7898eaa..a4817d05c 100644 --- a/src/com/magento/idea/magento2plugin/lang/psi/search/MagentoSearchScopesProvider.java +++ b/src/com/magento/idea/magento2plugin/lang/psi/search/MagentoSearchScopesProvider.java @@ -32,6 +32,6 @@ public class MagentoSearchScopesProvider implements SearchScopeProvider { return Collections.emptyList(); } - return Collections.singletonList(AllFilesExceptTestsScope.getInstance(project)); + return Collections.singletonList(new AllFilesExceptTestsScope(project)); } } diff --git a/src/com/magento/idea/magento2plugin/magento/packages/MagentoComponentManager.java b/src/com/magento/idea/magento2plugin/magento/packages/MagentoComponentManager.java index 2abb7b0f3..8933352c0 100644 --- a/src/com/magento/idea/magento2plugin/magento/packages/MagentoComponentManager.java +++ b/src/com/magento/idea/magento2plugin/magento/packages/MagentoComponentManager.java @@ -1,11 +1,13 @@ -/** +/* * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ + package com.magento.idea.magento2plugin.magento.packages; import com.intellij.json.psi.JsonFile; import com.intellij.json.psi.JsonObject; +import com.intellij.openapi.components.Service; import com.intellij.openapi.project.DumbService; import com.intellij.openapi.project.Project; import com.intellij.openapi.vfs.VirtualFile; @@ -18,40 +20,48 @@ import com.intellij.psi.xml.XmlTag; import com.intellij.util.indexing.FileBasedIndex; import com.magento.idea.magento2plugin.stubs.indexes.ModulePackageIndex; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.Map; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +@Service +public final class MagentoComponentManager { -public class MagentoComponentManager { private Map components = new HashMap<>(); private long cacheStartTime; - private static final int CACHE_LIFE_TIME = 20000; - private static MagentoComponentManager magentoComponentManager; - private Project project; + private static final int CACHE_LIFE_TIME = 20000;//NOPMD + private final Project project; - private MagentoComponentManager(Project project){ + public MagentoComponentManager(final Project project) { this.project = project; } - public static MagentoComponentManager getInstance(@NotNull Project project) { - if (magentoComponentManager == null) { - magentoComponentManager = new MagentoComponentManager(project); - } - return magentoComponentManager; + public static MagentoComponentManager getInstance(final @NotNull Project project) { + return project.getService(MagentoComponentManager.class); } public Collection getAllComponents() { return getComponents().values(); } + /** + * Get all components of the specified type. + * + * @param type Class + * + * @return Collection + */ @SuppressWarnings("unchecked") - public Collection getAllComponentsOfType(@NotNull Class type) { - Collection result = new ArrayList<>(); - Map components = getComponents(); - for (String key: components.keySet()) { + public Collection getAllComponentsOfType( + final @NotNull Class type + ) { + final Collection result = new ArrayList<>(); + final Map components = getComponents(); + + for (final String key: components.keySet()) { if (type.isInstance(components.get(key))) { result.add((T)components.get(key)); } @@ -60,8 +70,9 @@ public Collection getAllComponentsOfType(@NotNul return result; } - synchronized private Map getComponents() { - if (DumbService.getInstance(project).isDumb() || project.isDisposed()) { + @SuppressWarnings("PMD.AvoidSynchronizedAtMethodLevel") + private synchronized Map getComponents() { + if (project.isDisposed() || DumbService.getInstance(project).isDumb()) { return new HashMap<>(); } @@ -74,9 +85,16 @@ synchronized private Map getComponents() { return components; } + /** + * Get component for the specified file. + * + * @param psiFile PsiFile + * + * @return MagentoComponent + */ @Nullable - public MagentoComponent getComponentForFile(@NotNull PsiFile psiFile) { - for (MagentoComponent magentoComponent: this.getAllComponents()) { + public MagentoComponent getComponentForFile(final @NotNull PsiFile psiFile) { + for (final MagentoComponent magentoComponent: this.getAllComponents()) { if (magentoComponent.isFileInContext(psiFile)) { return magentoComponent; } @@ -85,10 +103,21 @@ public MagentoComponent getComponentForFile(@NotNull PsiFile psiFile) { return null; } + /** + * Get component of type for the specified file. + * + * @param psiFile PsiFile + * @param type Class + * + * @return T + */ @Nullable @SuppressWarnings("unchecked") - public T getComponentOfTypeForFile(@NotNull PsiFile psiFile, @NotNull Class type) { - for (MagentoComponent magentoComponent: this.getAllComponents()) { + public T getComponentOfTypeForFile( + final @NotNull PsiFile psiFile, + final @NotNull Class type + ) { + for (final MagentoComponent magentoComponent: this.getAllComponents()) { if (type.isInstance(magentoComponent) && magentoComponent.isFileInContext(psiFile)) { return (T)magentoComponent; } @@ -97,42 +126,62 @@ public T getComponentOfTypeForFile(@NotNull PsiFile return null; } - synchronized public void flushModules() { + @SuppressWarnings("PMD.AvoidSynchronizedAtMethodLevel") + public synchronized void flushModules() { components = new HashMap<>(); } + @SuppressWarnings({"PMD.AvoidInstantiatingObjectsInLoops", "PMD.AvoidDeeplyNestedIfStmts"}) private void loadModules() { - Collection packages = FileBasedIndex.getInstance().getAllKeys(ModulePackageIndex.KEY, this.project); - PsiManager psiManager = PsiManager.getInstance(this.project); - for (String packageName: packages) { + final Collection packages = FileBasedIndex + .getInstance() + .getAllKeys(ModulePackageIndex.KEY, this.project); + final PsiManager psiManager = PsiManager.getInstance(this.project); + + for (final String packageName: packages) { if (components.containsKey(packageName)) { continue; } - Collection containingFiles = FileBasedIndex.getInstance() - .getContainingFiles(ModulePackageIndex.KEY, packageName, GlobalSearchScope.allScope(this.project)); + final Collection containingFiles = FileBasedIndex + .getInstance() + .getContainingFiles( + ModulePackageIndex.KEY, + packageName, + GlobalSearchScope.allScope(this.project) + ); - if (containingFiles.size() > 0) { - VirtualFile configurationFile = containingFiles.iterator().next(); + if (!containingFiles.isEmpty()) { + final VirtualFile configurationFile = containingFiles.iterator().next(); + final PsiFile psiFile = psiManager.findFile(configurationFile); - PsiFile psiFile = psiManager.findFile(configurationFile); - if (psiFile != null && psiFile instanceof JsonFile) { - JsonObject jsonObject = PsiTreeUtil.getChildOfType((JsonFile) psiFile, JsonObject.class); + if (psiFile instanceof JsonFile) { + final JsonObject jsonObject = PsiTreeUtil + .getChildOfType((JsonFile) psiFile, JsonObject.class); if (jsonObject == null) { continue; } MagentoComponent magentoComponent; - ComposerPackageModel composerPackageModel = new ComposerPackageModelImpl(jsonObject); + final ComposerPackageModel composerPackageModel = new ComposerPackageModelImpl( + jsonObject + ); + if ("magento2-module".equals(composerPackageModel.getType())) { - magentoComponent = new MagentoModuleImpl(new ComposerPackageModelImpl(jsonObject), psiFile.getContainingDirectory()); + magentoComponent = new MagentoModuleImpl( + new ComposerPackageModelImpl(jsonObject), + psiFile.getContainingDirectory() + ); } else { - magentoComponent = new MagentoComponentImp(new ComposerPackageModelImpl(jsonObject), psiFile.getContainingDirectory()); + magentoComponent = new MagentoComponentImp( + new ComposerPackageModelImpl(jsonObject), + psiFile.getContainingDirectory() + ); } components.put( - packageName, - magentoComponent + packageName, + magentoComponent ); } } @@ -140,29 +189,34 @@ private void loadModules() { } } +@SuppressWarnings("checkstyle:OneTopLevelClass") class MagentoModuleImpl extends MagentoComponentImp implements MagentoModule { private static final String DEFAULT_MODULE_NAME = "Undefined module"; private static final String CONFIGURATION_PATH = "etc"; private String moduleName; - public MagentoModuleImpl(@NotNull ComposerPackageModel composerPackageModel, @NotNull PsiDirectory directory) { + public MagentoModuleImpl( + final @NotNull ComposerPackageModel composerPackageModel, + final @NotNull PsiDirectory directory + ) { super(composerPackageModel, directory); } + @SuppressWarnings({"PMD.AvoidDeeplyNestedIfStmts"}) @Override public String getMagentoName() { if (moduleName != null) { return moduleName; } - PsiDirectory configurationDir = directory.findSubdirectory(CONFIGURATION_PATH); + final PsiDirectory configurationDir = directory.findSubdirectory(CONFIGURATION_PATH); if (configurationDir != null) { - PsiFile configurationFile = configurationDir.findFile("module.xml"); + final PsiFile configurationFile = configurationDir.findFile("module.xml"); - if (configurationFile != null && configurationFile instanceof XmlFile) { - XmlTag rootTag = ((XmlFile) configurationFile).getRootTag(); + if (configurationFile instanceof XmlFile) { + final XmlTag rootTag = ((XmlFile) configurationFile).getRootTag(); if (rootTag != null) { - XmlTag module = rootTag.findFirstSubTag("module"); + final XmlTag module = rootTag.findFirstSubTag("module"); if (module != null && module.getAttributeValue("name") != null) { moduleName = module.getAttributeValue("name"); return moduleName; diff --git a/src/com/magento/idea/magento2plugin/reference/provider/FilePathReferenceProvider.java b/src/com/magento/idea/magento2plugin/reference/provider/FilePathReferenceProvider.java index fc3b53808..07c9cd0f3 100644 --- a/src/com/magento/idea/magento2plugin/reference/provider/FilePathReferenceProvider.java +++ b/src/com/magento/idea/magento2plugin/reference/provider/FilePathReferenceProvider.java @@ -33,7 +33,8 @@ public class FilePathReferenceProvider extends PsiReferenceProvider { "PMD.CognitiveComplexity", "PMD.CyclomaticComplexity", "PMD.NPathComplexity", - "PMD.AvoidInstantiatingObjectsInLoops" + "PMD.AvoidInstantiatingObjectsInLoops", + "PMD.AvoidDeeplyNestedIfStmts" }) @NotNull @Override @@ -92,14 +93,13 @@ public PsiReference[] getReferencesByElement( if (null != psiElement) { final int currentPathIndex = currentPath.lastIndexOf('/') == -1 ? 0 : currentPath.lastIndexOf('/') + 1; + final int startOffset = origValue.indexOf(filePath) + currentPathIndex; + final int endOffset = startOffset + pathPart.length(); - final TextRange pathRange = new TextRange( - origValue.indexOf(filePath) - + currentPathIndex, - origValue.indexOf(filePath) - + currentPathIndex - + pathPart.length() - ); + if (!isProperRange(startOffset, endOffset)) { + continue; + } + final TextRange pathRange = new TextRange(startOffset, endOffset); if (psiPathElements.containsKey(pathRange)) { psiPathElements.get(pathRange).add(psiElement); @@ -186,4 +186,8 @@ private Collection getFiles(final @NotNull PsiElement element) { private boolean isModuleNamePresent(final @NotNull PsiElement element) { return GetModuleNameUtil.getInstance().execute(element.getText()) != null; } + + private boolean isProperRange(final int startOffset, final int endOffset) { + return startOffset <= endOffset && startOffset >= 0; + } } diff --git a/src/com/magento/idea/magento2plugin/util/RegExUtil.java b/src/com/magento/idea/magento2plugin/util/RegExUtil.java index 41ebb1f8f..194ca170a 100644 --- a/src/com/magento/idea/magento2plugin/util/RegExUtil.java +++ b/src/com/magento/idea/magento2plugin/util/RegExUtil.java @@ -84,6 +84,9 @@ public static class Magento { public static final String TEST_CLASS_FQN = "^(\\\\)?(\\w+\\\\){1}(\\w+\\\\){1}Test(\\\\\\w+)+$"; + public static final String CUSTOM_VENDOR_NAME = + "app\\/code\\/(\\w+)\\/"; + public static final String COMMA_SEPARATED_STRING = "^[^\\s,]+(?:,\\s*[^\\s,]+)*$"; } @@ -114,6 +117,7 @@ public static class JsRegex { } public static class CustomTheme { + public static final String MODULE_NAME = "app\\/design\\/(adminhtml|frontend)\\/\\w*\\/\\w*\\/\\w*"; } diff --git a/src/com/magento/idea/magento2plugin/util/magento/GetMagentoModuleUtil.java b/src/com/magento/idea/magento2plugin/util/magento/GetMagentoModuleUtil.java index f1218c26b..3c4541f34 100644 --- a/src/com/magento/idea/magento2plugin/util/magento/GetMagentoModuleUtil.java +++ b/src/com/magento/idea/magento2plugin/util/magento/GetMagentoModuleUtil.java @@ -18,7 +18,10 @@ import com.magento.idea.magento2plugin.magento.files.RegistrationPhp; import com.magento.idea.magento2plugin.magento.packages.ComponentType; import com.magento.idea.magento2plugin.magento.packages.Package; +import com.magento.idea.magento2plugin.util.RegExUtil; import java.util.Collection; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -49,12 +52,9 @@ public static MagentoModuleData getByContext( if (registrationFile == null) { return null; } - final PsiDirectory configDir = registrationFile - .getContainingDirectory() - .findSubdirectory(Package.moduleBaseAreaDir); - final PsiDirectory viewDir = registrationFile - .getContainingDirectory() - .findSubdirectory(Package.moduleViewDir); + final PsiDirectory moduleDir = registrationFile.getContainingDirectory(); + final PsiDirectory configDir = moduleDir.findSubdirectory(Package.moduleBaseAreaDir); + final PsiDirectory viewDir = moduleDir.findSubdirectory(Package.moduleViewDir); final Collection methodReferences = PsiTreeUtil.findChildrenOfType( registrationFile, MethodReference.class @@ -80,12 +80,42 @@ public static MagentoModuleData getByContext( return null; } - return new MagentoModuleData(name, resolvedType, configDir, viewDir); + return new MagentoModuleData(name, resolvedType, moduleDir, configDir, viewDir); } return null; } + /** + * Check if specified module is in the app/code directory. + * + * @param moduleData MagentoModuleData + * + * @return boolean + */ + public static boolean isEditableModule(final @NotNull MagentoModuleData moduleData) { + final Pattern pattern = Pattern.compile(RegExUtil.Magento.CUSTOM_VENDOR_NAME); + final Matcher matcher = pattern.matcher( + moduleData.getModuleDir().getVirtualFile().getPath() + ); + + return matcher.find(); + } + + /** + * Check if specified directory is in the app/code. + * + * @param directory PsiDirectory + * + * @return boolean + */ + public static boolean isDirectoryInEditableModule(final @NotNull PsiDirectory directory) { + final Pattern pattern = Pattern.compile(RegExUtil.Magento.CUSTOM_VENDOR_NAME); + final Matcher matcher = pattern.matcher(directory.getVirtualFile().getPath()); + + return matcher.find(); + } + private static PsiFile getModuleRegistrationFile( final @NotNull PsiDirectory directory, final @NotNull String basePath @@ -136,6 +166,7 @@ public static class MagentoModuleData { private final String name; private final ComponentType type; + private final PsiDirectory moduleDir; private final PsiDirectory configDir; private final PsiDirectory viewDir; @@ -144,12 +175,14 @@ public static class MagentoModuleData { * * @param name String * @param type ComponentType + * @param moduleDir PsiDirectory */ public MagentoModuleData( final @NotNull String name, - final @NotNull ComponentType type + final @NotNull ComponentType type, + final @NotNull PsiDirectory moduleDir ) { - this(name, type, null, null); + this(name, type, moduleDir, null, null); } /** @@ -157,17 +190,20 @@ public MagentoModuleData( * * @param name String * @param type ComponentType + * @param moduleDir PsiDirectory * @param configDir PsiDirectory * @param viewDir PsiDirectory */ public MagentoModuleData( final @NotNull String name, final @NotNull ComponentType type, + final @NotNull PsiDirectory moduleDir, final @Nullable PsiDirectory configDir, final @Nullable PsiDirectory viewDir ) { this.name = name; this.type = type; + this.moduleDir = moduleDir; this.configDir = configDir; this.viewDir = viewDir; } @@ -180,6 +216,10 @@ public ComponentType getType() { return type; } + public PsiDirectory getModuleDir() { + return moduleDir; + } + public @Nullable PsiDirectory getConfigDir() { return configDir; } diff --git a/src/com/magento/idea/magento2plugin/util/magento/MagentoBasePathUtil.java b/src/com/magento/idea/magento2plugin/util/magento/MagentoBasePathUtil.java index 66a7924ff..bd94ef7dc 100644 --- a/src/com/magento/idea/magento2plugin/util/magento/MagentoBasePathUtil.java +++ b/src/com/magento/idea/magento2plugin/util/magento/MagentoBasePathUtil.java @@ -34,10 +34,10 @@ public static boolean isMagentoFolderValid(final String path) { return VfsUtil.findRelativeFile( file, Package.frameworkRootComposer.split(Package.V_FILE_SEPARATOR) - ) != null - || VfsUtil.findRelativeFile( - file, - Package.frameworkRootGit.split(Package.V_FILE_SEPARATOR)) != null; + ) != null || VfsUtil.findRelativeFile( + file, + Package.frameworkRootGit.split(Package.V_FILE_SEPARATOR) + ) != null; } return false;