Completed
Pull Request — master (#34)
by Raed
05:40
created

GeoRoute::orUnauthorized()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
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 5
ccs 0
cts 3
cp 0
crap 2
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace LaraCrafts\GeoRoutes;
4
5
use BadMethodCallException;
6
use Illuminate\Routing\Route;
7
use Illuminate\Support\Str;
8
use LaraCrafts\GeoRoutes\Support\Facades\CallbackRegistrar;
0 ignored issues
show
Bug introduced by
This use statement conflicts with another class in this namespace, LaraCrafts\GeoRoutes\CallbackRegistrar. Consider defining an alias.

Let?s assume that you have a directory layout like this:

.
|-- OtherDir
|   |-- Bar.php
|   `-- Foo.php
`-- SomeDir
    `-- Foo.php

and let?s assume the following content of Bar.php:

// Bar.php
namespace OtherDir;

use SomeDir\Foo; // This now conflicts the class OtherDir\Foo

If both files OtherDir/Foo.php and SomeDir/Foo.php are loaded in the same runtime, you will see a PHP error such as the following:

PHP Fatal error:  Cannot use SomeDir\Foo as Foo because the name is already in use in OtherDir/Foo.php

However, as OtherDir/Foo.php does not necessarily have to be loaded and the error is only triggered if it is loaded before OtherDir/Bar.php, this problem might go unnoticed for a while. In order to prevent this error from surfacing, you must import the namespace with a different alias:

// Bar.php
namespace OtherDir;

use SomeDir\Foo as SomeDirFoo; // There is no conflict anymore.
Loading history...
9
10
/**
11
 * @mixin \Illuminate\Routing\Route
12
 */
13
class GeoRoute
14
{
15
    use Concerns\HasCallback;
16
    use Concerns\ControlsAccess;
17
18
    /**
19
     * Rule is applied.
20
     *
21
     * @var bool
22
     */
23
    protected $applied;
24
25
    /**
26
     * The countries to apply the rule for.
27
     *
28
     * @var array
29
     */
30
    protected $countries;
31
32
    /**
33
     * The route.
34
     *
35
     * @var \Illuminate\Routing\Route
36
     */
37
    protected $route;
38
39
    /**
40
     * The rule's strategy.
41
     *
42
     * @var string
43
     */
44
    protected $strategy;
45
46
    /**
47
     * Create a new GeoRoute instance.
48
     *
49
     * @param  \Illuminate\Routing\Route $route
50
     * @param  array $countries
51
     * @param  string $strategy
52
     */
53 70
    public function __construct(Route $route, array $countries, string $strategy)
54
    {
55 70
        $this->applied = false;
56 70
        $this->countries = array_map('strtoupper', $countries);
57 70
        $this->route = $route;
58 70
        $this->strategy = $strategy;
59 70
    }
60
61
    /**
62
     * Dynamically call the underlying route.
63
     *
64
     * @param string $method
65
     * @param array $arguments
66
     *
67
     * @return mixed
68
     */
69
    public function __call(string $method, array $arguments)
70
    {
71
        if (method_exists($this->route, $method) || Route::hasMacro($method)) {
72
            return $this->route->$method(...$arguments);
73
        }
74
75
        if (CallbackRegistrar::hasProxy($method)) {
0 ignored issues
show
Bug introduced by
The method hasProxy() does not exist on LaraCrafts\GeoRoutes\Sup...cades\CallbackRegistrar. Since you implemented __callStatic, consider adding a @method annotation. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

75
        if (CallbackRegistrar::/** @scrutinizer ignore-call */ hasProxy($method)) {
Loading history...
76
            return $this->setCallback(CallbackRegistrar::callback($method), $arguments);
0 ignored issues
show
Bug introduced by
The method callback() does not exist on LaraCrafts\GeoRoutes\Sup...cades\CallbackRegistrar. Since you implemented __callStatic, consider adding a @method annotation. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

76
            return $this->setCallback(CallbackRegistrar::/** @scrutinizer ignore-call */ callback($method), $arguments);
Loading history...
77
        }
78
79
        throw new BadMethodCallException("Undefined method '$method'");
80
    }
81
82
    /**
83
     * Destruct the GeoRoute instance and apply the middleware.
84
     */
85 70
    public function __destruct()
86
    {
87 70
        $this->applyConstraint();
88 70
    }
89
90
    /**
91
     * Apply the geo-constraint to the route.
92
     */
93 70
    protected function applyConstraint()
94
    {
95 70
        if ($this->applied || !$this->countries) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $this->countries of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
96
            return;
97
        }
98
99 70
        $action = $this->route->getAction();
100 70
        $action['middleware'][] = 'geo';
101 70
        $action['geo'] = [
102 70
            'strategy' => $this->strategy,
103 70
            'countries' => (array)$this->countries,
104 70
            'callback' => $this->callback,
105
        ];
106
107 70
        $this->route->setAction($action);
0 ignored issues
show
Bug introduced by
It seems like $action can also be of type null; however, parameter $action of Illuminate\Routing\Route::setAction() does only seem to accept array, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

107
        $this->route->setAction(/** @scrutinizer ignore-type */ $action);
Loading history...
108
109 70
        $this->applied = true;
110 70
    }
111
}
112