Completed
Push — master ( 3eb51e...56a90a )
by Hong
02:37
created

ShareableTrait::setShareable()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 15
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 3
Bugs 0 Features 1
Metric Value
c 3
b 0
f 1
dl 0
loc 15
rs 9.4285
cc 3
eloc 8
nc 2
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 or $this is a shareable
105
        if (static::hasShareable($scope) || $this->isShareable() !== false) {
106
            throw new RuntimeException(
107
                Message::get(Message::MSG_SHAREABLE_FAIL, $scope),
108
                Message::MSG_SHAREABLE_FAIL
109
            );
110
        }
111
112
        $this->shared_in = $scope;
113
        self::$shareables[get_class($this)][$scope] = $this;
114
115
        return $this;
116
    }
117
118
    /**
119
     * {@inheritDoc}
120
     */
121
    public function addScope(/*# string */ $scope)
122
    {
123
        if ($this->isShareable() === false &&
124
            !$this->hasScope($scope)
125
        ) {
126
            $this->scopes[] = $scope;
127
        }
128
        return $this;
129
    }
130
131
    /**
132
     * {@inheritDoc}
133
     */
134
    public function hasScope(/*# string */ $scope = '')/*# : bool */
135
    {
136
        return in_array($scope, $this->getScopes());
137
    }
138
139
    /**
140
     * {@inheritDoc}
141
     */
142
    public function getShareables()/*# : array */
143
    {
144
        $result = [];
145
        foreach ($this->getScopes() as $scope) {
146
            $result[] = static::getShareable($scope);
147
        }
148
        return $result;
149
    }
150
151
    /**
152
     * {@inheritDoc}
153
     */
154
    public function isShareable()
155
    {
156
        return is_null($this->shared_in) ? false : $this->shared_in;
157
    }
158
159
    /**
160
     * Get all unique scopes for $this if not a shared instance
161
     *
162
     * @return array
163
     * @access protected
164
     */
165
    protected function getScopes()/*# : array */
166
    {
167
        $result = [];
168
169
        // skip shareable
170
        if ($this->isShareable() !== false) {
171
            return $result;
172
        }
173
174
        foreach ($this->scopes as $scope) {
175
            $result = array_merge($result, $this->splitScope($scope));
176
        }
177
178
        // add the global scope
179
        $result[] = '';
180
181
        return array_unique($result);
182
    }
183
184
    /**
185
     * Split a scope of 'vendor.app' into ['vendor.app', 'vendor']
186
     *
187
     * @param  string $scope
188
     * @return array
189
     * @access protected
190
     */
191
    protected function splitScope(/*# string */ $scope)/*# : array */
192
    {
193
        $result = [];
194
        $parts = explode('.', $scope);
195
196
        while (!empty($parts)) {
197
            $result[] = join('.', $parts);
198
            array_pop($parts);
199
        }
200
201
        return $result;
202
    }
203
}
204