Completed
Push — master ( f6cd53...69e8d2 )
by Elf
01:17
created

AppManager   A

Complexity

Total Complexity 29

Size/Duplication

Total Lines 265
Duplicated Lines 0 %

Coupling/Cohesion

Components 2
Dependencies 4

Test Coverage

Coverage 71.43%

Importance

Changes 0
Metric Value
dl 0
loc 265
ccs 50
cts 70
cp 0.7143
rs 10
c 0
b 0
f 0
wmc 29
lcom 2
cbo 4

17 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 8 1
A appUrls() 0 4 1
A appUrl() 0 5 2
A root() 0 4 1
A domain() 0 4 1
A prefix() 0 4 1
A id() 0 12 4
A refreshId() 0 6 1
A urlHasRoot() 0 9 2
A removeScheme() 0 4 1
A url() 0 7 1
A stringAfter() 0 4 2
A getRouteGroupAttributes() 0 14 3
A getRootControllerNamespace() 0 8 3
A registerMacros() 0 7 1
A appIdForUrl() 0 12 1
A routes() 0 15 3
1
<?php
2
3
namespace ElfSundae\Laravel\Apps;
4
5
use Illuminate\Support\Arr;
6
use Illuminate\Support\Str;
7
use Illuminate\Support\Traits\Macroable;
8
use Illuminate\Contracts\Container\Container;
9
10
class AppManager
11
{
12
    use Macroable;
13
14
    /**
15
     * The container instance.
16
     *
17
     * @var \Illuminate\Contracts\Container\Container
18
     */
19
    protected $container;
20
21
    /**
22
     * The current application identifier.
23
     *
24
     * @var string|false
25
     */
26
    protected $appId = false;
27
28
    /**
29
     * Create a new app manager instance.
30
     *
31
     * @param  \Illuminate\Contracts\Container\Container  $container
32
     */
33 13
    public function __construct(Container $container)
34
    {
35 13
        $this->container = $container;
36
37
        $this->container->rebinding('request', function () {
38 1
            $this->refreshId();
39 13
        });
40 13
    }
41
42
    /**
43
     * Get all application URLs.
44
     *
45
     * @return array
46
     */
47 10
    public function appUrls()
48
    {
49 10
        return $this->container['config']->get('apps.url', []);
50
    }
51
52
    /**
53
     * Get the root URL for the given application.
54
     *
55
     * @param  string  $app
56
     * @return string
57
     */
58 5
    public function appUrl($app = '')
59
    {
60 5
        return Arr::get($this->appUrls(), (string) $app)
61 5
            ?: $this->container['config']['app.url'];
62
    }
63
64
    /**
65
     * Get the root URL for the given application.
66
     *
67
     * @param  string  $app
68
     * @return string
69
     */
70 4
    public function root($app = '')
71
    {
72 4
        return $this->appUrl($app);
73
    }
74
75
    /**
76
     * Get the URL domain for the given application.
77
     *
78
     * @param  string  $app
79
     * @return string
80
     */
81 1
    public function domain($app = '')
82
    {
83 1
        return parse_url($this->root($app), PHP_URL_HOST);
84
    }
85
86
    /**
87
     * Get the URL prefix for the given application.
88
     *
89
     * @param  string  $app
90
     * @return string
91
     */
92 1
    public function prefix($app = '')
93
    {
94 1
        return trim(parse_url($this->root($app), PHP_URL_PATH), '/');
95
    }
96
97
    /**
98
     * Get or check the current application identifier.
99
     *
100
     * @return string|bool
101
     */
102 3
    public function id()
103
    {
104 3
        if ($this->appId === false) {
105 3
            $this->appId = $this->appIdForUrl($this->container['request']->getUri());
106
        }
107
108 3
        if (func_num_args() > 0) {
109 1
            return in_array($this->appId, is_array(func_get_arg(0)) ? func_get_arg(0) : func_get_args());
110
        }
111
112 2
        return $this->appId;
113
    }
114
115
    /**
116
     * Refresh the current application identifier.
117
     *
118
     * @return $this
119
     */
120 2
    public function refreshId()
121
    {
122 2
        $this->appId = false;
123
124 2
        return $this;
125
    }
126
127
    /**
128
     * Get the application identifier for the given URL.
129
     *
130
     * @param  string  $url
131
     * @return string
132
     */
133 4
    public function appIdForUrl($url)
134
    {
135 4
        return collect($this->appUrls())
136
            ->filter(function ($root) use ($url) {
137 4
                return $this->urlHasRoot($url, $root);
138 4
            })
139
            ->sortByDesc(function ($root) {
140 4
                return strlen($root);
141 4
            })
142 4
            ->keys()
143 4
            ->first();
144
    }
145
146
    /**
147
     * Determine if an URL has the given root URL.
148
     *
149
     * @param  string  $url
150
     * @param  string  $root
151
     * @param  bool  $strict
152
     * @return bool
153
     */
154 4
    protected function urlHasRoot($url, $root, $strict = false)
155
    {
156 4
        if (! $strict) {
157 4
            $url = $this->removeScheme($url);
158 4
            $root = $this->removeScheme($root);
159
        }
160
161 4
        return (bool) preg_match('~^'.preg_quote($root, '~').'([/\?#].*)?$~i', $url);
162
    }
163
164
    /**
165
     * Remove scheme for an URL.
166
     *
167
     * @param  string  $url
168
     * @return string
169
     */
170 4
    protected function removeScheme($url)
171
    {
172 4
        return preg_replace('#^https?://#i', '', $url);
173
    }
174
175
    /**
176
     * Generate an absolute URL to a path for the given application.
177
     *
178
     * @param  string  $app
179
     * @param  string  $path
180
     * @param  mixed  $extra
181
     * @return string
182
     */
183 1
    public function url($app = '', $path = '', $extra = [])
184
    {
185 1
        return $this->root($app).$this->stringAfter(
186 1
            $this->container['url']->to($path, $extra),
187 1
            $this->container['url']->to('')
188
        );
189
    }
190
191
    /**
192
     * Return the remainder of a string after a given value.
193
     *
194
     * @param  string  $subject
195
     * @param  string  $search
196
     * @return string
197
     */
198 1
    protected function stringAfter($subject, $search)
199
    {
200 1
        return $search === '' ? $subject : array_reverse(explode($search, $subject, 2))[0];
201
    }
202
203
    /**
204
     * Register routes for each sub application.
205
     *
206
     * @param  array  $attributes
207
     * @return void
208
     */
209
    public function routes(array $attributes = [])
210
    {
211
        foreach ($this->appUrls() as $id => $url) {
212
            if (! file_exists($file = base_path("routes/$id.php"))) {
213
                continue;
214
            }
215
216
            $this->container['router']->group(
217
                $this->getRouteGroupAttributes($id, Arr::get($attributes, $id, [])),
218
                function ($router) use ($file) {
219
                    require $file;
220
                }
221
            );
222
        }
223
    }
224
225
    /**
226
     * Get route group attributes for the given application.
227
     *
228
     * @param  string  $app
229
     * @param  array  $attributes
230
     * @return array
231
     */
232
    protected function getRouteGroupAttributes($app, array $attributes = [])
233
    {
234
        $attr = [
235
            'domain' => $this->domain($app),
236
            'namespace' => $this->getRootControllerNamespace().'\\'.Str::studly($app),
237
            'middleware' => $this->container['router']->hasMiddlewareGroup($app) ? $app : 'web',
238
        ];
239
240
        if ($prefix = $this->prefix($app)) {
241
            $attr['prefix'] = $prefix;
242
        }
243
244
        return array_merge($attr, $attributes);
245
    }
246
247
    /**
248
     * Get the root controller namespace.
249
     *
250
     * @return string
251
     */
252
    protected function getRootControllerNamespace()
253
    {
254
        if ($this->container['url']->hasMacro('getRootControllerNamespace')) {
255
            $namespace = $this->container['url']->getRootControllerNamespace();
256
        }
257
258
        return isset($namespace) ? $namespace : 'App\Http\Controllers';
259
    }
260
261
    /**
262
     * Register macros.
263
     *
264
     * @param  \Illuminate\Contracts\Container\Container  $app
265
     * @return void
266
     */
267
    public static function registerMacros($app)
268
    {
269 3
        $app['url']->macro('getRootControllerNamespace', function () {
270
            /* @var $this \Illuminate\Routing\UrlGenerator */
271 1
            return $this->rootNamespace;
0 ignored issues
show
Bug introduced by
The property rootNamespace does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
272 3
        });
273 3
    }
274
}
275