Completed
Push — master ( 9ec735...3eb51e )
by Hong
03:03
created

ShareableTrait::hasShareable()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 4
rs 10
cc 1
eloc 2
nc 1
nop 1
1
<?php
2
/**
3
 * Phossa Project
4
 *
5
 * PHP version 5.4
6
 *
7
 * @category  Library
8
 * @package   Phossa2\Shared
9
 * @copyright Copyright (c) 2016 phossa.com
10
 * @license   http://mit-license.org/ MIT License
11
 * @link      http://www.phossa.com/
12
 */
13
/*# declare(strict_types=1); */
14
15
namespace Phossa2\Shared\Shareable;
16
17
use Phossa2\Shared\Message\Message;
18
use Phossa2\Shared\Exception\RuntimeException;
19
20
/**
21
 * Implementation of ShareableInterface
22
 *
23
 * @package Phossa2\Shared
24
 * @author  Hong Zhang <[email protected]>
25
 * @see     ShareableInterface
26
 * @version 2.0.10
27
 * @since   2.0.10 added
28
 */
29
trait ShareableTrait
30
{
31
    /**
32
     * Shareables' pool
33
     *
34
     * @var    ShareableInstance[]
35
     * @access private
36
     * @staticvar
37
     */
38
    private static $shareables = [];
39
40
    /**
41
     * Is this shared instance, store scope here
42
     *
43
     * @var    string
44
     * @access protected
45
     */
46
    protected $shared_in;
47
48
    /**
49
     * Scopes of this instance belongs to
50
     *
51
     * @var    string[]
52
     * @access protected
53
     */
54
    protected $scopes = [];
55
56
    /**
57
     * minimum constructor
58
     *
59
     * @access public
60
     */
61
    public function __construct()
62
    {
63
    }
64
65
    /*
66
     * {@inheritDoc}
67
     */
68
    public static function getShareable(
69
        /*# string */ $scope = ''
70
    )/*# : ShareableInterface */ {
71
        // create the shared instance if not yet
72
        if (!static::hasShareable($scope)) {
73
            (new static())->setShareable($scope);
74
        }
75
76
        return self::$shareables[get_called_class()][$scope];
77
    }
78
79
    /**
80
     * {@inheritDoc}
81
     */
82
    public static function hasShareable(/*# string */ $scope = '')/*# : bool */
83
    {
84
        return isset(self::$shareables[get_called_class()][$scope]);
85
    }
86
87
    /**
88
     * {@inheritDoc}
89
     */
90
    public static function clearShareable(/*# string */ $scope = '')
91
    {
92
        if (static::hasShareable($scope)) {
93
            $shared = static::getShareable($scope);
94
            $shared->shared_in = null;
95
            unset(self::$shareables[get_called_class()][$scope]);
96
        }
97
    }
98
99
    /**
100
     * {@inheritDoc}
101
     */
102
    public function setShareable(/*# string */ $scope = '')
103
    {
104
        // this $scope has shareable already
105
        if (static::hasShareable($scope)) {
106
            throw new RuntimeException(
107
                Message::get(Message::MSG_SHAREABLE_DUPPED, $scope),
108
                Message::MSG_SHAREABLE_DUPPED
109
            );
110
        }
111
112
        // try assign $this shareable to another scope
113
        if ($this->isShareable() !== false) {
114
            throw new RuntimeException(
115
                Message::get(
116
                    Message::MSG_SHAREABLE_ALREADY,
117
                    $this->isShareable() ?: 'GLBOAL'
118
                ),
119
                Message::MSG_SHAREABLE_ALREADY
120
            );
121
        }
122
123
        $this->shared_in = $scope;
124
        self::$shareables[get_class($this)][$scope] = $this;
125
126
        return $this;
127
    }
128
129
    /**
130
     * {@inheritDoc}
131
     */
132
    public function addScope(/*# string */ $scope)
133
    {
134
        if ($this->isShareable() === false &&
135
            !$this->hasScope($scope)
136
        ) {
137
            $this->scopes[] = $scope;
138
        }
139
        return $this;
140
    }
141
142
    /**
143
     * {@inheritDoc}
144
     */
145
    public function hasScope(/*# string */ $scope = '')/*# : bool */
146
    {
147
        return in_array($scope, $this->getScopes());
148
    }
149
150
    /**
151
     * {@inheritDoc}
152
     */
153
    public function getShareables()/*# : array */
154
    {
155
        $result = [];
156
        foreach ($this->getScopes() as $scope) {
157
            $result[] = static::getShareable($scope);
158
        }
159
        return $result;
160
    }
161
162
    /**
163
     * {@inheritDoc}
164
     */
165
    public function isShareable()
166
    {
167
        return is_null($this->shared_in) ? false : $this->shared_in;
168
    }
169
170
    /**
171
     * Get all unique scopes for $this if not a shared instance
172
     *
173
     * @return array
174
     * @access protected
175
     */
176
    protected function getScopes()/*# : array */
177
    {
178
        $result = [];
179
180
        // skip shareable
181
        if ($this->isShareable() !== false) {
182
            return $result;
183
        }
184
185
        foreach ($this->scopes as $scope) {
186
            $result = array_merge($result, $this->splitScope($scope));
187
        }
188
189
        // add the global scope
190
        $result[] = '';
191
192
        return array_unique($result);
193
    }
194
195
    /**
196
     * Split a scope of 'vendor.app' into ['vendor.app', 'vendor']
197
     *
198
     * @param  string $scope
199
     * @return array
200
     * @access protected
201
     */
202
    protected function splitScope(/*# string */ $scope)/*# : array */
203
    {
204
        $result = [];
205
        $parts = explode('.', $scope);
206
207
        while (!empty($parts)) {
208
            $result[] = join('.', $parts);
209
            array_pop($parts);
210
        }
211
212
        return $result;
213
    }
214
}
215