Completed
Push — master ( 56a90a...da2227 )
by Hong
02:29
created

ShareableTrait::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

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