Completed
Push — master ( b2c081...7ac994 )
by Hong
02:32
created

ReferenceTrait::deReferenceArray()   B

Complexity

Conditions 5
Paths 5

Size

Total Lines 14
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 14
rs 8.8571
cc 5
eloc 8
nc 5
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\RuntimeException;
19
20
/**
21
 * ReferenceTrait
22
 *
23
 * Provides reference & dereference methods
24
 *
25
 * @package Phossa2\Shared
26
 * @author  Hong Zhang <[email protected]>
27
 * @see     ReferenceInterface
28
 * @version 2.0.4
29
 * @since   2.0.4 added
30
 */
31
trait ReferenceTrait
32
{
33
    /**
34
     * refernece start chars
35
     *
36
     * @var    string
37
     * @access protected
38
     */
39
    protected $ref_start = '${';
40
41
    /**
42
     * reference ending chars
43
     *
44
     * @var    string
45
     * @access protected
46
     */
47
    protected $ref_end = '}';
48
49
    /**
50
     * cached pattern to match
51
     *
52
     * @var    string
53
     * @access protected
54
     */
55
    protected $ref_pattern;
56
57
    /**
58
     * unresolved reference
59
     *
60
     * @var    array
61
     * @access protected
62
     */
63
    protected $unresolved = [];
64
65
    /**
66
     * {@inheritDoc}
67
     */
68
    public function setReference(
69
        /*# string */ $start,
70
        /*# string */ $end
71
    ) {
72
        $this->ref_start = $start;
73
        $this->ref_end = $end;
74
75
        // build pattern
76
        $s = preg_quote($start);
77
        $e = preg_quote($end);
78
        $this->ref_pattern = sprintf(
79
            "~(%s((?:(?!%s|%s).)+?)%s)~", $s, $s, $e, $e
80
        );
81
82
        return $this;
83
    }
84
85
    /**
86
     * {@inheritDoc}
87
     */
88
    public function hasReference(
89
        /*# string */ $subject,
90
        array &$matched
91
    )/*# : bool */ {
92
        $m = [];
0 ignored issues
show
Unused Code introduced by
$m is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
93
        if (is_string($subject) &&
94
            false !== strpos($subject, $this->ref_start) &&
95
            preg_match($this->ref_pattern, $subject, $matched)
96
        ) {
97
            return true;
98
        }
99
        return false;
100
    }
101
102
    /**
103
     * {@inheritDoc}
104
     */
105
    public function deReference(/*# string */ $subject)
106
    {
107
        $loop = 0;
108
        $matched = [];
109
        while ($loop++ < 8 && $this->hasReference($subject, $matched)) {
110
            // resolving
111
            $val = $this->resolveReference($matched[2]);
112
113
            // full match
114
            if ($matched[1] === $subject) {
115
                return $val;
116
117
            // partial matched
118
            } elseif (is_string($val)) {
119
                $subject = str_replace($matched[1], $val, $subject);
120
121
            // malformed
122
            } else {
123
                throw new RuntimeException(
124
                    Message::get(Message::MSG_REF_MALFORMED, $subject),
125
                    Message::MSG_REF_MALFORMED
126
                );
127
            }
128
        }
129
        return $subject;
130
    }
131
132
    /**
133
     * {@inheritDoc}
134
     */
135
    public function deReferenceArray(array &$dataArray)
136
    {
137
        foreach ($dataArray as $idx => &$data) {
138
            if (is_array($data)) {
139
                $this->dereferenceArray($data);
140
141
            } elseif (is_string($data)) {
142
                $data = $this->deReference($data);
143
                if (is_array($data)) {
144
                    $this->dereferenceArray($data);
145
                }
146
            }
147
        }
148
    }
149
150
    /**
151
     * Resolve the reference $name
152
     *
153
     * @param  string $name
154
     * @return mixed
155
     * @access protected
156
     */
157
    protected function resolveReference(/*# string */ $name)
158
    {
159
        // unresolved found
160
        if (isset($this->unresolved[$name])) {
161
            return $this->unresolved[$name];
162
        }
163
164
        // get the referenced value
165
        $val = $this->getReference($name);
166
167
        // not found
168
        if (is_null($val)) {
169
            $this->unresolved[$name] = $this->resolveUnknown($name);
170
            return $this->unresolved[$name];
171
172
        // found it
173
        } else {
174
            return $val;
175
        }
176
    }
177
178
    /**
179
     * For unknown reference $name
180
     *
181
     * @param  string $name
182
     * @return mixed
183
     * @access protected
184
     */
185
    abstract protected function resolveUnknown(/*# string */ $name);
186
187
    /**
188
     * The real resolving method. return NULL for unknown reference
189
     *
190
     * @param  string $name
191
     * @return mixed
192
     * @access protected
193
     */
194
    abstract protected function getReference(/*# string */ $name);
195
}
196