LockService   A
last analyzed

Complexity

Total Complexity 11

Size/Duplication

Total Lines 82
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 9
Bugs 5 Features 0
Metric Value
eloc 23
dl 0
loc 82
ccs 15
cts 15
cp 1
rs 10
c 9
b 5
f 0
wmc 11

5 Methods

Rating   Name   Duplication   Size   Complexity  
A lock() 0 4 1
A __construct() 0 3 1
A cache() 0 7 2
A lockProvider() 0 19 5
A bindTo() 0 8 2
1
<?php
2
3
namespace Bavix\Wallet\Services;
4
5
use Bavix\Wallet\Objects\EmptyLock;
6
use Illuminate\Contracts\Cache\Lock;
7
use Illuminate\Contracts\Cache\LockProvider;
8
use Illuminate\Contracts\Cache\Store;
9
use Illuminate\Database\Eloquent\Model;
10
use Illuminate\Support\Facades\Cache;
11
use Illuminate\Support\Str;
12
13
class LockService
14
{
15
    /**
16
     * @var string
17
     */
18
    protected $uniqId;
19
20
    /**
21
     * LockService constructor.
22
     */
23 118
    public function __construct()
24
    {
25 118
        $this->uniqId = Str::random();
26 118
    }
27
28
    /**
29
     * @param object $self
30
     * @param string $name
31
     * @param \Closure $closure
32
     * @return mixed
33
     */
34 117
    public function lock($self, string $name, \Closure $closure)
35
    {
36 117
        return $this->lockProvider($self, $name, (int) config('wallet.lock.seconds', 1))
37 117
            ->get($this->bindTo($self, $closure));
38
    }
39
40
    /**
41
     * @param object $self
42
     * @param \Closure $closure
43
     * @return \Closure
44
     * @throws
45
     */
46 117
    protected function bindTo($self, \Closure $closure): \Closure
47
    {
48 117
        $reflect = new \ReflectionFunction($closure);
49 117
        if (strpos((string) $reflect, 'static') === false) {
50 113
            return $closure->bindTo($self);
51
        }
52
53 114
        return $closure;
54
    }
55
56
    /**
57
     * @return Store|null
58
     * @codeCoverageIgnore
59
     */
60
    protected function cache(): ?Store
61
    {
62
        try {
63
            return Cache::store(config('wallet.lock.cache'))
64
                ->getStore();
65
        } catch (\Throwable $throwable) {
66
            return null;
67
        }
68
    }
69
70
    /**
71
     * @param object $self
72
     * @param string $name
73
     * @param int $seconds
74
     * @return Lock
75
     */
76 117
    protected function lockProvider($self, string $name, int $seconds): Lock
77
    {
78 117
        $store = $this->cache();
79 117
        $enabled = $store && config('wallet.lock.enabled', false);
80
81
        // fixme: CodeClimate
82
        // @codeCoverageIgnoreStart
83
        if ($enabled && $store instanceof LockProvider) {
84
            $class = \get_class($self);
85
            $uniqId = $class.$this->uniqId;
86
            if ($self instanceof Model) {
87
                $uniqId = $class.$self->getKey();
88
            }
89
90
            return $store->lock("$name.$uniqId", $seconds);
91
        }
92
        // @codeCoverageIgnoreEnd
93
94 95
        return app(EmptyLock::class);
95
    }
96
}
97