Completed
Push — master ( 717fa4...c41941 )
by Elf
01:35
created

AppManager::appUrls()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 0
dl 0
loc 4
ccs 0
cts 2
cp 0
crap 2
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 all application URLs.
122
     *
123
     * @return array
124
     */
125
    public function appUrls()
126
    {
127
        return $this->container['config']->get('apps.url', []);
128
    }
129
130
    /**
131
     * Get the root URL for the given application.
132
     *
133
     * @param  string  $app
134
     * @return mixed
135
     */
136
    public function appUrl($app = '')
137
    {
138
        return Arr::get($this->appUrls(), (string) $app)
139
            ?: $this->container['config']['app.url'];
140
    }
141
142
    /**
143
     * Get the root URL for the given application identifier.
144
     *
145
     * @param  string  $appId
146
     * @return string
147
     */
148 4
    public function root($appId = '')
149
    {
150 4
        return $this->container['config']["apps.url.$appId"]
151 4
            ?: $this->container['config']['app.url'];
152
    }
153
154
    /**
155
     * Get the domain for the given application identifier.
156
     *
157
     * @param  string  $appId
158
     * @return string
159
     */
160 1
    public function domain($appId = '')
161
    {
162 1
        return parse_url($this->root($appId), PHP_URL_HOST);
163
    }
164
165
    /**
166
     * Get the URL prefix for the given application identifier.
167
     *
168
     * @param  string  $appId
169
     * @return string
170
     */
171 1
    public function prefix($appId = '')
172
    {
173 1
        return trim(parse_url($this->root($appId), PHP_URL_PATH), '/');
174
    }
175
176
    /**
177
     * Generate an absolute URL to a path for the given application identifier.
178
     *
179
     * @param  string  $appId
180
     * @param  string  $path
181
     * @param  mixed  $extra
182
     * @return string
183
     */
184 1
    public function url($appId = '', $path = '', $extra = [])
185
    {
186 1
        return $this->root($appId).$this->stringAfter(
187 1
            $this->container['url']->to($path, $extra),
188 1
            $this->container['url']->to('')
189
        );
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 sub application.
206
     *
207
     * @param  array  $attributes
208
     * @return void
209
     */
210
    public function routes(array $attributes = [])
211
    {
212
        foreach ($this->container['config']['apps.url'] as $id => $url) {
213
            if (! file_exists($file = base_path("routes/$id.php"))) {
214
                continue;
215
            }
216
217
            $this->container['router']->group(
218
                $this->getRouteGroupAttributes($id, Arr::get($attributes, $id, [])),
219
                function ($router) use ($file) {
220
                    require $file;
221
                }
222
            );
223
        }
224
    }
225
226
    /**
227
     * Get route group attributes for the given application identifier.
228
     *
229
     * @param  string  $appId
230
     * @param  array  $attributes
231
     * @return array
232
     */
233
    protected function getRouteGroupAttributes($appId, array $attributes = [])
234
    {
235
        $attr = [
236
            'domain' => $this->domain($appId),
237
            'namespace' => $this->getRootControllerNamespace().'\\'.Str::studly($appId),
238
            'middleware' => $this->container['router']->hasMiddlewareGroup($appId) ? $appId : 'web',
239
        ];
240
241
        if ($prefix = $this->prefix($appId)) {
242
            $attr['prefix'] = $prefix;
243
        }
244
245
        return array_merge($attr, $attributes);
246
    }
247
248
    /**
249
     * Get the root controller namespace.
250
     *
251
     * @return string
252
     */
253
    protected function getRootControllerNamespace()
254
    {
255
        if ($this->container['url']->hasMacro('getRootControllerNamespace')) {
256
            $namespace = $this->container['url']->getRootControllerNamespace();
257
        }
258
259
        return isset($namespace) ? $namespace : 'App\Http\Controllers';
260
    }
261
262
    /**
263
     * Register macros.
264
     *
265
     * @param  \Illuminate\Contracts\Container\Container  $app
266
     * @return void
267
     */
268
    public static function registerMacros($app)
269
    {
270 3
        $app['url']->macro('getRootControllerNamespace', function () {
271
            /* @var $this \Illuminate\Routing\UrlGenerator */
272 1
            return $this->rootNamespace;
0 ignored issues
show
Bug introduced by
The property rootNamespace does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
273 3
        });
274 3
    }
275
}
276