Passed
Push — master ( e72405...8eb963 )
by Thomas
11:41
created

AdminiRootController   A

Complexity

Total Complexity 19

Size/Duplication

Total Lines 158
Duplicated Lines 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
eloc 48
c 2
b 0
f 0
dl 0
loc 158
rs 10
wmc 19

8 Methods

Rating   Name   Duplication   Size   Complexity  
A get_admin_route() 0 5 2
A admin_url() 0 3 1
A add_rule_for_controller() 0 16 4
A force_redirect() 0 7 2
A rules() 0 10 2
A get_current_admin_route() 0 14 3
A handleRequest() 0 24 4
A get_template_global_variables() 0 4 1
1
<?php
2
3
namespace LeKoala\Admini;
4
5
use SilverStripe\Control\Controller;
6
use SilverStripe\Control\Director;
7
use SilverStripe\Control\HTTPRequest;
8
use SilverStripe\Core\Config\Config;
9
use SilverStripe\Core\Injector\Injector;
10
use SilverStripe\View\TemplateGlobalProvider;
11
12
class AdminiRootController extends Controller implements TemplateGlobalProvider
13
{
14
15
    /**
16
     * Fallback admin URL in case this cannot be infered from Director.rules
17
     *
18
     * @var string
19
     * @config
20
     */
21
    private static $url_base = 'admini';
0 ignored issues
show
introduced by
The private property $url_base is not used, and could be removed.
Loading history...
22
23
    /**
24
     * Convenience function to return the admin route config.
25
     * Looks for the {@link Director::$rules} for the current admin Controller.
26
     *
27
     * @return string
28
     */
29
    public static function get_admin_route()
30
    {
31
        $rules = Director::config()->get('rules');
32
        $adminRoute = array_search(__CLASS__, $rules);
33
        return $adminRoute ?: static::config()->get('url_base');
34
    }
35
36
    /**
37
     * Returns the root admin URL for the site with trailing slash
38
     *
39
     * @return string
40
     */
41
    public static function admin_url()
42
    {
43
        return self::get_admin_route() . '/';
44
    }
45
46
    /**
47
     * Useful when used alongside regular admin
48
     *
49
     * @return string
50
     */
51
    public static function get_current_admin_route()
52
    {
53
        $route = self::get_admin_route();
54
        if (Controller::has_curr()) {
55
            $curr = Controller::curr();
56
            $request = $curr->getRequest()->getURL();
57
            $firstSegment = explode("/", $request)[0] ?? null;
58
59
            // Force route to admin if it's the current segment
60
            if ($firstSegment == "admin") {
61
                $route = $firstSegment;
62
            }
63
        }
64
        return $route;
65
    }
66
67
    public static function force_redirect($segment, $fallbackRoute = null)
68
    {
69
        if ($fallbackRoute === null) {
70
            $fallbackRoute = self::get_current_admin_route();
71
        }
72
        header('Location: ' . $fallbackRoute . '/' . $segment);
73
        exit();
74
    }
75
76
    /**
77
     * @var string
78
     * @config
79
     * The LeftAndMain child that will be used as the initial panel to display if none is selected (i.e. if you
80
     * visit /admin)
81
     */
82
    private static $default_panel = SecurityAdmin::class;
0 ignored issues
show
introduced by
The private property $default_panel is not used, and could be removed.
Loading history...
83
84
    /**
85
     * @var array
86
     * @internal
87
     *
88
     * Holds an array of url_pattern => controller k/v pairs, the same as Director::rules. However this is built
89
     * dynamically from introspecting on all the classes that derive from LeftAndMain.
90
     *
91
     * Don't access this directly - always access via the rules() accessor below, which will build this array
92
     * the first time it's accessed
93
     */
94
    private static $adminRules = null;
95
96
    /**
97
     * Gets a list of url_pattern => controller k/v pairs for each LeftAndMain derived controller
98
     */
99
    public static function rules()
100
    {
101
        if (self::$adminRules === null) {
0 ignored issues
show
introduced by
The condition self::adminRules === null is always false.
Loading history...
102
            self::$adminRules = array();
103
104
            // Map over the array calling add_rule_for_controller on each
105
            $classes = CMSMenu::get_cms_classes(null, true, CMSMenu::URL_PRIORITY);
106
            array_map(array(__CLASS__, 'add_rule_for_controller'), $classes);
107
        }
108
        return self::$adminRules;
109
    }
110
111
    /**
112
     * Add the appropriate k/v pair to self::$rules for the given controller.
113
     *
114
     * @param string $controllerClass Name of class
115
     */
116
    protected static function add_rule_for_controller($controllerClass)
117
    {
118
        $config = Config::forClass($controllerClass);
119
        $urlSegment = $config->get('url_segment');
120
        $urlRule    = $config->get('url_rule');
121
122
        if ($urlSegment) {
123
            // Make director rule
124
            if ($urlRule[0] == '/') {
125
                $urlRule = substr($urlRule, 1);
126
            }
127
            $rule = $urlSegment . '//' . $urlRule;
128
129
            // ensure that the first call to add_rule_for_controller for a rule takes precedence
130
            if (!isset(self::$adminRules[$rule])) {
131
                self::$adminRules[$rule] = $controllerClass;
132
            }
133
        }
134
    }
135
136
    public function handleRequest(HTTPRequest $request)
137
    {
138
        // If this is the final portion of the request (i.e. the URL is just /admin), direct to the default panel
139
        if ($request->allParsed()) {
140
            $segment = Config::forClass($this->config()->get('default_panel'))
141
                ->get('url_segment');
142
143
            $this->redirect(Controller::join_links(self::admin_url(), $segment, '/'));
144
            return $this->getResponse();
145
        }
146
147
        // Otherwise
148
        $rules = self::rules();
149
        foreach ($rules as $pattern => $controller) {
150
            if (($arguments = $request->match($pattern, true)) !== false) {
0 ignored issues
show
Unused Code introduced by
The assignment to $arguments is dead and can be removed.
Loading history...
151
                /** @var LeftAndMain $controllerObj */
152
                $controllerObj = Injector::inst()->create($controller);
153
                return $controllerObj->handleRequest($request);
154
            }
155
        }
156
157
        // Fall back to methods defined on LeftAndMain
158
        $controllerObj = Injector::inst()->create(LeftAndMain::class);
159
        return $controllerObj->handleRequest($request);
160
    }
161
162
    /**
163
     * @return array Returns an array of strings of the method names of methods on the call that should be exposed
164
     * as global variables in the templates.
165
     */
166
    public static function get_template_global_variables()
167
    {
168
        return array(
169
            'adminiURL' => 'admin_url'
170
        );
171
    }
172
}
173