Skip to content

Commit

Permalink
Merge pull request #2320 from Haehnchen/feature/controller-new
Browse files Browse the repository at this point in the history
migrate Symfony controller action and including template guessing
  • Loading branch information
Haehnchen authored Mar 31, 2024
2 parents 4398d69 + fcfeadc commit 0fbd632
Show file tree
Hide file tree
Showing 8 changed files with 194 additions and 79 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@
import java.util.HashMap;
import java.util.List;

/**
* @author Daniel Espendiller <[email protected]>
*/
public class NewCommandAction extends AbstractProjectDumbAwareAction {
public NewCommandAction() {
super("Command", "Create Command Class", Symfony2Icons.SYMFONY);
Expand Down Expand Up @@ -49,6 +52,10 @@ public void actionPerformed(@NotNull AnActionEvent event) {
return;
}

if (!className.toLowerCase().endsWith("command")) {
className += "Command";
}

if (!PhpNameUtil.isValidClassName(className)) {
JOptionPane.showMessageDialog(null, "Invalid class name");
return;
Expand All @@ -60,16 +67,17 @@ public void actionPerformed(@NotNull AnActionEvent event) {
return;
}

String finalClassName = className;
ApplicationManager.getApplication().runWriteAction(() -> {
HashMap<String, String> hashMap = new HashMap<>() {{
String clazz = className;
if (className.endsWith("Command")) {
clazz = className.substring(0, "Command".length());
String clazz = finalClassName;
if (finalClassName.endsWith("Command")) {
clazz = finalClassName.substring(0, finalClassName.length() - "Command".length());
}

String prefix = NewFileActionUtil.getCommandPrefix(directory);

put("class", className);
put("class", finalClassName);
put("namespace", strings.get(0));
put("command_name", prefix + ":" + fr.adrienbrault.idea.symfony2plugin.util.StringUtils.underscore(clazz));
}};
Expand All @@ -78,7 +86,7 @@ public void actionPerformed(@NotNull AnActionEvent event) {
project,
directory.getVirtualFile(),
NewFileActionUtil.guessCommandTemplateType(project),
className,
finalClassName,
hashMap
);

Expand All @@ -94,8 +102,7 @@ public void update(AnActionEvent event) {
return;
}

PsiDirectory directory = NewFileActionUtil.getSelectedDirectoryFromAction(event);
this.setStatus(event, directory != null && "Command".equals(directory.getName()));
this.setStatus(event, NewFileActionUtil.isInGivenDirectoryScope(event, "Command"));
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
package fr.adrienbrault.idea.symfony2plugin.action;

import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.fileEditor.OpenFileDescriptor;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.Messages;
import com.intellij.psi.PsiDirectory;
import com.intellij.psi.PsiElement;
import com.jetbrains.php.refactoring.PhpNameUtil;
import com.jetbrains.php.roots.PhpNamespaceCompositeProvider;
import fr.adrienbrault.idea.symfony2plugin.Symfony2Icons;
import fr.adrienbrault.idea.symfony2plugin.Symfony2ProjectComponent;
import fr.adrienbrault.idea.symfony2plugin.util.psi.PhpBundleFileFactory;
import org.apache.commons.lang3.StringUtils;
import org.jetbrains.annotations.NotNull;

import javax.swing.*;
import java.util.HashMap;
import java.util.List;

/**
* @author Daniel Espendiller <[email protected]>
*/
public class NewControllerAction extends AbstractProjectDumbAwareAction {
public NewControllerAction() {
super("Controller", "Create Controller Class", Symfony2Icons.SYMFONY);
}

public void update(AnActionEvent event) {
this.setStatus(event, false);
Project project = getEventProject(event);
if (!Symfony2ProjectComponent.isEnabled(project)) {
return;
}

if (NewFileActionUtil.getSelectedDirectoryFromAction(event) != null) {
this.setStatus(event, true);
}
}

@Override
public void actionPerformed(@NotNull AnActionEvent event) {
PsiDirectory directory = NewFileActionUtil.getSelectedDirectoryFromAction(event);
if (directory == null) {
return;
}

Project project = getEventProject(event);
String className = Messages.showInputDialog(project, "New class name:", "New File", Symfony2Icons.SYMFONY);
if (StringUtils.isBlank(className)) {
return;
}

if (!className.toLowerCase().endsWith("controller")) {
className += "Controller";
}

if (!PhpNameUtil.isValidClassName(className)) {
JOptionPane.showMessageDialog(null, "Invalid class name");
return;
}

List<String> strings = PhpNamespaceCompositeProvider.INSTANCE.suggestNamespaces(directory);
if (strings.isEmpty()) {
JOptionPane.showMessageDialog(null, "No namespace found");
return;
}

String finalClassName = className;
ApplicationManager.getApplication().runWriteAction(() -> {
HashMap<String, String> hashMap = new HashMap<>() {{
String clazz = finalClassName;
if (finalClassName.toLowerCase().endsWith("controller")) {
clazz = finalClassName.substring(0, finalClassName.length() - "controller".length());
}

put("class", finalClassName);
put("namespace", strings.get(0));
put("path", "/" + fr.adrienbrault.idea.symfony2plugin.util.StringUtils.underscore(clazz).replace("_", "-"));
put("template_path", fr.adrienbrault.idea.symfony2plugin.util.StringUtils.underscore(clazz));
}};

PsiElement commandAttributes = PhpBundleFileFactory.createFile(
project,
directory.getVirtualFile(),
NewFileActionUtil.guessControllerTemplateType(project),
finalClassName,
hashMap
);

new OpenFileDescriptor(project, commandAttributes.getContainingFile().getVirtualFile(), 0).navigate(true);
});
}

public static class Shortcut extends NewControllerAction {
@Override
public void update(AnActionEvent event) {
Project project = getEventProject(event);
if (!Symfony2ProjectComponent.isEnabled(project)) {
return;
}

this.setStatus(event, NewFileActionUtil.isInGivenDirectoryScope(event, "Controller"));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,30 @@ public static PsiDirectory getSelectedDirectoryFromAction(@NotNull AnActionEvent

}

public static boolean isInGivenDirectoryScope(@NotNull AnActionEvent event, @NotNull String directoryName) {
DataContext dataContext = event.getDataContext();
IdeView view = LangDataKeys.IDE_VIEW.getData(dataContext);
if (view == null) {
return false;
}

PsiDirectory @NotNull [] directories = view.getDirectories();
if (directories.length == 0) {
return false;
}

if (directoryName.equals(directories[0].getName())) {
return true;
}

PsiDirectory parent = directories[0].getParent();
if (parent != null && directoryName.equals(parent.getName())) {
return true;
}

return false;
}

public static String guessCommandTemplateType(@NotNull Project project) {
if (PhpElementsUtil.getClassInterface(project, "\\Symfony\\Component\\Console\\Attribute\\AsCommand") != null) {
return "command_attributes";
Expand All @@ -50,6 +74,14 @@ public static String guessCommandTemplateType(@NotNull Project project) {
return "command_configure";
}

public static String guessControllerTemplateType(@NotNull Project project) {
if (PhpElementsUtil.getClassInterface(project, "\\Symfony\\Component\\Routing\\Attribute\\Route") != null) {
return "controller_attributes";
}

return "controller_annotations";
}

public static String getCommandPrefix(@NotNull PsiDirectory psiDirectory) {
List<String> strings = PhpNamespaceCompositeProvider.INSTANCE.suggestNamespaces(psiDirectory).stream().filter(s -> !s.isBlank()).toList();
if (!strings.isEmpty()) {
Expand Down

This file was deleted.

3 changes: 2 additions & 1 deletion src/main/resources/META-INF/plugin.xml
Original file line number Diff line number Diff line change
Expand Up @@ -779,11 +779,11 @@
<group id="SymfonyGroup" text="Symfony" popup="false">
<group id="SymfonyNewFile" class="com.intellij.ide.actions.NonTrivialActionGroup" text="Symfony" popup="true" icon="SymfonyIcons.Symfony">
<action id="SymfonyNewCommandAction" class="fr.adrienbrault.idea.symfony2plugin.action.NewCommandAction"/>
<action id="SymfonyNewControllerAction" class="fr.adrienbrault.idea.symfony2plugin.action.NewControllerAction"/>
<separator/>
<action id="Symfony2NewXmlService" class="fr.adrienbrault.idea.symfony2plugin.action.NewXmlServiceAction"/>
<action id="Symfony2NewYamlService" class="fr.adrienbrault.idea.symfony2plugin.action.NewYamlServiceAction"/>
</group>
<action id="Symfony2NewControllerService" class="fr.adrienbrault.idea.symfony2plugin.action.bundle.NewBundleControllerAction"/>
<action id="SymfonyBundleCompilerPass" class="fr.adrienbrault.idea.symfony2plugin.action.bundle.NewBundleCompilerPass"/>
<action id="SymfonyBundleFormAction" class="fr.adrienbrault.idea.symfony2plugin.action.bundle.NewBundleFormAction"/>
<action id="SymfonyBundleTwigExtensionAction" class="fr.adrienbrault.idea.symfony2plugin.action.bundle.NewBundleTwigExtensionAction"/>
Expand All @@ -792,6 +792,7 @@

<group id="SymfonyGroupShortcut" text="Symfony" popup="false">
<action id="SymfonyNewCommandActionShortcut" class="fr.adrienbrault.idea.symfony2plugin.action.NewCommandAction$Shortcut"/>
<action id="SymfonyNewControllerActionShortcut" class="fr.adrienbrault.idea.symfony2plugin.action.NewControllerAction$Shortcut"/>
<add-to-group group-id="NewGroup" anchor="before" relative-to-action="SymfonyGroup" />
</group>

Expand Down
13 changes: 0 additions & 13 deletions src/main/resources/fileTemplates/controller.php

This file was deleted.

21 changes: 21 additions & 0 deletions src/main/resources/fileTemplates/controller_annotations.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?php

declare(strict_types=1);

namespace {{ namespace }};

use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;

class {{ class }} extends AbstractController
{

/**
* @Route("{{ path }}")
*/
public function index(): Response
{
return $this->render('{{ template_path }}/index.html.twig');
}
}
18 changes: 18 additions & 0 deletions src/main/resources/fileTemplates/controller_attributes.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php

declare(strict_types=1);

namespace {{ namespace }};

use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;

class {{ class }} extends AbstractController
{
#[Route('{{ path }}')]
public function index(): Response
{
return $this->render('{{ template_path }}/index.html.twig');
}
}

0 comments on commit 0fbd632

Please sign in to comment.