Completed
Push — master ( 316a2b...717fa4 )
by Elf
01:54
created

AppManager::domain()   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
        $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
            ->filter(function ($root) use ($url) {
82 4
                return $this->urlHasRoot($url, $root);
83 4
            })
84
            ->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
    /**
241
     * Register macros.
242
     *
243
     * @param  \Illuminate\Contracts\Container\Container  $app
244
     * @return void
245
     */
246
    public static function registerMacros($app)
247
    {
248 3
        $app['url']->macro('getRootControllerNamespace', function () {
249
            /* @var $this \Illuminate\Routing\UrlGenerator */
250 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...
251 3
        });
252 3
    }
253
}
254