Completed
Push — master ( 0ceb2a...d02411 )
by Elf
05:33
created

AppManager::getRouteFile()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

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