Completed
Push — master ( 1de045...f1e92d )
by Elf
01:33
created

AppManager::id()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 12
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 4

Importance

Changes 0
Metric Value
cc 4
eloc 6
nc 4
nop 0
dl 0
loc 12
ccs 7
cts 7
cp 1
crap 4
rs 9.2
c 0
b 0
f 0
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 3
        }
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 4
        }
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  $parameters
181
     * @return string
182
     */
183 1
    public function url($app = '', $path = '', $parameters = [])
184
    {
185 1
        return $this->root($app).$this->stringAfter(
186 1
            $this->container['url']->to($path, $parameters),
187 1
            $this->container['url']->to('')
188 1
        );
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($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 for the given application.
249
     *
250
     * @param  string  $app
251
     * @return string
252
     */
253
    protected function getRootControllerNamespace($app)
254
    {
255
        return trim($this->container['url']->getRootControllerNamespace().'\\'.Str::studly($app), '\\');
256
    }
257
}
258