BaseProxy::getInstance()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 3
dl 0
loc 7
c 0
b 0
f 0
rs 10
cc 2
nc 2
nop 0
1
<?php
2
3
declare(strict_types=1);
4
5
/**
6
 * Contains the BaseProxy class.
7
 *
8
 * @copyright   Copyright (c) 2017 Attila Fulop
9
 * @author      Attila Fulop
10
 * @license     MIT
11
 * @since       2017-05-24
12
 *
13
 */
14
15
namespace Konekt\Concord\Proxies;
16
17
use Konekt\Concord\Contracts\Concord;
18
use LogicException;
19
20
abstract class BaseProxy
21
{
22
    /** @var Concord */
23
    public $concord;
24
25
    /** @var string */
26
    protected $contract;
27
28
    /** @var array */
29
    protected static $instances = [];
30
31
    /**
32
     * Repository constructor.
33
     *
34
     * @param Concord $concord
35
     */
36
    public function __construct(Concord $concord = null)
37
    {
38
        $this->concord = $concord ?: app('concord');
0 ignored issues
show
Documentation Bug introduced by
It seems like $concord ?: app('concord') can also be of type Illuminate\Contracts\Foundation\Application. However, the property $concord is declared as type Konekt\Concord\Contracts\Concord. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
39
40
        if (empty($this->contract)) {
41
            $this->contract = $this->guessContract();
42
        }
43
44
        if (!interface_exists($this->contract)) {
45
            throw new LogicException(
46
                sprintf(
47
                    'The proxy %s has a non-existent contract class: `%s`',
48
                    static::class,
49
                    $this->contract
50
                )
51
            );
52
        }
53
    }
54
55
    /**
56
     * Resets the proxy by removing the class instance.
57
     * Shouldn't be used in application code.
58
     *
59
     */
60
    public static function __reset()
61
    {
62
        // This is only needed to ensure that in the rare case when
63
        // the app instance gets replaced along with the Concord
64
        // singleton in runtime, no stale concord survives it
65
        if (isset(static::$instances[static::class])) {
66
            unset(static::$instances[static::class]);
67
        }
68
    }
69
70
    /**
71
     * @param $method
72
     * @param $parameters
73
     *
74
     * @return mixed
75
     */
76
    public static function __callStatic($method, $parameters)
77
    {
78
        return call_user_func(static::getInstance()->targetClass() . '::' . $method, ...$parameters);
79
    }
80
81
    /**
82
     * This is a method where the dark word 'static' has 7 occurrences
83
     *
84
     * @return BaseProxy
85
     */
86
    public static function getInstance()
87
    {
88
        if (!isset(static::$instances[static::class])) {
89
            static::$instances[static::class] = new static();
90
        }
91
92
        return static::$instances[static::class];
93
    }
94
95
    /**
96
     * Try guessing the associated contract class for a concrete proxy class
97
     *
98
     * @return string
99
     */
100
    abstract protected function guessContract();
101
102
    /**
103
     * Returns the resolved class
104
     *
105
     * @return string
106
     */
107
    abstract protected function targetClass(): string;
108
}
109