diff --git a/.history/src/main/java/com/magento/idea/magento2plugin/init/ConfigurationManager_20250215225312.java b/.history/src/main/java/com/magento/idea/magento2plugin/init/ConfigurationManager_20250215225312.java new file mode 100644 index 000000000..f28d834a9 --- /dev/null +++ b/.history/src/main/java/com/magento/idea/magento2plugin/init/ConfigurationManager_20250215225312.java @@ -0,0 +1,247 @@ +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +package com.magento.idea.magento2plugin.init; + +import com.intellij.notification.Notification; +import com.intellij.notification.NotificationType; +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.application.ModalityState; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.ModuleManager; +import com.intellij.openapi.options.ShowSettingsUtil; +import com.intellij.openapi.project.DumbAwareAction; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.roots.ContentEntry; +import com.intellij.openapi.roots.ModuleRootManager; +import com.intellij.openapi.roots.ModuleRootModificationUtil; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.openapi.vfs.LocalFileSystem; +import com.intellij.openapi.vfs.VfsUtilCore; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.util.PlatformUtils; +import com.jetbrains.php.config.PhpProjectConfigurable; +import com.jetbrains.php.config.library.PhpIncludePathManager; +import com.jetbrains.php.ui.PhpUiUtil; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.function.Function; +import com.magento.idea.magento2plugin.project.Settings; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +public class ConfigurationManager { + private static final ConfigurationManager INSTANCE = new ConfigurationManager(); + + public static ConfigurationManager getInstance() { + return INSTANCE; + } + + private ConfigurationManager() { + } + + public void refreshIncludePaths(Settings.State newState, Project project) { + if (!project.isDefault() && newState.isPluginEnabled() && !newState.isDoNotAskContentConfigAgain()) { + VirtualFile magentoFile = getMagentoFile(newState); + if (magentoFile == null) { + return; + } + + if (VfsUtilCore.isAncestor(project.getBaseDir(), magentoFile, false)) { + return; + } + + boolean isModuleInsideMagento = VfsUtilCore.isAncestor(magentoFile, project.getBaseDir(), false); + if (isModuleInsideMagento) { + Module[] modules = ModuleManager.getInstance(project).getModules(); + if (modules.length == 1) { + Module module = modules[0]; + boolean isMagentoIncluded = isFileInsideModule(magentoFile, module); + if (!isMagentoIncluded) { + suggestToChangeContentRoots(magentoFile, project, module); + } + } + } else { + boolean isMagentoIncluded = isInIncludePath(magentoFile, project); + if (!isMagentoIncluded) { + suggestToAddToIncludePath(magentoFile, project); + } + } + } + + } + + private static void suggestToChangeContentRoots(@NotNull VirtualFile magentoFile, @NotNull Project project, @NotNull Module module) { + String message = "For Magento 2 containing plugins inside it's better to add whole Magento 2 to project."; + Function fixAction = (notification) -> { + return new DumbAwareAction("Fix") { + public void actionPerformed(@NotNull AnActionEvent e) { + notification.expire(); + ModuleRootModificationUtil.updateModel(module, (model) -> { + ContentEntry[] contentEntries = model.getContentEntries(); + ContentEntry rootEntry = null; + ContentEntry[] entries = contentEntries; + int length = contentEntries.length; + + for (int i = 0; i < length; ++i) { + ContentEntry entry = entries[i]; + VirtualFile entryFile = entry.getFile(); + if (entryFile != null && VfsUtilCore.isAncestor(entryFile, project.getBaseDir(), false)) { + rootEntry = entry; + break; + } + } + + if (rootEntry != null) { + VirtualFile rootEntryFile = rootEntry.getFile(); + if (rootEntryFile == null || !VfsUtilCore.isAncestor(rootEntryFile, magentoFile, false)) { + model.addContentEntry(magentoFile); + model.removeContentEntry(rootEntry); + } + } else { + model.addContentEntry(magentoFile); + } + + }); + if (PlatformUtils.isPhpStorm()) { + Runnable runnable = () -> { + ShowSettingsUtil.getInstance().showSettingsDialog(project, "Directories"); + }; + ApplicationManager.getApplication().invokeLater(runnable, ModalityState.NON_MODAL); + } + } + }; + }; + Function ignoreAction = (notification) -> { + return new DumbAwareAction("Ignore") { + public void actionPerformed(@NotNull AnActionEvent e) { + notification.expire(); + Settings.getInstance(project).setDoNotAskContentConfigurationAgain(true); + } + }; + }; + showPopup(project, message, fixAction, ignoreAction); + } + + private static void suggestToAddToIncludePath(@NotNull VirtualFile magentoFile, @NotNull Project project) { + String message = "Magento installation is not added to PHP | Include path"; + Function fixAction = (notification) -> { + return new DumbAwareAction("Fix") { + public void actionPerformed(@NotNull AnActionEvent e) { + notification.expire(); + Runnable runnable = () -> { + PhpIncludePathManager facade = PhpIncludePathManager.getInstance(project); + List includePaths = facade.getIncludePath(); + List newIncludePaths = new ArrayList(includePaths.size() + 1); + newIncludePaths.addAll(includePaths); + String path = magentoFile.getPath(); + newIncludePaths.add(path); + facade.setIncludePath(newIncludePaths); + ApplicationManager.getApplication().invokeLater(() -> { + if (!project.isDisposed()) { + PhpUiUtil.editConfigurable(project, new PhpProjectConfigurable(project)); + } + }); + }; + ApplicationManager.getApplication().runWriteAction(runnable); + } + }; + }; + Function ignoreAction = (notification) -> { + return new DumbAwareAction("Ignore") { + public void actionPerformed(@NotNull AnActionEvent e) { + notification.expire(); + Settings.getInstance(project).setDoNotAskContentConfigurationAgain(true); + } + }; + }; + Function showSettingsAction = (notification) -> { + return new DumbAwareAction("Show settings") { + public void actionPerformed(@NotNull AnActionEvent e) { + notification.expire(); + PhpUiUtil.editConfigurable(project, new PhpProjectConfigurable(project)); + } + }; + }; + showPopup(project, message, fixAction, ignoreAction, showSettingsAction); + } + + public static void suggestToConfigureMagentoPath(@NotNull Project project) { + String message = "Magento 2 support is disabled. Please configure Magento 2 installation path."; + Function showSettingsAction = (notification) -> { + return new DumbAwareAction("Show settings") { + public void actionPerformed(@NotNull AnActionEvent e) { + notification.expire(); + ShowSettingsUtil.getInstance().showSettingsDialog(project, "Magento2.SettingsForm"); + } + }; + }; + showPopup(project, message, showSettingsAction); + } + + private static boolean isInIncludePath(@NotNull VirtualFile fileToCheck, @NotNull Project project) { + List includePaths = PhpIncludePathManager.getInstance(project).getAllIncludedRoots(); + Iterator iterator = includePaths.iterator(); + + VirtualFile file; + do { + if (!iterator.hasNext()) { + return false; + } + + file = (VirtualFile)iterator.next(); + } while(file == null || !VfsUtilCore.isAncestor(file, fileToCheck, false)); + + return true; + } + + @Nullable + private static VirtualFile getMagentoFile(Settings.State state) { + String path = state.getMagentoPath(); + if (StringUtil.isEmpty(path)) { + return null; + } else { + VirtualFile file = LocalFileSystem.getInstance().findFileByPath(path); + return file != null && file.isDirectory() ? file : null; + } + } + + private static boolean isFileInsideModule(@NotNull VirtualFile magentoFile, @NotNull Module module) { + VirtualFile[] contentRoots = ModuleRootManager.getInstance(module).getContentRoots(); + VirtualFile[] roots = contentRoots; + int length = contentRoots.length; + + for (int i = 0; i < length; ++i) { + VirtualFile root = roots[i]; + if (VfsUtilCore.isAncestor(root, magentoFile, false)) { + return true; + } + } + + return false; + } + + private static void showPopup(Project project, String message, Function... actions) { + Runnable runnable = () -> { + notifyGlobally(project, "Magento 2 Support", message, NotificationType.INFORMATION, actions); + }; + ApplicationManager.getApplication().invokeLater(runnable, ModalityState.NON_MODAL); + } + + public static void notifyGlobally(@Nullable Project project, String title, String message, NotificationType notificationType, Function... actions) { + Notification notification = new Notification("Magento 2 Support", title, message, notificationType); + Function[] functions = actions; + int length = actions.length; + + for (int i = 0; i < length; ++i) { + Function generator = functions[i]; + notification.addAction(generator.apply(notification)); + } + + notification.notify(project); + } +} diff --git a/.history/src/main/java/com/magento/idea/magento2plugin/init/ConfigurationManager_20250217134829.java b/.history/src/main/java/com/magento/idea/magento2plugin/init/ConfigurationManager_20250217134829.java new file mode 100644 index 000000000..edd952edc --- /dev/null +++ b/.history/src/main/java/com/magento/idea/magento2plugin/init/ConfigurationManager_20250217134829.java @@ -0,0 +1,176 @@ +package com.magento.idea.magento2plugin.init; + +import com.intellij.notification.Notification; +import com.intellij.notification.NotificationType; +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.application.ModalityState; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.ModuleManager; +import com.intellij.openapi.options.ShowSettingsUtil; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.roots.ContentEntry; +import com.intellij.openapi.roots.ModuleRootManager; +import com.intellij.openapi.roots.ModuleRootModificationUtil; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.openapi.vfs.LocalFileSystem; +import com.intellij.openapi.vfs.VfsUtilCore; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.util.PlatformUtils; +import com.jetbrains.php.config.library.PhpIncludePathManager; +import com.jetbrains.php.ui.PhpUiUtil; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.function.Function; + +public class ConfigurationManager { + private static final ConfigurationManager INSTANCE = new ConfigurationManager(); + + public static ConfigurationManager getInstance() { + return INSTANCE; + } + + private ConfigurationManager() { + } + + public void refreshIncludePaths(Settings.State newState, Project project) { + if (!project.isDefault() && newState.isPluginEnabled() && !newState.isDoNotAskContentConfigAgain()) { + VirtualFile magentoFile = getMagentoFile(newState); + if (magentoFile == null || VfsUtilCore.isAncestor(project.getBaseDir(), magentoFile, false)) { + return; + } + + if (VfsUtilCore.isAncestor(magentoFile, project.getBaseDir(), false)) { + Module[] modules = ModuleManager.getInstance(project).getModules(); + if (modules.length == 1) { + Module module = modules[0]; + if (!isFileInsideModule(magentoFile, module)) { + suggestToChangeContentRoots(magentoFile, project, module); + } + } + } else if (!isInIncludePath(magentoFile, project)) { + suggestToAddToIncludePath(magentoFile, project); + } + } + } + + private static void suggestToChangeContentRoots(@NotNull VirtualFile magentoFile, @NotNull Project project, @NotNull Module module) { + String message = "For Magento 2 containing plugins, it's better to add whole Magento 2 to the project."; + showPopupWithActions(project, message, + createFixAction(() -> updateContentRoots(magentoFile, project, module)), + createIgnoreAction(() -> Settings.getInstance(project).setDoNotAskContentConfigurationAgain(true)) + ); + } + + private static void suggestToAddToIncludePath(@NotNull VirtualFile magentoFile, @NotNull Project project) { + String message = "Magento installation is not added to PHP | Include path"; + showPopupWithActions(project, message, + createFixAction(() -> addToIncludePath(magentoFile, project)), + createIgnoreAction(() -> Settings.getInstance(project).setDoNotAskContentConfigurationAgain(true)), + createShowSettingsAction(() -> PhpUiUtil.editConfigurable(project, new PhpProjectConfigurable(project))) + ); + } + + public static void suggestToConfigureMagentoPath(@NotNull Project project) { + String message = "Magento 2 support is disabled. Please configure Magento 2 installation path."; + showPopupWithActions(project, message, createShowSettingsAction(() -> + ShowSettingsUtil.getInstance().showSettingsDialog(project, "Magento2.SettingsForm")) + ); + } + + private static boolean isInIncludePath(@NotNull VirtualFile fileToCheck, @NotNull Project project) { + List includePaths = PhpIncludePathManager.getInstance(project).getAllIncludedRoots(); + return includePaths.stream().anyMatch(path -> VfsUtilCore.isAncestor(path, fileToCheck, false)); + } + + @Nullable + private static VirtualFile getMagentoFile(Settings.State state) { + String path = state.getMagentoPath(); + if (StringUtil.isEmpty(path)) { + return null; + } + VirtualFile file = LocalFileSystem.getInstance().findFileByPath(path); + return file != null && file.isDirectory() ? file : null; + } + + private static boolean isFileInsideModule(@NotNull VirtualFile magentoFile, @NotNull Module module) { + VirtualFile[] contentRoots = ModuleRootManager.getInstance(module).getContentRoots(); + return contentRoots != null && VfsUtilCore.isAncestor(contentRoots[0], magentoFile, false); + } + + private static void updateContentRoots(@NotNull VirtualFile magentoFile, @NotNull Project project, @NotNull Module module) { + ModuleRootModificationUtil.updateModel(module, model -> { + ContentEntry rootEntry = findRootEntry(model, project.getBaseDir()); + if (rootEntry != null) { + VirtualFile rootEntryFile = rootEntry.getFile(); + if (rootEntryFile == null || !VfsUtilCore.isAncestor(rootEntryFile, magentoFile, false)) { + model.addContentEntry(magentoFile); + model.removeContentEntry(rootEntry); + } + } else { + model.addContentEntry(magentoFile); + } + }); + } + + private static ContentEntry findRootEntry(ModuleRootManager.Model model, VirtualFile baseDir) { + for (ContentEntry entry : model.getContentEntries()) { + VirtualFile entryFile = entry.getFile(); + if (entryFile != null && VfsUtilCore.isAncestor(entryFile, baseDir, false)) { + return entry; + } + } + return null; + } + + private static void addToIncludePath(@NotNull VirtualFile magentoFile, @NotNull Project project) { + PhpIncludePathManager facade = PhpIncludePathManager.getInstance(project); + List includePaths = new ArrayList<>(facade.getIncludePath()); + includePaths.add(magentoFile.getPath()); + facade.setIncludePath(includePaths); + } + + private static void showPopupWithActions(Project project, String message, Function... actions) { + ApplicationManager.getApplication().invokeLater(() -> notifyGlobally(project, "Magento 2 Support", message, NotificationType.INFORMATION, actions)); + } + + private static Function createFixAction(Runnable action) { + return notification -> new DumbAwareAction("Fix") { + public void actionPerformed(@NotNull AnActionEvent e) { + notification.expire(); + action.run(); + } + }; + } + + private static Function createIgnoreAction(Runnable action) { + return notification -> new DumbAwareAction("Ignore") { + public void actionPerformed(@NotNull AnActionEvent e) { + notification.expire(); + action.run(); + } + }; + } + + private static Function createShowSettingsAction(Runnable action) { + return notification -> new DumbAwareAction("Show settings") { + public void actionPerformed(@NotNull AnActionEvent e) { + notification.expire(); + action.run(); + } + }; + } + + public static void notifyGlobally(@Nullable Project project, String title, String message, NotificationType notificationType, Function... actions) { + Notification notification = new Notification("Magento 2 Support", title, message, notificationType); + for (Function generator : actions) { + notification.addAction(generator.apply(notification)); + } + notification.notify(project); + } +} diff --git a/.history/src/main/java/com/magento/idea/magento2plugin/init/ConfigurationManager_20250217134831.java b/.history/src/main/java/com/magento/idea/magento2plugin/init/ConfigurationManager_20250217134831.java new file mode 100644 index 000000000..edd952edc --- /dev/null +++ b/.history/src/main/java/com/magento/idea/magento2plugin/init/ConfigurationManager_20250217134831.java @@ -0,0 +1,176 @@ +package com.magento.idea.magento2plugin.init; + +import com.intellij.notification.Notification; +import com.intellij.notification.NotificationType; +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.application.ModalityState; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.ModuleManager; +import com.intellij.openapi.options.ShowSettingsUtil; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.roots.ContentEntry; +import com.intellij.openapi.roots.ModuleRootManager; +import com.intellij.openapi.roots.ModuleRootModificationUtil; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.openapi.vfs.LocalFileSystem; +import com.intellij.openapi.vfs.VfsUtilCore; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.util.PlatformUtils; +import com.jetbrains.php.config.library.PhpIncludePathManager; +import com.jetbrains.php.ui.PhpUiUtil; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.function.Function; + +public class ConfigurationManager { + private static final ConfigurationManager INSTANCE = new ConfigurationManager(); + + public static ConfigurationManager getInstance() { + return INSTANCE; + } + + private ConfigurationManager() { + } + + public void refreshIncludePaths(Settings.State newState, Project project) { + if (!project.isDefault() && newState.isPluginEnabled() && !newState.isDoNotAskContentConfigAgain()) { + VirtualFile magentoFile = getMagentoFile(newState); + if (magentoFile == null || VfsUtilCore.isAncestor(project.getBaseDir(), magentoFile, false)) { + return; + } + + if (VfsUtilCore.isAncestor(magentoFile, project.getBaseDir(), false)) { + Module[] modules = ModuleManager.getInstance(project).getModules(); + if (modules.length == 1) { + Module module = modules[0]; + if (!isFileInsideModule(magentoFile, module)) { + suggestToChangeContentRoots(magentoFile, project, module); + } + } + } else if (!isInIncludePath(magentoFile, project)) { + suggestToAddToIncludePath(magentoFile, project); + } + } + } + + private static void suggestToChangeContentRoots(@NotNull VirtualFile magentoFile, @NotNull Project project, @NotNull Module module) { + String message = "For Magento 2 containing plugins, it's better to add whole Magento 2 to the project."; + showPopupWithActions(project, message, + createFixAction(() -> updateContentRoots(magentoFile, project, module)), + createIgnoreAction(() -> Settings.getInstance(project).setDoNotAskContentConfigurationAgain(true)) + ); + } + + private static void suggestToAddToIncludePath(@NotNull VirtualFile magentoFile, @NotNull Project project) { + String message = "Magento installation is not added to PHP | Include path"; + showPopupWithActions(project, message, + createFixAction(() -> addToIncludePath(magentoFile, project)), + createIgnoreAction(() -> Settings.getInstance(project).setDoNotAskContentConfigurationAgain(true)), + createShowSettingsAction(() -> PhpUiUtil.editConfigurable(project, new PhpProjectConfigurable(project))) + ); + } + + public static void suggestToConfigureMagentoPath(@NotNull Project project) { + String message = "Magento 2 support is disabled. Please configure Magento 2 installation path."; + showPopupWithActions(project, message, createShowSettingsAction(() -> + ShowSettingsUtil.getInstance().showSettingsDialog(project, "Magento2.SettingsForm")) + ); + } + + private static boolean isInIncludePath(@NotNull VirtualFile fileToCheck, @NotNull Project project) { + List includePaths = PhpIncludePathManager.getInstance(project).getAllIncludedRoots(); + return includePaths.stream().anyMatch(path -> VfsUtilCore.isAncestor(path, fileToCheck, false)); + } + + @Nullable + private static VirtualFile getMagentoFile(Settings.State state) { + String path = state.getMagentoPath(); + if (StringUtil.isEmpty(path)) { + return null; + } + VirtualFile file = LocalFileSystem.getInstance().findFileByPath(path); + return file != null && file.isDirectory() ? file : null; + } + + private static boolean isFileInsideModule(@NotNull VirtualFile magentoFile, @NotNull Module module) { + VirtualFile[] contentRoots = ModuleRootManager.getInstance(module).getContentRoots(); + return contentRoots != null && VfsUtilCore.isAncestor(contentRoots[0], magentoFile, false); + } + + private static void updateContentRoots(@NotNull VirtualFile magentoFile, @NotNull Project project, @NotNull Module module) { + ModuleRootModificationUtil.updateModel(module, model -> { + ContentEntry rootEntry = findRootEntry(model, project.getBaseDir()); + if (rootEntry != null) { + VirtualFile rootEntryFile = rootEntry.getFile(); + if (rootEntryFile == null || !VfsUtilCore.isAncestor(rootEntryFile, magentoFile, false)) { + model.addContentEntry(magentoFile); + model.removeContentEntry(rootEntry); + } + } else { + model.addContentEntry(magentoFile); + } + }); + } + + private static ContentEntry findRootEntry(ModuleRootManager.Model model, VirtualFile baseDir) { + for (ContentEntry entry : model.getContentEntries()) { + VirtualFile entryFile = entry.getFile(); + if (entryFile != null && VfsUtilCore.isAncestor(entryFile, baseDir, false)) { + return entry; + } + } + return null; + } + + private static void addToIncludePath(@NotNull VirtualFile magentoFile, @NotNull Project project) { + PhpIncludePathManager facade = PhpIncludePathManager.getInstance(project); + List includePaths = new ArrayList<>(facade.getIncludePath()); + includePaths.add(magentoFile.getPath()); + facade.setIncludePath(includePaths); + } + + private static void showPopupWithActions(Project project, String message, Function... actions) { + ApplicationManager.getApplication().invokeLater(() -> notifyGlobally(project, "Magento 2 Support", message, NotificationType.INFORMATION, actions)); + } + + private static Function createFixAction(Runnable action) { + return notification -> new DumbAwareAction("Fix") { + public void actionPerformed(@NotNull AnActionEvent e) { + notification.expire(); + action.run(); + } + }; + } + + private static Function createIgnoreAction(Runnable action) { + return notification -> new DumbAwareAction("Ignore") { + public void actionPerformed(@NotNull AnActionEvent e) { + notification.expire(); + action.run(); + } + }; + } + + private static Function createShowSettingsAction(Runnable action) { + return notification -> new DumbAwareAction("Show settings") { + public void actionPerformed(@NotNull AnActionEvent e) { + notification.expire(); + action.run(); + } + }; + } + + public static void notifyGlobally(@Nullable Project project, String title, String message, NotificationType notificationType, Function... actions) { + Notification notification = new Notification("Magento 2 Support", title, message, notificationType); + for (Function generator : actions) { + notification.addAction(generator.apply(notification)); + } + notification.notify(project); + } +} diff --git a/src/main/java/com/magento/idea/magento2plugin/init/ConfigurationManager.java b/src/main/java/com/magento/idea/magento2plugin/init/ConfigurationManager.java index f28d834a9..edd952edc 100644 --- a/src/main/java/com/magento/idea/magento2plugin/init/ConfigurationManager.java +++ b/src/main/java/com/magento/idea/magento2plugin/init/ConfigurationManager.java @@ -1,7 +1,3 @@ -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ package com.magento.idea.magento2plugin.init; import com.intellij.notification.Notification; @@ -13,7 +9,6 @@ import com.intellij.openapi.module.Module; import com.intellij.openapi.module.ModuleManager; import com.intellij.openapi.options.ShowSettingsUtil; -import com.intellij.openapi.project.DumbAwareAction; import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.ContentEntry; import com.intellij.openapi.roots.ModuleRootManager; @@ -23,16 +18,15 @@ import com.intellij.openapi.vfs.VfsUtilCore; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.util.PlatformUtils; -import com.jetbrains.php.config.PhpProjectConfigurable; import com.jetbrains.php.config.library.PhpIncludePathManager; import com.jetbrains.php.ui.PhpUiUtil; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.function.Function; -import com.magento.idea.magento2plugin.project.Settings; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; public class ConfigurationManager { private static final ConfigurationManager INSTANCE = new ConfigurationManager(); @@ -47,156 +41,51 @@ private ConfigurationManager() { public void refreshIncludePaths(Settings.State newState, Project project) { if (!project.isDefault() && newState.isPluginEnabled() && !newState.isDoNotAskContentConfigAgain()) { VirtualFile magentoFile = getMagentoFile(newState); - if (magentoFile == null) { - return; - } - - if (VfsUtilCore.isAncestor(project.getBaseDir(), magentoFile, false)) { + if (magentoFile == null || VfsUtilCore.isAncestor(project.getBaseDir(), magentoFile, false)) { return; } - boolean isModuleInsideMagento = VfsUtilCore.isAncestor(magentoFile, project.getBaseDir(), false); - if (isModuleInsideMagento) { + if (VfsUtilCore.isAncestor(magentoFile, project.getBaseDir(), false)) { Module[] modules = ModuleManager.getInstance(project).getModules(); if (modules.length == 1) { Module module = modules[0]; - boolean isMagentoIncluded = isFileInsideModule(magentoFile, module); - if (!isMagentoIncluded) { + if (!isFileInsideModule(magentoFile, module)) { suggestToChangeContentRoots(magentoFile, project, module); } } - } else { - boolean isMagentoIncluded = isInIncludePath(magentoFile, project); - if (!isMagentoIncluded) { - suggestToAddToIncludePath(magentoFile, project); - } + } else if (!isInIncludePath(magentoFile, project)) { + suggestToAddToIncludePath(magentoFile, project); } } - } private static void suggestToChangeContentRoots(@NotNull VirtualFile magentoFile, @NotNull Project project, @NotNull Module module) { - String message = "For Magento 2 containing plugins inside it's better to add whole Magento 2 to project."; - Function fixAction = (notification) -> { - return new DumbAwareAction("Fix") { - public void actionPerformed(@NotNull AnActionEvent e) { - notification.expire(); - ModuleRootModificationUtil.updateModel(module, (model) -> { - ContentEntry[] contentEntries = model.getContentEntries(); - ContentEntry rootEntry = null; - ContentEntry[] entries = contentEntries; - int length = contentEntries.length; - - for (int i = 0; i < length; ++i) { - ContentEntry entry = entries[i]; - VirtualFile entryFile = entry.getFile(); - if (entryFile != null && VfsUtilCore.isAncestor(entryFile, project.getBaseDir(), false)) { - rootEntry = entry; - break; - } - } - - if (rootEntry != null) { - VirtualFile rootEntryFile = rootEntry.getFile(); - if (rootEntryFile == null || !VfsUtilCore.isAncestor(rootEntryFile, magentoFile, false)) { - model.addContentEntry(magentoFile); - model.removeContentEntry(rootEntry); - } - } else { - model.addContentEntry(magentoFile); - } - - }); - if (PlatformUtils.isPhpStorm()) { - Runnable runnable = () -> { - ShowSettingsUtil.getInstance().showSettingsDialog(project, "Directories"); - }; - ApplicationManager.getApplication().invokeLater(runnable, ModalityState.NON_MODAL); - } - } - }; - }; - Function ignoreAction = (notification) -> { - return new DumbAwareAction("Ignore") { - public void actionPerformed(@NotNull AnActionEvent e) { - notification.expire(); - Settings.getInstance(project).setDoNotAskContentConfigurationAgain(true); - } - }; - }; - showPopup(project, message, fixAction, ignoreAction); + String message = "For Magento 2 containing plugins, it's better to add whole Magento 2 to the project."; + showPopupWithActions(project, message, + createFixAction(() -> updateContentRoots(magentoFile, project, module)), + createIgnoreAction(() -> Settings.getInstance(project).setDoNotAskContentConfigurationAgain(true)) + ); } private static void suggestToAddToIncludePath(@NotNull VirtualFile magentoFile, @NotNull Project project) { String message = "Magento installation is not added to PHP | Include path"; - Function fixAction = (notification) -> { - return new DumbAwareAction("Fix") { - public void actionPerformed(@NotNull AnActionEvent e) { - notification.expire(); - Runnable runnable = () -> { - PhpIncludePathManager facade = PhpIncludePathManager.getInstance(project); - List includePaths = facade.getIncludePath(); - List newIncludePaths = new ArrayList(includePaths.size() + 1); - newIncludePaths.addAll(includePaths); - String path = magentoFile.getPath(); - newIncludePaths.add(path); - facade.setIncludePath(newIncludePaths); - ApplicationManager.getApplication().invokeLater(() -> { - if (!project.isDisposed()) { - PhpUiUtil.editConfigurable(project, new PhpProjectConfigurable(project)); - } - }); - }; - ApplicationManager.getApplication().runWriteAction(runnable); - } - }; - }; - Function ignoreAction = (notification) -> { - return new DumbAwareAction("Ignore") { - public void actionPerformed(@NotNull AnActionEvent e) { - notification.expire(); - Settings.getInstance(project).setDoNotAskContentConfigurationAgain(true); - } - }; - }; - Function showSettingsAction = (notification) -> { - return new DumbAwareAction("Show settings") { - public void actionPerformed(@NotNull AnActionEvent e) { - notification.expire(); - PhpUiUtil.editConfigurable(project, new PhpProjectConfigurable(project)); - } - }; - }; - showPopup(project, message, fixAction, ignoreAction, showSettingsAction); + showPopupWithActions(project, message, + createFixAction(() -> addToIncludePath(magentoFile, project)), + createIgnoreAction(() -> Settings.getInstance(project).setDoNotAskContentConfigurationAgain(true)), + createShowSettingsAction(() -> PhpUiUtil.editConfigurable(project, new PhpProjectConfigurable(project))) + ); } public static void suggestToConfigureMagentoPath(@NotNull Project project) { String message = "Magento 2 support is disabled. Please configure Magento 2 installation path."; - Function showSettingsAction = (notification) -> { - return new DumbAwareAction("Show settings") { - public void actionPerformed(@NotNull AnActionEvent e) { - notification.expire(); - ShowSettingsUtil.getInstance().showSettingsDialog(project, "Magento2.SettingsForm"); - } - }; - }; - showPopup(project, message, showSettingsAction); + showPopupWithActions(project, message, createShowSettingsAction(() -> + ShowSettingsUtil.getInstance().showSettingsDialog(project, "Magento2.SettingsForm")) + ); } private static boolean isInIncludePath(@NotNull VirtualFile fileToCheck, @NotNull Project project) { List includePaths = PhpIncludePathManager.getInstance(project).getAllIncludedRoots(); - Iterator iterator = includePaths.iterator(); - - VirtualFile file; - do { - if (!iterator.hasNext()) { - return false; - } - - file = (VirtualFile)iterator.next(); - } while(file == null || !VfsUtilCore.isAncestor(file, fileToCheck, false)); - - return true; + return includePaths.stream().anyMatch(path -> VfsUtilCore.isAncestor(path, fileToCheck, false)); } @Nullable @@ -204,44 +93,84 @@ private static VirtualFile getMagentoFile(Settings.State state) { String path = state.getMagentoPath(); if (StringUtil.isEmpty(path)) { return null; - } else { - VirtualFile file = LocalFileSystem.getInstance().findFileByPath(path); - return file != null && file.isDirectory() ? file : null; } + VirtualFile file = LocalFileSystem.getInstance().findFileByPath(path); + return file != null && file.isDirectory() ? file : null; } private static boolean isFileInsideModule(@NotNull VirtualFile magentoFile, @NotNull Module module) { VirtualFile[] contentRoots = ModuleRootManager.getInstance(module).getContentRoots(); - VirtualFile[] roots = contentRoots; - int length = contentRoots.length; + return contentRoots != null && VfsUtilCore.isAncestor(contentRoots[0], magentoFile, false); + } + + private static void updateContentRoots(@NotNull VirtualFile magentoFile, @NotNull Project project, @NotNull Module module) { + ModuleRootModificationUtil.updateModel(module, model -> { + ContentEntry rootEntry = findRootEntry(model, project.getBaseDir()); + if (rootEntry != null) { + VirtualFile rootEntryFile = rootEntry.getFile(); + if (rootEntryFile == null || !VfsUtilCore.isAncestor(rootEntryFile, magentoFile, false)) { + model.addContentEntry(magentoFile); + model.removeContentEntry(rootEntry); + } + } else { + model.addContentEntry(magentoFile); + } + }); + } - for (int i = 0; i < length; ++i) { - VirtualFile root = roots[i]; - if (VfsUtilCore.isAncestor(root, magentoFile, false)) { - return true; + private static ContentEntry findRootEntry(ModuleRootManager.Model model, VirtualFile baseDir) { + for (ContentEntry entry : model.getContentEntries()) { + VirtualFile entryFile = entry.getFile(); + if (entryFile != null && VfsUtilCore.isAncestor(entryFile, baseDir, false)) { + return entry; } } + return null; + } + + private static void addToIncludePath(@NotNull VirtualFile magentoFile, @NotNull Project project) { + PhpIncludePathManager facade = PhpIncludePathManager.getInstance(project); + List includePaths = new ArrayList<>(facade.getIncludePath()); + includePaths.add(magentoFile.getPath()); + facade.setIncludePath(includePaths); + } + + private static void showPopupWithActions(Project project, String message, Function... actions) { + ApplicationManager.getApplication().invokeLater(() -> notifyGlobally(project, "Magento 2 Support", message, NotificationType.INFORMATION, actions)); + } + + private static Function createFixAction(Runnable action) { + return notification -> new DumbAwareAction("Fix") { + public void actionPerformed(@NotNull AnActionEvent e) { + notification.expire(); + action.run(); + } + }; + } - return false; + private static Function createIgnoreAction(Runnable action) { + return notification -> new DumbAwareAction("Ignore") { + public void actionPerformed(@NotNull AnActionEvent e) { + notification.expire(); + action.run(); + } + }; } - private static void showPopup(Project project, String message, Function... actions) { - Runnable runnable = () -> { - notifyGlobally(project, "Magento 2 Support", message, NotificationType.INFORMATION, actions); + private static Function createShowSettingsAction(Runnable action) { + return notification -> new DumbAwareAction("Show settings") { + public void actionPerformed(@NotNull AnActionEvent e) { + notification.expire(); + action.run(); + } }; - ApplicationManager.getApplication().invokeLater(runnable, ModalityState.NON_MODAL); } public static void notifyGlobally(@Nullable Project project, String title, String message, NotificationType notificationType, Function... actions) { Notification notification = new Notification("Magento 2 Support", title, message, notificationType); - Function[] functions = actions; - int length = actions.length; - - for (int i = 0; i < length; ++i) { - Function generator = functions[i]; + for (Function generator : actions) { notification.addAction(generator.apply(notification)); } - notification.notify(project); } }