Completed
Branch master (46ece2)
by Elf
01:32
created

AppManager::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 4
nc 1
nop 1
dl 0
loc 8
ccs 6
cts 6
cp 1
crap 1
rs 9.4285
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 20
    public function __construct(Container $container)
34
    {
35 20
        $this->container = $container;
36
37 20
        $this->container->rebinding('request', function () {
38 2
            $this->refreshId();
39 20
        });
40 20
    }
41
42
    /**
43
     * Get all application URLs.
44
     *
45
     * @return array
46
     */
47 18
    public function urls()
48
    {
49 18
        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 6
    public function root($app = '')
59
    {
60 6
        return Arr::get($this->urls(), (string) $app)
61 6
            ?: $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 11
    public function id()
92
    {
93 11
        if (is_null($this->appId)) {
94 11
            $this->appId = (string) $this->idForUrl($this->container['request']->getUri());
95
        }
96
97 11
        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 10
        return $this->appId;
102
    }
103
104
    /**
105
     * Get the application identifier for the given URL.
106
     *
107
     * @param  string  $url
108
     * @return string|null
109
     */
110 12
    public function idForUrl($url)
111
    {
112 12
        return collect($this->urls())
113 12
            ->filter(function ($root) use ($url) {
114 12
                return $this->urlHasRoot($url, $root);
115 12
            })
116 12
            ->sortByDesc(function ($root) {
117 11
                return strlen($root);
118 12
            })
119 12
            ->keys()
120 12
            ->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 = null;
131
132 3
        return $this;
133
    }
134
135
    /**
136
     * Determine if a URL has the given root URL.
137
     *
138
     * @param  string  $url
139
     * @param  string  $root
140
     * @param  bool  $strict
141
     * @return bool
142
     */
143 12
    protected function urlHasRoot($url, $root, $strict = false)
144
    {
145 12
        if (! $strict) {
146 12
            $url = $this->removeScheme($url);
147 12
            $root = $this->removeScheme($root);
148
        }
149
150 12
        return (bool) preg_match('~^'.preg_quote($root, '~').'([/\?#].*)?$~i', $url);
151
    }
152
153
    /**
154
     * Remove scheme for a URL.
155
     *
156
     * @param  string  $url
157
     * @return string
158
     */
159 12
    protected function removeScheme($url)
160
    {
161 12
        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
     * Generate the URL to an application asset.
182
     *
183
     * @param  string  $path
184
     * @param  bool|null  $secure
185
     * @return string
186
     */
187 1
    public function asset($path, $secure = null)
188
    {
189 1
        return $this->container['url']->assetFrom($this->root('assets'), $path, $secure);
190
    }
191
192
    /**
193
     * Return the remainder of a string after a given value.
194
     *
195
     * @param  string  $subject
196
     * @param  string  $search
197
     * @return string
198
     */
199 1
    protected function stringAfter($subject, $search)
200
    {
201 1
        return $search === '' ? $subject : array_reverse(explode($search, $subject, 2))[0];
202
    }
203
204
    /**
205
     * Register routes for each application.
206
     *
207
     * You may call this method in the `map` method of your `RouteServiceProvider`.
208
     *
209
     * @param  array  $attributes
210
     * @return void
211
     */
212 1
    public function routes(array $attributes = [])
213
    {
214 1
        foreach ($this->urls() as $id => $url) {
215 1
            if (! file_exists($file = base_path("routes/$id.php"))) {
216 1
                continue;
217
            }
218
219 1
            $this->container['router']->group(
220 1
                $this->getRouteGroupAttributes($id, Arr::get($attributes, $id, [])),
221 1
                function ($router) use ($file) {
222 1
                    require $file;
223 1
                }
224
            );
225
        }
226 1
    }
227
228
    /**
229
     * Get route group attributes for the given application.
230
     *
231
     * @param  string  $app
232
     * @param  array  $attributes
233
     * @return array
234
     */
235 1
    protected function getRouteGroupAttributes($app, array $attributes = [])
236
    {
237
        $attr = [
238 1
            'domain' => $this->domain($app),
239 1
            'prefix' => $this->prefix($app),
240 1
            'middleware' => $this->container['router']->hasMiddlewareGroup($app) ? $app : 'web',
241 1
            'namespace' => $this->getRootControllerNamespace($app),
242
        ];
243
244 1
        return array_filter(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 1
    protected function getRootControllerNamespace($app)
254
    {
255 1
        $namespace = $this->container['url']->getRootControllerNamespace()
256 1
            ?: 'App\Http\Controllers';
257
258 1
        return trim($namespace.'\\'.Str::studly($app), '\\');
259
    }
260
}
261