Completed
Push — master ( b1b59b...7d45b7 )
by Hong
02:53
created

MappingTrait::loadMappings()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 19
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
c 2
b 0
f 0
dl 0
loc 19
rs 9.4285
cc 3
eloc 9
nc 2
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\Message\Mapping;
16
17
use Phossa2\Shared\Message\Loader\LoaderAwareTrait;
18
19
/**
20
 * MappingTrait
21
 *
22
 * One implementation of `MappingInterface`
23
 *
24
 * @package Phossa2\Shared
25
 * @author  Hong Zhang <[email protected]>
26
 * @see     MappingInterface
27
 * @version 2.0.0
28
 * @since   2.0.0 added
29
 */
30
trait MappingTrait
31
{
32
    use LoaderAwareTrait;
33
34
    /**
35
     * Ddefault messages for current message class
36
     *
37
     * This property HAS TO BE redefined for each descendant message class !
38
     *
39
     * @var    string[]
40
     * @access protected
41
     */
42
    protected static $messages = [];
43
44
    /**
45
     * Message mapping cache
46
     *
47
     * @var    array
48
     * @access private
49
     */
50
    private static $mappings = [];
51
52
    /**
53
     * Reset current message class' code to message mappings cache
54
     *
55
     * ```php
56
     *     MyMessage::setMappings([
57
     *         MyMessage::MSG_HELLO => 'Hello %s'
58
     *     ]);
59
     * ```
60
     *
61
     * @param  array $messages messages mapping array
62
     * @param  bool $manual manually, not auto load from $loader
63
     * @access public
64
     * @api
65
     */
66
    public static function setMappings(
67
        array $messages,
68
        /*# bool */ $manual = true
69
    ) {
70
        $class = get_called_class();
71
72
        if ($manual) {
73
            // set default
74
            static::$messages = $messages;
75
76
            // status changed
77
            self::setStatus();
78
        } else {
79
            // set cache
80
            self::$mappings[$class] = array_replace(
81
                $class::getMappings(),
82
                $messages
83
            );
84
        }
85
    }
86
87
    /**
88
     * Check current class' message mapping cache
89
     *
90
     * @return bool
91
     * @access protected
92
     */
93
    protected static function hasMappings()/*# : bool */
94
    {
95
        return isset(self::$mappings[get_called_class()]);
96
    }
97
98
    /**
99
     * Get current class' message mapping, default or cached
100
     *
101
     * @return array
102
     * @access protected
103
     */
104
    protected static function getMappings()/*# : array */
105
    {
106
        // use cached first if any
107
        if (static::hasMappings()) {
108
            return self::$mappings[get_called_class()];
109
        }
110
111
        // return the default
112
        return static::$messages;
113
    }
114
115
    /**
116
     * Clear the mapping cache
117
     *
118
     * @access protected
119
     */
120
    protected static function resetMappings()
121
    {
122
        self::$mappings = [];
123
    }
124
125
    /**
126
     * Check message template in default mapping
127
     *
128
     * @param  int $code the message code
129
     * @return bool
130
     * @access protected
131
     */
132
    protected static function messageDefined(/*# int */ $code)/*# : bool */
133
    {
134
        return isset(static::$messages[$code]);
135
    }
136
137
    /**
138
     * Resolving code for current message class, from cache or default
139
     *
140
     * If nothing found, return the code anyway
141
     *
142
     * @param  int $code the message code
143
     * @return string
144
     * @access protected
145
     */
146
    protected static function getMessage(/*# int */ $code)/*# : string */
147
    {
148
        $mapping = static::getMappings();
149
        if (isset($mapping[$code])) {
150
            return $mapping[$code];
151
        }
152
        return (string) $code;
153
    }
154
155
    /**
156
     * Resolving $code to message template, start from $class
157
     *
158
     * @param  int $code message code
159
     * @param  string $class class name
160
     * @return string
161
     * @access protected
162
     */
163
    protected static function getTemplateByCode(
164
        /*# int */ $code,
165
        /*# string */ $class
166
    )/*# : string */ {
167
        // search $code upwards in inheritance tree
168
        do {
169
            // default message template
170
            $template = 'message: %s';
171
172
            // code is defined for $class
173
            if ($class::messageDefined($code)) {
174
                // load message mapping for $class
175
                $class::loadMappings();
176
177
                // get the message template
178
                $template = $class::getMessage($code);
179
                break;
180
            }
181
182
            // last resort, use the default message template
183
            if ($class === __CLASS__) {
184
                break;
185
            }
186
187
            $class = get_parent_class($class);
188
189
        } while ($class);
190
191
        return $template;
192
    }
193
194
    /**
195
     * Load message mappings into cache for $class
196
     *
197
     * @access protected
198
     */
199
    protected static function loadMappings()
200
    {
201
        // check status
202
        self::checkStatus();
203
204
        // mapping cache loaded already for $class
205
        if (static::hasMappings()) {
206
            return;
207
        }
208
209
        // load $class mapping
210
        $loadedClass = static::hasLoader(true);
211
        static::setMappings(
212
            $loadedClass ?
213
                $loadedClass::getLoader()->loadMessages(get_called_class()) :
214
                [],
215
            false
216
        );
217
    }
218
219
    /**
220
     * Update mapping cache if status changed
221
     *
222
     * @access protected
223
     */
224
    protected static function checkStatus()
225
    {
226
        if (self::isStatusUpdated()) {
227
            self::resetMappings();
228
            self::setStatus(false);
229
        }
230
    }
231
}
232