diff --git a/resources/META-INF/plugin.xml b/resources/META-INF/plugin.xml index 45ba1193a..b0cc5b59f 100644 --- a/resources/META-INF/plugin.xml +++ b/resources/META-INF/plugin.xml @@ -75,6 +75,7 @@ + diff --git a/resources/fileTemplates/internal/Magento Layout XML.xml.ft b/resources/fileTemplates/internal/Magento Layout XML.xml.ft index 46efc847d..76f98fb5e 100644 --- a/resources/fileTemplates/internal/Magento Layout XML.xml.ft +++ b/resources/fileTemplates/internal/Magento Layout XML.xml.ft @@ -1,4 +1,10 @@ #parse("XML File Header.xml") - +#if (${IS_ADMIN} == "true") + #set ($isAdmin = true) +#else + #set ($isAdmin = false) +#end + diff --git a/resources/magento2/common.properties b/resources/magento2/common.properties index 7270fbea4..01ad830e0 100644 --- a/resources/magento2/common.properties +++ b/resources/magento2/common.properties @@ -72,4 +72,5 @@ common.template.type=Email Type common.diagnostic.reportButtonText=Report Me common.diagnostic.reportSubmittedTitle=The report is successfully submitted! common.diagnostic.reportSubmittedMessage=Thank you for submitting your report! We will check it as soon as possible. +common.layout.filename=Layout File Name common.targetMethod=Target Method diff --git a/resources/magento2/validation.properties b/resources/magento2/validation.properties index 83170d817..e3e52c9c0 100644 --- a/resources/magento2/validation.properties +++ b/resources/magento2/validation.properties @@ -45,3 +45,5 @@ validator.dbSchema.invalidColumnType=Invalid ''{0}'' column type specified validator.arrayValuesDialog.invalidValueForRowWithName=Invalid value ''{0}'' specified for the row with name ''{1}'' validator.arrayValuesDialog.namesMustBeUnique=Duplicated items names validator.arrayValuesDialog.nameMustNotBeEmpty=The array name cannot be empty +validator.layoutNameRuleInvalid=The layout name is invalid +validator.layoutNameUnderscoreQtyInvalid=Wrong layout name, please check diff --git a/src/com/magento/idea/magento2plugin/actions/context/xml/NewLayoutXmlAction.java b/src/com/magento/idea/magento2plugin/actions/context/xml/NewLayoutXmlAction.java new file mode 100644 index 000000000..04e3cc15b --- /dev/null +++ b/src/com/magento/idea/magento2plugin/actions/context/xml/NewLayoutXmlAction.java @@ -0,0 +1,137 @@ +/* + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +package com.magento.idea.magento2plugin.actions.context.xml; + +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.actionSystem.LangDataKeys; +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.actions.generation.dialog.NewLayoutTemplateDialog; +import com.magento.idea.magento2plugin.magento.files.LayoutXml; +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.project.Settings; +import com.magento.idea.magento2plugin.util.magento.GetMagentoModuleUtil; +import java.util.Arrays; +import java.util.List; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +public class NewLayoutXmlAction extends AnAction { + + public static final String ACTION_NAME = "Magento 2 Layout File"; + public static final String ACTION_DESCRIPTION = "Create a new Magento 2 layout.xml file"; + private PsiDirectory targetDirectory; + + /** + * New layout.xml file generation action constructor. + */ + public NewLayoutXmlAction() { + super(ACTION_NAME, ACTION_DESCRIPTION, MagentoIcons.MODULE); + } + + @Override + @SuppressWarnings({"PMD.CyclomaticComplexity", "PMD.NPathComplexity"}) + public void update(final @NotNull AnActionEvent event) { + setIsAvailableForEvent(event, false); + final Project project = event.getProject(); + + if (project == null || !Settings.isEnabled(project)) { + return; + } + final DataContext context = event.getDataContext(); + final PsiElement targetElement = LangDataKeys.PSI_ELEMENT.getData(context); + final PsiDirectory targetDirectoryCandidate = resolveTargetDirectory(targetElement); + + if (targetDirectoryCandidate == null) { + return; + } + final GetMagentoModuleUtil.MagentoModuleData moduleData = GetMagentoModuleUtil + .getByContext(targetDirectoryCandidate, project); + + if (moduleData == null) { + return; + } + final PsiDirectory viewDir = moduleData.getViewDir(); + + if (viewDir == null) { + return; + } + final List allowedDirectories = Arrays.asList( + Package.moduleViewDir, + Areas.adminhtml.toString(), + Areas.frontend.toString() + ); + if (!allowedDirectories.contains(targetDirectoryCandidate.getName()) + || !moduleData.getType().equals(ComponentType.module)) { + return; + } + final PsiDirectory parentDir = targetDirectoryCandidate.getParentDirectory(); + + if (parentDir == null + || !targetDirectoryCandidate.equals(viewDir) && !parentDir.equals(viewDir)) { + return; + } + targetDirectory = targetDirectoryCandidate; + setIsAvailableForEvent(event, true); + } + + @Override + public void actionPerformed(final @NotNull AnActionEvent event) { + if (event.getProject() == null || targetDirectory == null) { + return; + } + + NewLayoutTemplateDialog.open(event.getProject(), targetDirectory); + } + + /** + * Set is action available for event. + * + * @param event AnActionEvent + * @param isAvailable boolean + */ + private void setIsAvailableForEvent( + final @NotNull AnActionEvent event, + final boolean isAvailable + ) { + event.getPresentation().setVisible(isAvailable); + event.getPresentation().setEnabled(isAvailable); + } + + /** + * Resolve target directory. + * + * @param targetElement PsiElement + * + * @return PsiDirectory + */ + private @Nullable PsiDirectory resolveTargetDirectory(final PsiElement targetElement) { + PsiDirectory target = null; + + if (targetElement instanceof PsiDirectory) { + target = (PsiDirectory) targetElement; + } else if (targetElement instanceof PsiFile) { + target = ((PsiFile) targetElement).getContainingDirectory(); + } + + if (target == null) { + return null; + } + + if (LayoutXml.PARENT_DIR.equals(target.getName())) { + target = target.getParentDirectory(); + } + + return target; + } +} diff --git a/src/com/magento/idea/magento2plugin/actions/generation/data/LayoutXmlData.java b/src/com/magento/idea/magento2plugin/actions/generation/data/LayoutXmlData.java index 3be8921b5..c9727dbb1 100644 --- a/src/com/magento/idea/magento2plugin/actions/generation/data/LayoutXmlData.java +++ b/src/com/magento/idea/magento2plugin/actions/generation/data/LayoutXmlData.java @@ -39,6 +39,30 @@ public LayoutXmlData( this.uiComponentName = uiComponentName; } + /** + * Layout XML data. + * + * @param area String + * @param route String + * @param moduleName String + * @param controllerName String + * @param actionName String + */ + public LayoutXmlData( + final String area, + final String route, + final String moduleName, + final String controllerName, + final String actionName + ) { + this.area = area; + this.route = route; + this.moduleName = moduleName; + this.controllerName = controllerName; + this.actionName = actionName; + this.uiComponentName = ""; + } + public String getArea() { return area; } diff --git a/src/com/magento/idea/magento2plugin/actions/generation/dialog/NewLayoutTemplateDialog.form b/src/com/magento/idea/magento2plugin/actions/generation/dialog/NewLayoutTemplateDialog.form new file mode 100644 index 000000000..f5c0221d5 --- /dev/null +++ b/src/com/magento/idea/magento2plugin/actions/generation/dialog/NewLayoutTemplateDialog.form @@ -0,0 +1,113 @@ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/src/com/magento/idea/magento2plugin/actions/generation/dialog/NewLayoutTemplateDialog.java b/src/com/magento/idea/magento2plugin/actions/generation/dialog/NewLayoutTemplateDialog.java new file mode 100644 index 000000000..9dc5507af --- /dev/null +++ b/src/com/magento/idea/magento2plugin/actions/generation/dialog/NewLayoutTemplateDialog.java @@ -0,0 +1,246 @@ +/* + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +package com.magento.idea.magento2plugin.actions.generation.dialog; + +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.ComboBox; +import com.intellij.psi.PsiDirectory; +import com.magento.idea.magento2plugin.actions.context.xml.NewLayoutXmlAction; +import com.magento.idea.magento2plugin.actions.generation.data.LayoutXmlData; +import com.magento.idea.magento2plugin.actions.generation.data.ui.ComboBoxItemData; +import com.magento.idea.magento2plugin.actions.generation.dialog.util.DialogFieldErrorUtil; +import com.magento.idea.magento2plugin.actions.generation.dialog.validator.annotation.FieldValidation; +import com.magento.idea.magento2plugin.actions.generation.dialog.validator.annotation.RuleRegistry; +import com.magento.idea.magento2plugin.actions.generation.dialog.validator.rule.IdentifierRule; +import com.magento.idea.magento2plugin.actions.generation.dialog.validator.rule.NotEmptyRule; +import com.magento.idea.magento2plugin.actions.generation.generator.LayoutXmlTemplateGenerator; +import com.magento.idea.magento2plugin.bundles.ValidatorBundle; +import com.magento.idea.magento2plugin.magento.packages.Areas; +import com.magento.idea.magento2plugin.util.magento.GetModuleNameByDirectoryUtil; +import java.awt.event.KeyEvent; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; +import java.util.HashMap; +import java.util.Map; +import javax.swing.JButton; +import javax.swing.JComboBox; +import javax.swing.JComponent; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JTextField; +import javax.swing.KeyStroke; +import org.jetbrains.annotations.NotNull; + +public class NewLayoutTemplateDialog extends AbstractDialog { + + private static final String LAYOUT_NAME = "Layout Name"; + + private final @NotNull Project project; + private final String moduleName; + private final PsiDirectory directory; + + private JPanel contentPane; + private JButton buttonOK; + private JButton buttonCancel; + + @FieldValidation(rule = RuleRegistry.NOT_EMPTY, message = {NotEmptyRule.MESSAGE, LAYOUT_NAME}) + @FieldValidation(rule = RuleRegistry.LAYOUT_NAME, + message = {IdentifierRule.MESSAGE, LAYOUT_NAME}) + private JTextField layoutName; + + private JComboBox area; + + // labels + private JLabel layoutNameLabel; // NOPMD + private JLabel areaLabel; // NOPMD + private JLabel layoutNameErrorMessage; // NOPMD + + /** + * NewLayoutTemplateDialog constructor. + * + * @param project Project + * @param directory PsiDirectory + */ + public NewLayoutTemplateDialog( + final @NotNull Project project, + final @NotNull PsiDirectory directory + ) { + super(); + + this.project = project; + this.moduleName = GetModuleNameByDirectoryUtil.execute(directory, project); + this.directory = directory; + + setContentPane(contentPane); + setModal(true); + setTitle(NewLayoutXmlAction.ACTION_DESCRIPTION); + getRootPane().setDefaultButton(buttonOK); + + buttonOK.addActionListener(event -> onOK()); + buttonCancel.addActionListener(event -> onCancel()); + + // call onCancel() when cross is clicked + setDefaultCloseOperation(DO_NOTHING_ON_CLOSE); + addWindowListener(new WindowAdapter() { + @Override + public void windowClosing(final WindowEvent event) { + onCancel(); + } + }); + + // call onCancel() on ESCAPE + contentPane.registerKeyboardAction( + event -> onCancel(), + KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), + JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT + ); + + addComponentListener(new FocusOnAFieldListener(() -> area.requestFocusInWindow())); + autoSelectCurrentArea(); + } + + /** + * Open a new layout template dialog. + * + * @param project Project + * @param directory Directory + */ + public static void open( + final @NotNull Project project, + final @NotNull PsiDirectory directory + ) { + final NewLayoutTemplateDialog dialog = new NewLayoutTemplateDialog(project, directory); + dialog.pack(); + dialog.centerDialog(dialog); + dialog.setVisible(true); + } + + /** + * Fire generation process if all fields are valid. + */ + private void onOK() { + if (validateFormFields() && isUnderscoreCorrect()) { + final String[] layoutNameParts = getLayoutNameParts(); + new LayoutXmlTemplateGenerator( + new LayoutXmlData( + getArea(), + layoutNameParts[0], + moduleName, + layoutNameParts[1], + layoutNameParts[2] + ), + project + ).generate(NewLayoutXmlAction.ACTION_NAME, true); + exit(); + } + } + + /** + * Create custom components and fill their entries. + */ + @SuppressWarnings({"PMD.UnusedPrivateMethod", "PMD.AvoidInstantiatingObjectsInLoops"}) + private void createUIComponents() { + area = new ComboBox<>(); + + for (final Areas areaEntry : Areas.values()) { + if (!areaEntry.equals(Areas.adminhtml) && !areaEntry.equals(Areas.frontend)) { + continue; + } + area.addItem(new ComboBoxItemData(areaEntry.toString(), areaEntry.toString())); + } + } + + private void autoSelectCurrentArea() { + final String selectedDirName = directory.getName(); + final Map areaIndexMap = new HashMap<>(); + + for (int i = 0; i < area.getItemCount(); i++) { + final ComboBoxItemData item = area.getItemAt(i); + areaIndexMap.put(item.getKey(), i); + } + + if (areaIndexMap.containsKey(selectedDirName)) { + area.setSelectedIndex(areaIndexMap.get(selectedDirName)); + } + } + + /** + * Get parts of inserted layout name. + * + * @return String[] + */ + private String[] getLayoutNameParts() { + + final String[] layoutNameParts = layoutName.getText().trim().split("_"); + String routeName = ""; + String controllerName = ""; + String actionName = ""; + + if (layoutNameParts.length >= 1) { // NOPMD + routeName = layoutNameParts[0]; + } + + if (layoutNameParts.length == 3) { // NOPMD + controllerName = layoutNameParts[1]; + actionName = layoutNameParts[2]; + } + + return new String[]{routeName, controllerName, actionName}; + } + + /** + * Check is count of underscore is correct in layout name. + * + * @return boolean + */ + private boolean isUnderscoreCorrect() { + final String name = layoutName.getText().trim(); + + if (name.contains("_")) { + final int count = countUnderscore(name); + + if (count != 0 && count != 2) { + DialogFieldErrorUtil.showErrorMessageForField( + layoutName, + layoutNameErrorMessage, + new ValidatorBundle() + .message("validator.layoutNameUnderscoreQtyInvalid") + ); + + return false; + } + } + + return true; + } + + /** + * Count underscore symbols in string. + * + * @param name String + * @return int + */ + private int countUnderscore(final String name) { + int count = 0; + + for (int i = 0; i < name.length(); i++) { + if (name.charAt(i) == '_') { //NOPMD + count++; + } + } + + return count; + } + + /** + * Get area. + * + * @return String + */ + private String getArea() { + return area.getSelectedItem().toString(); + } +} diff --git a/src/com/magento/idea/magento2plugin/actions/generation/dialog/util/DialogFieldErrorUtil.java b/src/com/magento/idea/magento2plugin/actions/generation/dialog/util/DialogFieldErrorUtil.java index 80c12d54a..385fc1566 100644 --- a/src/com/magento/idea/magento2plugin/actions/generation/dialog/util/DialogFieldErrorUtil.java +++ b/src/com/magento/idea/magento2plugin/actions/generation/dialog/util/DialogFieldErrorUtil.java @@ -19,6 +19,7 @@ import javax.swing.JTextField; import javax.swing.UIManager; import javax.swing.border.Border; +import javax.swing.text.JTextComponent; import org.jetbrains.annotations.NotNull; public final class DialogFieldErrorUtil { @@ -165,6 +166,40 @@ public void focusLost(final FocusEvent event) { return true; } + /** + * Show error message for field for component. + * + * @param fieldComponent JTextComponent + * @param messageHolder JLabel + * @param message String + */ + public static void showErrorMessageForField( + final @NotNull JTextComponent fieldComponent, + final @NotNull JLabel messageHolder, + final @NotNull String message + ) { + highlightField(fieldComponent); + + messageHolder.setVisible(true); + messageHolder.setFont(UIUtil.getLabelFont(UIUtil.FontSize.MINI)); + messageHolder.setForeground(ERROR_COLOR); + messageHolder.setText(message); + + fieldComponent.addFocusListener(new FocusListener() { + @Override + public void focusGained(final FocusEvent event) { + messageHolder.setVisible(false); + messageHolder.setText(""); + } + + @Override + public void focusLost(final FocusEvent event) { + messageHolder.setVisible(false); + messageHolder.setText(""); + } + }); + } + /** * Get message holder component for field. * diff --git a/src/com/magento/idea/magento2plugin/actions/generation/dialog/validator/annotation/RuleRegistry.java b/src/com/magento/idea/magento2plugin/actions/generation/dialog/validator/annotation/RuleRegistry.java index 057126732..14a5ee1de 100644 --- a/src/com/magento/idea/magento2plugin/actions/generation/dialog/validator/annotation/RuleRegistry.java +++ b/src/com/magento/idea/magento2plugin/actions/generation/dialog/validator/annotation/RuleRegistry.java @@ -19,6 +19,7 @@ import com.magento.idea.magento2plugin.actions.generation.dialog.validator.rule.IdentifierRule; import com.magento.idea.magento2plugin.actions.generation.dialog.validator.rule.IdentifierWithColonRule; import com.magento.idea.magento2plugin.actions.generation.dialog.validator.rule.IdentifierWithForwardSlash; +import com.magento.idea.magento2plugin.actions.generation.dialog.validator.rule.LayoutNameRule; import com.magento.idea.magento2plugin.actions.generation.dialog.validator.rule.Lowercase; import com.magento.idea.magento2plugin.actions.generation.dialog.validator.rule.MenuIdentifierRule; import com.magento.idea.magento2plugin.actions.generation.dialog.validator.rule.NotEmptyRule; @@ -57,7 +58,8 @@ public enum RuleRegistry { NUMERIC(NumericRule.class), EXTENDED_NUMERIC(ExtendedNumericRule.class), TABLE_NAME_LENGTH(TableNameLength.class), - MENU_IDENTIFIER(MenuIdentifierRule.class); + MENU_IDENTIFIER(MenuIdentifierRule.class), + LAYOUT_NAME(LayoutNameRule.class); private Class rule; diff --git a/src/com/magento/idea/magento2plugin/actions/generation/dialog/validator/rule/LayoutNameRule.java b/src/com/magento/idea/magento2plugin/actions/generation/dialog/validator/rule/LayoutNameRule.java new file mode 100644 index 000000000..9af322458 --- /dev/null +++ b/src/com/magento/idea/magento2plugin/actions/generation/dialog/validator/rule/LayoutNameRule.java @@ -0,0 +1,24 @@ +/* + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +package com.magento.idea.magento2plugin.actions.generation.dialog.validator.rule; + +import com.magento.idea.magento2plugin.util.RegExUtil; +import org.jetbrains.annotations.NotNull; + +public class LayoutNameRule implements ValidationRule { + + public static final String MESSAGE = "validator.layoutNameRuleInvalid"; + public static final ValidationRule INSTANCE = new LayoutNameRule(); + + @Override + public boolean check(final @NotNull String value) { + return value.matches(RegExUtil.LAYOUT_NAME); + } + + public static ValidationRule getInstance() { + return INSTANCE; + } +} diff --git a/src/com/magento/idea/magento2plugin/actions/generation/generator/LayoutXmlTemplateGenerator.java b/src/com/magento/idea/magento2plugin/actions/generation/generator/LayoutXmlTemplateGenerator.java new file mode 100644 index 000000000..dc95aa570 --- /dev/null +++ b/src/com/magento/idea/magento2plugin/actions/generation/generator/LayoutXmlTemplateGenerator.java @@ -0,0 +1,85 @@ +/* + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +package com.magento.idea.magento2plugin.actions.generation.generator; + +import com.intellij.openapi.command.WriteCommandAction; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiDocumentManager; +import com.intellij.psi.PsiFile; +import com.intellij.psi.xml.XmlFile; +import com.intellij.psi.xml.XmlTag; +import com.magento.idea.magento2plugin.actions.generation.data.LayoutXmlData; +import com.magento.idea.magento2plugin.actions.generation.generator.util.FindOrCreateLayoutXml; +import java.util.Properties; +import org.jetbrains.annotations.NotNull; + +public class LayoutXmlTemplateGenerator extends FileGenerator { + + private final LayoutXmlData layoutXmlData; + private final Project project; + private final FindOrCreateLayoutXml findOrCreateLayoutXml; + + /** + * Constructor. + * + * @param layoutXmlData LayoutXmlData + * @param project Project + */ + public LayoutXmlTemplateGenerator( + final @NotNull LayoutXmlData layoutXmlData, + final Project project + ) { + super(project); + this.layoutXmlData = layoutXmlData; + this.project = project; + this.findOrCreateLayoutXml = new FindOrCreateLayoutXml(project); + } + + /** + * Creates a module layout file. + * + * @param actionName String + * + * @return PsiFile + */ + @Override + public PsiFile generate(final @NotNull String actionName) { + final XmlFile layoutXml = (XmlFile) findOrCreateLayoutXml.execute( + actionName, + layoutXmlData.getRoute(), + layoutXmlData.getControllerName(), + layoutXmlData.getActionName(), + layoutXmlData.getModuleName(), + layoutXmlData.getArea() + ); + + if (layoutXml == null) { + return null; + } + final PsiDocumentManager psiDocumentManager = + PsiDocumentManager.getInstance(project); + final Document document = psiDocumentManager.getDocument(layoutXml); + + if (document == null) { + return null; + } + WriteCommandAction.runWriteCommandAction(project, () -> { + final XmlTag rootTag = layoutXml.getRootTag(); + + if (rootTag == null) { + return; + } + psiDocumentManager.commitDocument(document); + }); + + return layoutXml; + } + + @Override + @SuppressWarnings("PMD.UncommentedEmptyMethodBody") + protected void fillAttributes(final Properties attributes) {} +} diff --git a/src/com/magento/idea/magento2plugin/actions/generation/generator/util/FindOrCreateLayoutXml.java b/src/com/magento/idea/magento2plugin/actions/generation/generator/util/FindOrCreateLayoutXml.java index 177059235..d6b2e8055 100644 --- a/src/com/magento/idea/magento2plugin/actions/generation/generator/util/FindOrCreateLayoutXml.java +++ b/src/com/magento/idea/magento2plugin/actions/generation/generator/util/FindOrCreateLayoutXml.java @@ -15,12 +15,16 @@ import com.magento.idea.magento2plugin.util.magento.FileBasedIndexUtil; import java.util.ArrayList; import java.util.Properties; +import org.jetbrains.annotations.NotNull; public final class FindOrCreateLayoutXml { + private final Project project; + private final Properties properties; public FindOrCreateLayoutXml(final Project project) { this.project = project; + properties = new Properties(); } /** @@ -60,7 +64,12 @@ public PsiFile execute( parentDirectory = directoryGenerator .findOrCreateSubdirectory(parentDirectory, fileDirectory); } - final LayoutXml layoutXml = new LayoutXml(routeId, controllerName, controllerActionName); + + LayoutXml layoutXml = new LayoutXml(routeId, controllerName, controllerActionName); + + if (controllerName.isEmpty()) { + layoutXml = new LayoutXml(routeId); + } PsiFile layoutXmlFile = FileBasedIndexUtil.findModuleViewFile( layoutXml.getFileName(), getArea(area), @@ -69,9 +78,10 @@ public PsiFile execute( LayoutXml.PARENT_DIR ); if (layoutXmlFile == null) { + fillDefaultAttributes(area, properties); layoutXmlFile = fileFromTemplateGenerator.generate( layoutXml, - new Properties(), + properties, parentDirectory, actionName ); @@ -82,4 +92,15 @@ public PsiFile execute( private Areas getArea(final String area) { return Areas.getAreaByString(area); } + + private void fillDefaultAttributes( + final @NotNull String area, + final @NotNull Properties properties + ) { + if (Areas.adminhtml.toString().equals(area)) { + properties.setProperty("IS_ADMIN", Boolean.TRUE.toString()); + } else { + properties.setProperty("IS_ADMIN", Boolean.FALSE.toString()); + } + } } diff --git a/src/com/magento/idea/magento2plugin/magento/files/LayoutXml.java b/src/com/magento/idea/magento2plugin/magento/files/LayoutXml.java index 37faf3f34..cfe0910a8 100644 --- a/src/com/magento/idea/magento2plugin/magento/files/LayoutXml.java +++ b/src/com/magento/idea/magento2plugin/magento/files/LayoutXml.java @@ -11,19 +11,19 @@ @SuppressWarnings({"PMD.FieldNamingConventions", "PMD.ClassNamingConventions"}) public class LayoutXml implements ModuleFileInterface { - public static String DEFAULT_FILENAME = "default.xml"; - public static String CACHEABLE_ATTRIBUTE_NAME = "cacheable"; - public static String CACHEABLE_ATTRIBUTE_VALUE_FALSE = "false"; - public static String BLOCK_ATTRIBUTE_TAG_NAME = "block"; - public static String REFERENCE_BLOCK_ATTRIBUTE_TAG_NAME = "referenceBlock"; - public static String ROOT_TAG_NAME = "body"; - public static String REFERENCE_CONTAINER_TAG_NAME = "referenceContainer"; - public static String UI_COMPONENT_TAG_NAME = "uiComponent"; - public static String XML_ATTRIBUTE_TEMPLATE = "template"; - public static String ARGUMENTS_TEMPLATE = "Magento Module Class Arguments In Xml"; - public static String PARENT_DIR = "layout"; - public static String NAME_ATTRIBUTE = "name"; - public static String CONTENT_CONTAINER_NAME = "content"; + public static final String DEFAULT_FILENAME = "default.xml"; + public static final String CACHEABLE_ATTRIBUTE_NAME = "cacheable"; + public static final String CACHEABLE_ATTRIBUTE_VALUE_FALSE = "false"; + public static final String BLOCK_ATTRIBUTE_TAG_NAME = "block"; + public static final String REFERENCE_BLOCK_ATTRIBUTE_TAG_NAME = "referenceBlock"; + public static final String ROOT_TAG_NAME = "body"; + public static final String REFERENCE_CONTAINER_TAG_NAME = "referenceContainer"; + public static final String UI_COMPONENT_TAG_NAME = "uiComponent"; + public static final String XML_ATTRIBUTE_TEMPLATE = "template"; + public static final String ARGUMENTS_TEMPLATE = "Magento Module Class Arguments In Xml"; + public static final String PARENT_DIR = "layout"; + public static final String NAME_ATTRIBUTE = "name"; + public static final String CONTENT_CONTAINER_NAME = "content"; public static String TEMPLATE = "Magento Layout XML"; private String fileName; @@ -46,6 +46,15 @@ public LayoutXml(final String routeId, final String controllerName, final String ); } + /** + * Layout XML file. + * + * @param routeId String + */ + public LayoutXml(final String routeId) { + this.setFileName(routeId + ".xml"); + } + /** * Get name of file. * diff --git a/src/com/magento/idea/magento2plugin/util/RegExUtil.java b/src/com/magento/idea/magento2plugin/util/RegExUtil.java index 8a8794ba7..2603d8b4b 100644 --- a/src/com/magento/idea/magento2plugin/util/RegExUtil.java +++ b/src/com/magento/idea/magento2plugin/util/RegExUtil.java @@ -49,6 +49,9 @@ public class RegExUtil { public static final String MAGENTO_VERSION = "(\\d+)\\.(\\d+)\\.(\\d+)[a-zA-Z0-9_\\-]*"; + public static final String LAYOUT_NAME + = "^([a-zA-Z0-9]+){1,}(_[a-zA-Z0-9]+){0,2}"; + public static class Magento { public static final String PHP_CLASS diff --git a/src/com/magento/idea/magento2plugin/util/magento/GetMagentoModuleUtil.java b/src/com/magento/idea/magento2plugin/util/magento/GetMagentoModuleUtil.java index 207b7eaf4..503844a89 100644 --- a/src/com/magento/idea/magento2plugin/util/magento/GetMagentoModuleUtil.java +++ b/src/com/magento/idea/magento2plugin/util/magento/GetMagentoModuleUtil.java @@ -51,6 +51,9 @@ public static MagentoModuleData getByContext( final PsiDirectory configDir = registrationFile .getContainingDirectory() .findSubdirectory(Package.moduleBaseAreaDir); + final PsiDirectory viewDir = registrationFile + .getContainingDirectory() + .findSubdirectory(Package.moduleViewDir); final Collection methodReferences = PsiTreeUtil.findChildrenOfType( registrationFile, MethodReference.class @@ -76,7 +79,7 @@ public static MagentoModuleData getByContext( return null; } - return new MagentoModuleData(name, resolvedType, configDir); + return new MagentoModuleData(name, resolvedType, configDir, viewDir); } return null; @@ -130,6 +133,7 @@ public static class MagentoModuleData { private final String name; private final ComponentType type; private final PsiDirectory configDir; + private final PsiDirectory viewDir; /** * Default constructor. @@ -141,7 +145,7 @@ public MagentoModuleData( final @NotNull String name, final @NotNull ComponentType type ) { - this(name, type, null); + this(name, type, null, null); } /** @@ -150,15 +154,18 @@ public MagentoModuleData( * @param name String * @param type ComponentType * @param configDir PsiDirectory + * @param viewDir PsiDirectory */ public MagentoModuleData( final @NotNull String name, final @NotNull ComponentType type, - final @Nullable PsiDirectory configDir + final @Nullable PsiDirectory configDir, + final @Nullable PsiDirectory viewDir ) { this.name = name; this.type = type; this.configDir = configDir; + this.viewDir = viewDir; } public String getName() { @@ -172,5 +179,9 @@ public ComponentType getType() { public @Nullable PsiDirectory getConfigDir() { return configDir; } + + public @Nullable PsiDirectory getViewDir() { + return viewDir; + } } }