Completed
Push — master ( d02411...0c454b )
by Elf
02:50
created

AppManager::getRouteFileLoader()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 1
dl 0
loc 4
ccs 2
cts 2
cp 1
crap 1
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace ElfSundae\Apps;
4
5
use Closure;
6
use Illuminate\Support\Arr;
7
use Illuminate\Support\Str;
8
use Illuminate\Support\Traits\Macroable;
9
use Illuminate\Contracts\Container\Container;
10
11
class AppManager
12
{
13
    use Macroable;
14
15
    /**
16
     * The container instance.
17
     *
18
     * @var \Illuminate\Contracts\Container\Container
19
     */
20
    protected $container;
21
22
    /**
23
     * The current application identifier.
24
     *
25
     * @var string
26
     */
27
    protected $appId;
28
29
    /**
30
     * Create a new app manager instance.
31
     *
32
     * @param  \Illuminate\Contracts\Container\Container  $container
33
     */
34 84
    public function __construct(Container $container)
35
    {
36 84
        $this->container = $container;
37
38 42
        $this->container->rebinding('request', function () {
39 8
            $this->refreshId();
40 84
        });
41 84
    }
42
43
    /**
44
     * Get all application URLs.
45
     *
46
     * @return array
47
     */
48 76
    public function urls()
49
    {
50 76
        return $this->container['config']->get('apps.url', []);
51
    }
52
53
    /**
54
     * Get all application identifiers.
55
     *
56
     * @return array
57
     */
58 8
    public function ids()
59
    {
60 8
        return array_keys($this->urls());
61
    }
62
63
    /**
64
     * Get the root URL for the application identifier.
65
     *
66
     * @param  string  $app
67
     * @return string
68
     */
69 24
    public function root($app = '')
70
    {
71 24
        return Arr::get($this->urls(), (string) $app)
72 24
            ?: $this->container['config']['app.url'];
73
    }
74
75
    /**
76
     * Get the URL domain for the application identifier.
77
     *
78
     * @param  string  $app
79
     * @return string
80
     */
81 8
    public function domain($app = '')
82
    {
83 8
        return parse_url($this->root($app), PHP_URL_HOST);
84
    }
85
86
    /**
87
     * Get the URL prefix for the application identifier.
88
     *
89
     * @param  string  $app
90
     * @return string
91
     */
92 8
    public function prefix($app = '')
93
    {
94 8
        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 44
    public function id()
103
    {
104 44
        if (is_null($this->appId)) {
0 ignored issues
show
introduced by
The condition is_null($this->appId) can never be true.
Loading history...
105 44
            $this->appId = (string) $this->idForUrl($this->container['request']->getUri());
106 22
        }
107
108 44
        if (func_num_args() > 0) {
109 4
            return in_array($this->appId, is_array(func_get_arg(0)) ? func_get_arg(0) : func_get_args());
110
        }
111
112 40
        return $this->appId;
113
    }
114
115
    /**
116
     * Get the application identifier for the given URL.
117
     *
118
     * @param  string  $url
119
     * @return string|null
120
     */
121 48
    public function idForUrl($url)
122
    {
123 48
        return collect($this->urls())
124 24
            ->filter(function ($root) use ($url) {
125 48
                return $this->urlHasRoot($url, $root);
126 48
            })
127 24
            ->sortByDesc(function ($root) {
128 44
                return strlen($root);
129 48
            })
130 48
            ->keys()
131 48
            ->first();
132
    }
133
134
    /**
135
     * Refresh the current application identifier.
136
     *
137
     * @return $this
138
     */
139 12
    public function refreshId()
140
    {
141 12
        $this->appId = null;
142
143 12
        return $this;
144
    }
145
146
    /**
147
     * Determine if a URL has the given root URL.
148
     *
149
     * @param  string  $url
150
     * @param  string  $root
151
     * @param  bool  $strict
152
     * @return bool
153
     */
154 48
    protected function urlHasRoot($url, $root, $strict = false)
155
    {
156 48
        if (! $strict) {
157 48
            $url = $this->removeScheme($url);
158 48
            $root = $this->removeScheme($root);
159 24
        }
160
161 48
        return (bool) preg_match('~^'.preg_quote($root, '~').'([/\?#].*)?$~i', $url);
162
    }
163
164
    /**
165
     * Remove scheme for a URL.
166
     *
167
     * @param  string  $url
168
     * @return string
169
     */
170 48
    protected function removeScheme($url)
171
    {
172 48
        return preg_replace('#^https?://#i', '', $url);
173
    }
174
175
    /**
176
     * Generate an absolute URL to a path for the given application identifier.
177
     *
178
     * @param  string  $app
179
     * @param  string  $path
180
     * @param  mixed  $parameters
181
     * @return string
182
     */
183 4
    public function url($app = '', $path = '', $parameters = [])
184
    {
185 4
        return $this->root($app).$this->stringAfter(
186 4
            $this->container['url']->to($path, $parameters),
187 4
            $this->container['url']->to('')
188 2
        );
189
    }
190
191
    /**
192
     * Generate the URL to an application asset.
193
     *
194
     * @param  string  $path
195
     * @param  bool|null  $secure
196
     * @return string
197
     */
198 4
    public function asset($path, $secure = null)
199
    {
200 4
        return $this->container['url']->assetFrom($this->root('assets'), $path, $secure);
201
    }
202
203
    /**
204
     * Return the remainder of a string after a given value.
205
     *
206
     * @param  string  $subject
207
     * @param  string  $search
208
     * @return string
209
     */
210 4
    protected function stringAfter($subject, $search)
211
    {
212 4
        return $search === '' ? $subject : array_reverse(explode($search, $subject, 2))[0];
213
    }
214
215
    /**
216
     * Register routes for each application.
217
     *
218
     * You may call this method in the `map` method of your `RouteServiceProvider`.
219
     *
220
     * @param  array|\Closure  $attributes
221
     * @return void
222
     */
223 4
    public function routes($attributes = [])
224
    {
225 2
        $attr = $attributes instanceof Closure
226 2
            ? $attributes
227 2
            : function ($app) use ($attributes) {
228 4
                return Arr::get($attributes, $app, []);
229 4
            };
230
231 4
        foreach ($this->ids() as $app) {
232 4
            if (file_exists($file = $this->getRouteFile($app))) {
233 4
                $this->container['router']->group(
234 4
                    $this->getRouteAttributes($app, $attr),
235 4
                    $this->getRouteFileLoader($file)
236 2
                );
237 2
            }
238 2
        }
239 4
    }
240
241
    /**
242
     * Get the route file for the application.
243
     *
244
     * @param  string  $app
245
     * @return string
246
     */
247 4
    protected function getRouteFile($app)
248
    {
249 4
        return base_path("routes/{$app}.php");
250
    }
251
252
    /**
253
     * Get the route file loader.
254
     *
255
     * @param  string  $file
256
     * @return \Closure
257
     */
258
    protected function getRouteFileLoader($file)
259
    {
260 4
        return function ($router) use ($file) {
261 4
            require $file;
262 4
        };
263
    }
264
265
    /**
266
     * Get the route attributes for the application.
267
     *
268
     * @param  string  $app
269
     * @param  array|\Closure  $attributes
270
     * @return array
271
     */
272 4
    protected function getRouteAttributes($app, $attributes = [])
273
    {
274 4
        if ($attributes instanceof Closure) {
275 4
            $attributes = $attributes($app, $this) ?: [];
276 2
        }
277
278 4
        return array_filter(array_merge(
279 4
            $this->getDefaultRouteAttributes($app), $attributes
280 2
        ));
281
    }
282
283
    /**
284
     * Get the default route attributes for the application.
285
     *
286
     * @param  string  $app
287
     * @return array
288
     */
289 4
    protected function getDefaultRouteAttributes($app)
290
    {
291
        return [
292 4
            'domain' => $this->domain($app),
293 4
            'prefix' => $this->prefix($app),
294 4
            'middleware' => $this->container['router']->hasMiddlewareGroup($app) ? $app : 'web',
295 4
            'namespace' => $this->getRootControllerNamespace($app),
296 2
        ];
297
    }
298
299
    /**
300
     * Get the root controller namespace for the application.
301
     *
302
     * @param  string  $app
303
     * @return string
304
     */
305 4
    protected function getRootControllerNamespace($app)
306
    {
307 4
        $namespace = $this->container['url']->getRootControllerNamespace()
308 4
            ?: 'App\Http\Controllers';
309
310 4
        return trim($namespace.'\\'.Str::studly($app), '\\');
311
    }
312
}
313