Completed
Push — master ( 106baa...ab630c )
by Elf
01:39
created

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