Completed
Push — master ( f10077...eddc4f )
by Elf
03:19 queued 02:07
created

Apps::id()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 12
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 4

Importance

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