Completed
Push — master ( f4e5db...37e69c )
by Hong
02:48
created

ShareableTrait::clearShareable()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 8
rs 9.4285
cc 2
eloc 5
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 protected
36
     * @staticvar
37
     */
38
    protected 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
     * {@inheritDoc}
58
     */
59
    public static function getShareable(
60
        /*# string */ $scope = ''
61
    )/*# : ShareableInterface */ {
62
        if (!static::hasShareable($scope)) {
63
            (new static())->setShareable($scope);
64
        }
65
        return self::$shareables[get_called_class()][$scope];
66
    }
67
68
    /**
69
     * {@inheritDoc}
70
     */
71
    public function setShareable(/*# string */ $scope = '')
72
    {
73
        // this $scope has shareable already or $this is a shareable
74
        if (static::hasShareable($scope) || $this->isShareable() !== false) {
75
            throw new RuntimeException(
76
                Message::get(Message::MSG_SHAREABLE_FAIL, $scope),
77
                Message::MSG_SHAREABLE_FAIL
78
            );
79
        }
80
81
        $this->shared_in = $scope;
82
        self::$shareables[get_class($this)][$scope] = $this;
83
84
        return $this;
85
    }
86
87
    /**
88
     * {@inheritDoc}
89
     */
90
    public function isShareable()
91
    {
92
        return is_null($this->shared_in) ? false : $this->shared_in;
93
    }
94
95
    /**
96
     * {@inheritDoc}
97
     */
98
    public function addScope(/*# string */ $scope)
99
    {
100
        if ($this->isShareable() === false) {
101
            $this->scopes[] = $scope;
102
        }
103
        return $this;
104
    }
105
106
    /**
107
     * {@inheritDoc}
108
     */
109
    public function hasScope(/*# string */ $scope = '')/*# : bool */
110
    {
111
        return in_array($scope, static::getScopes($this->scopes));
112
    }
113
114
    /**
115
     * {@inheritDoc}
116
     */
117
    public function getShareables()/*# : array */
118
    {
119
        $result = [];
120
        foreach (static::getScopes($this->scopes) as $scope) {
121
            $result[] = static::getShareable($scope);
122
        }
123
        return $result;
124
    }
125
126
    /**
127
     * Test existense of shareable in $scope
128
     *
129
     * @param  string $scope
130
     * @return bool
131
     * @access protected
132
     */
133
    protected static function hasShareable(
134
        /*# string */ $scope = ''
135
    )/*# : bool */ {
136
        return isset(self::$shareables[get_called_class()][$scope]);
137
    }
138
139
    /**
140
     * Get all unique scopes for $this if not a shared instance
141
     *
142
     * @param  string|array $scopes
143
     * @return array
144
     * @access protected
145
     * @static
146
     */
147
    protected static function getScopes($scopes)/*# : array */
148
    {
149
        $result = [];
150
151
        foreach ((array) $scopes as $scope) {
152
            $result = array_merge($result, static::splitScope($scope));
153
        }
154
155
        // add global scope
156
        $result[] = '';
157
158
        return array_unique($result);
159
    }
160
161
    /**
162
     * Split a scope of 'vendor.app' into ['vendor.app', 'vendor']
163
     *
164
     * @param  string $scope
165
     * @return array
166
     * @access protected
167
     * @static
168
     */
169
    protected static function splitScope(/*# string */ $scope)/*# : array */
170
    {
171
        $result = [];
172
        $parts = explode('.', $scope);
173
174
        while (!empty($parts)) {
175
            $result[] = join('.', $parts);
176
            array_pop($parts);
177
        }
178
179
        return $result;
180
    }
181
}
182