Completed
Push — master ( 558df7...329d64 )
by Hong
03:22
created

DelegatorTrait::addContainer()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 17
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 17
rs 9.4285
cc 2
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\Reference;
16
17
use Phossa2\Shared\Message\Message;
18
use Phossa2\Shared\Exception\NotFoundException;
19
use Phossa2\Shared\Exception\InvalidArgumentException;
20
21
/**
22
 * DelegatorTrait
23
 *
24
 * Implementation of DelegatorInterface
25
 *
26
 * @package Phossa2\Shared
27
 * @author  Hong Zhang <[email protected]>
28
 * @see     DelegatorInterface
29
 * @version 2.0.8
30
 * @since   2.0.8 added
31
 */
32
trait DelegatorTrait
33
{
34
    /**
35
     * lookup pool of containers
36
     *
37
     * @var    array
38
     * @access private
39
     */
40
    private $lookup_pool = [];
41
42
    /**
43
     * cached lookup key
44
     *
45
     * @var    string
46
     * @access private
47
     */
48
    private $cache_key;
49
50
    /**
51
     * cached lookup container
52
     *
53
     * @var    object
54
     * @access private
55
     */
56
    private $cache_obj;
57
58
    /**
59
     * {@inheritDoc}
60
     */
61
    public function addContainer($container)
62
    {
63
        if ($this->isValidContainer($container)) {
64
            // remove container if exists already
65
            $this->removeFromLookup($container);
66
67
            // append to the pool end
68
            $this->lookup_pool[] = $container;
69
70
            return $this;
71
        }
72
73
        throw new InvalidArgumentException(
74
            Message::get(Message::MSG_ARGUMENT_INVALID, get_class($container)),
75
            Message::MSG_ARGUMENT_INVALID
76
        );
77
    }
78
79
    /**
80
     * {@inheritDoc}
81
     */
82
    public function hasInLookup(/*# string */ $key)/*# : bool */
83
    {
84
        foreach ($this->lookup_pool as $container) {
85
            if ($this->hasInContainer($container, $key)) {
86
                $this->cache_key = $key;
87
                $this->cache_obj = $container;
88
                return true;
89
            }
90
        }
91
        return false;
92
    }
93
94
    /**
95
     * {@inheritDoc}
96
     */
97
    public function getFromLookup(/*# string */ $key)
98
    {
99
        // check cache first
100
        if ($key === $this->cache_key) {
101
            return $this->getFromContainer($this->cache_obj, $key);
102
        }
103
104
        // try lookup
105
        if ($this->hasInLookup($key)) {
106
            return $this->getFromContainer($this->cache_obj, $key);
107
        }
108
109
        // not found
110
        throw new NotFoundException(
111
            Message::get(Message::MSG_REF_UNKNOWN, $key),
112
            Message::MSG_REF_UNKNOWN
113
        );
114
    }
115
116
    /**
117
     * Remove one object from the pool
118
     *
119
     * @param  object $container
120
     * @return $this
121
     * @access protected
122
     */
123
    protected function removeFromLookup($container)
124
    {
125
        foreach ($this->lookup_pool as $idx => $obj) {
126
            if ($container === $obj) {
127
                unset($this->lookup_pool[$idx]);
128
            }
129
        }
130
        return $this;
131
    }
132
133
    /**
134
     * Is container type allowed in lookup pool ?
135
     *
136
     * @param  object $container
137
     * @return bool
138
     * @access protected
139
     */
140
    abstract protected function isValidContainer($container)/*# : bool */;
141
142
    /**
143
     * Try has in container
144
     *
145
     * @param  object $container
146
     * @param  name $key
147
     * @return bool
148
     * @access protected
149
     */
150
    abstract protected function hasInContainer(
151
        $container,
152
        /*# string */ $key
153
    )/*# : bool */;
154
155
    /**
156
     * Try get from container
157
     *
158
     * @param  object $container
159
     * @param  name $key
160
     * @return mixed
161
     * @access protected
162
     */
163
    abstract protected function getFromContainer(
164
        $container,
165
        /*# string */ $key
166
    );
167
}
168