package de.espend.idea.laravel.controller;

import com.intellij.openapi.project.Project;
import com.jetbrains.php.PhpIndex;
import com.jetbrains.php.lang.psi.elements.Method;
import com.jetbrains.php.lang.psi.elements.PhpClass;
import org.jetbrains.annotations.NotNull;

import java.util.Collection;
import java.util.HashSet;
import java.util.Set;

/**
 * @author Daniel Espendiller <daniel@espendiller.net>
 */
public class ControllerCollector {

    public static void visitController(final Project project, ControllerVisitor visitor) {

        Collection<PhpClass> allSubclasses = new HashSet<PhpClass>() {{
            addAll(PhpIndex.getInstance(project).getAllSubclasses("\\Illuminate\\Routing\\Controller"));
            addAll(PhpIndex.getInstance(project).getAllSubclasses("\\App\\Http\\Controllers\\Controller"));
        }};

        for(PhpClass phpClass: allSubclasses) {
            if(!phpClass.isAbstract()) {
                for(Method method: phpClass.getMethods()) {
                    String className = phpClass.getPresentableFQN();
                    if(className != null) {
                        String methodName = method.getName();
                        if(!method.isStatic() && method.getAccess().isPublic() && !methodName.startsWith("__")) {
                            PhpClass phpTrait = method.getContainingClass();
                            if(phpTrait == null || !("ValidatesRequests".equals(phpTrait.getName()) || "DispatchesCommands".equals(phpTrait.getName()) || "Controller".equals(phpTrait.getName()))) {
                                visitor.visit(method, className + "@" + methodName);
                            }
                        }
                    }

                }
            }

        }
    }

    public static interface ControllerVisitor {
        public void visit(@NotNull Method method, String name);
    }

}


@@ -82,16 +82,52 @@
 roject;%0A
+import com.intellij.psi.PsiElement;%0A
 import c
@@ -153,16 +153,66 @@
 pIndex;%0A
+import com.jetbrains.php.lang.psi.elements.Field;%0A
 import c
@@ -307,16 +307,206 @@
 pClass;%0A
+import com.jetbrains.php.lang.psi.elements.StringLiteralExpression;%0Aimport fr.adrienbrault.idea.symfony2plugin.codeInsight.utils.PhpElementsUtil;%0Aimport org.apache.commons.lang.StringUtils;%0A
 import o
@@ -598,30 +598,8 @@
 Set;
-%0Aimport java.util.Set;
 %0A%0A/*
@@ -1085,16 +1085,67 @@
    %7D%7D;%0A%0A
+        String ns = getDefaultNamespace(project);%0A%0A
         
@@ -1845,24 +1845,292 @@
 Name()))) %7B%0A
+%0A                                if(className.startsWith(ns + %22%5C%5C%22)) %7B%0A                                    className = className.substring(ns.length() + 1);%0A                                %7D%0A%0A                                if(StringUtils.isNotBlank(className)) %7B%0A    
             
@@ -2198,24 +2198,58 @@
 ethodName);%0A
+                                %7D%0A
             
@@ -2361,24 +2361,990 @@
    %7D%0A    %7D%0A%0A
+    @NotNull%0A    private static String getDefaultNamespace(@NotNull Project project) %7B%0A%0A        PhpClass providerPhpClass = PhpElementsUtil.getClassInterface(project, %22%5C%5CApp%5C%5CProviders%5C%5CRouteServiceProvider%22);%0A        if(providerPhpClass != null) %7B%0A            Field namespace = providerPhpClass.findOwnFieldByName(%22namespace%22, false);%0A            if(namespace != null) %7B%0A                PsiElement defaultValue = namespace.getDefaultValue();%0A                if(defaultValue instanceof StringLiteralExpression) %7B%0A                    String contents = ((StringLiteralExpression) defaultValue).getContents();%0A                    if(StringUtils.isNotBlank(contents)) %7B%0A                        if(contents.startsWith(%22%5C%5C%22)) %7B%0A                            contents = contents.substring(1);%0A                        %7D%0A                        return contents;%0A                    %7D%0A                %7D%0A            %7D%0A        %7D%0A%0A        return %22%5C%5CApp%5C%5CHttp%5C%5CControllers%22;%0A    %7D%0A%0A
     public s

fix handling of namespaced controller classes #31