Completed
Push — master ( f8d1bb...25dd19 )
by Elf
01:40
created

AppManager::urls()   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 0
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\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 13
        $this->container->rebinding('request', function () {
38 2
            $this->refreshId();
39 13
        });
40 13
    }
41
42
    /**
43
     * Get all application URLs.
44
     *
45
     * @return array
46
     */
47 10
    public function urls()
48
    {
49 10
        return $this->container['config']->get('apps.url', []);
50
    }
51
52
    /**
53
     * Get the root URL for the application identifier.
54
     *
55
     * @param  string  $app
56
     * @return string
57
     */
58 5
    public function root($app = '')
59
    {
60 5
        return Arr::get($this->urls(), (string) $app)
61 5
            ?: $this->container['config']['app.url'];
62
    }
63
64
    /**
65
     * Get the URL domain for the application identifier.
66
     *
67
     * @param  string  $app
68
     * @return string
69
     */
70 2
    public function domain($app = '')
71
    {
72 2
        return parse_url($this->root($app), PHP_URL_HOST);
73
    }
74
75
    /**
76
     * Get the URL prefix for the application identifier.
77
     *
78
     * @param  string  $app
79
     * @return string
80
     */
81 2
    public function prefix($app = '')
82
    {
83 2
        return trim(parse_url($this->root($app), PHP_URL_PATH), '/');
84
    }
85
86
    /**
87
     * Get or check the current application identifier.
88
     *
89
     * @return string|bool
90
     */
91 3
    public function id()
92
    {
93 3
        if ($this->appId === false) {
94 3
            $this->appId = $this->idForUrl($this->container['request']->getUri());
95
        }
96
97 3
        if (func_num_args() > 0) {
98 1
            return in_array($this->appId, is_array(func_get_arg(0)) ? func_get_arg(0) : func_get_args());
99
        }
100
101 2
        return $this->appId;
102
    }
103
104
    /**
105
     * Get the application identifier for the given URL.
106
     *
107
     * @param  string  $url
108
     * @return string
109
     */
110 4
    public function idForUrl($url)
111
    {
112 4
        return collect($this->urls())
113 4
            ->filter(function ($root) use ($url) {
114 4
                return $this->urlHasRoot($url, $root);
115 4
            })
116 4
            ->sortByDesc(function ($root) {
117 4
                return strlen($root);
118 4
            })
119 4
            ->keys()
120 4
            ->first();
121
    }
122
123
    /**
124
     * Refresh the current application identifier.
125
     *
126
     * @return $this
127
     */
128 3
    public function refreshId()
129
    {
130 3
        $this->appId = false;
131
132 3
        return $this;
133
    }
134
135
    /**
136
     * Determine if an URL has the given root URL.
137
     *
138
     * @param  string  $url
139
     * @param  string  $root
140
     * @param  bool  $strict
141
     * @return bool
142
     */
143 4
    protected function urlHasRoot($url, $root, $strict = false)
144
    {
145 4
        if (! $strict) {
146 4
            $url = $this->removeScheme($url);
147 4
            $root = $this->removeScheme($root);
148
        }
149
150 4
        return (bool) preg_match('~^'.preg_quote($root, '~').'([/\?#].*)?$~i', $url);
151
    }
152
153
    /**
154
     * Remove scheme for an URL.
155
     *
156
     * @param  string  $url
157
     * @return string
158
     */
159 4
    protected function removeScheme($url)
160
    {
161 4
        return preg_replace('#^https?://#i', '', $url);
162
    }
163
164
    /**
165
     * Generate an absolute URL to a path for the given application identifier.
166
     *
167
     * @param  string  $app
168
     * @param  string  $path
169
     * @param  mixed  $parameters
170
     * @return string
171
     */
172 1
    public function url($app = '', $path = '', $parameters = [])
173
    {
174 1
        return $this->root($app).$this->stringAfter(
175 1
            $this->container['url']->to($path, $parameters),
176 1
            $this->container['url']->to('')
177
        );
178
    }
179
180
    /**
181
     * Return the remainder of a string after a given value.
182
     *
183
     * @param  string  $subject
184
     * @param  string  $search
185
     * @return string
186
     */
187 1
    protected function stringAfter($subject, $search)
188
    {
189 1
        return $search === '' ? $subject : array_reverse(explode($search, $subject, 2))[0];
190
    }
191
192
    /**
193
     * Register routes for each sub application.
194
     * You may call this method in `RouteServiceProvider::map()`.
195
     *
196
     * @param  array  $attributes
197
     * @return void
198
     */
199 1
    public function routes(array $attributes = [])
200
    {
201 1
        foreach ($this->urls() as $id => $url) {
202 1
            if (! file_exists($file = base_path("routes/$id.php"))) {
203 1
                continue;
204
            }
205
206 1
            $this->container['router']->group(
207 1
                $this->getRouteGroupAttributes($id, Arr::get($attributes, $id, [])),
208 1
                function ($router) use ($file) {
209 1
                    require $file;
210 1
                }
211
            );
212
        }
213 1
    }
214
215
    /**
216
     * Get route group attributes for the given application.
217
     *
218
     * @param  string  $app
219
     * @param  array  $attributes
220
     * @return array
221
     */
222 1
    protected function getRouteGroupAttributes($app, array $attributes = [])
223
    {
224
        $attr = [
225 1
            'domain' => $this->domain($app),
226 1
            'middleware' => $this->container['router']->hasMiddlewareGroup($app) ? $app : 'web',
227 1
            'namespace' => $this->getRootControllerNamespace($app),
228
        ];
229
230 1
        if ($prefix = $this->prefix($app)) {
231 1
            $attr['prefix'] = $prefix;
232
        }
233
234 1
        return array_merge($attr, $attributes);
235
    }
236
237
    /**
238
     * Get the root controller namespace for the given application.
239
     *
240
     * @param  string  $app
241
     * @return string
242
     */
243 1
    protected function getRootControllerNamespace($app)
244
    {
245 1
        $namespace = $this->container['url']->getRootControllerNamespace()
246 1
            ?: 'App\Http\Controllers';
247
248 1
        return trim($namespace.'\\'.Str::studly($app), '\\');
249
    }
250
}
251