Completed
Push — master ( 3bd0a2...b2c081 )
by Hong
03:17
created

ReferenceTrait::deReference()   B

Complexity

Conditions 5
Paths 5

Size

Total Lines 27
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
c 1
b 0
f 1
dl 0
loc 27
rs 8.439
cc 5
eloc 12
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
/**
18
 * ReferenceTrait
19
 *
20
 * Provides reference & dereference methods
21
 *
22
 * @package Phossa2\Shared
23
 * @author  Hong Zhang <[email protected]>
24
 * @see     ReferenceInterface
25
 * @version 2.0.4
26
 * @since   2.0.4 added
27
 */
28
trait ReferenceTrait
29
{
30
    /**
31
     * refernece start chars
32
     *
33
     * @var    string
34
     * @access protected
35
     */
36
    protected $ref_start = '${';
37
38
    /**
39
     * reference ending chars
40
     *
41
     * @var    string
42
     * @access protected
43
     */
44
    protected $ref_end = '}';
45
46
    /**
47
     * pattern to match
48
     *
49
     * @var    string
50
     * @access protected
51
     */
52
    protected $ref_pattern;
53
54
    /**
55
     * unresolved reference
56
     *
57
     * @var    array
58
     * @access protected
59
     */
60
    protected $unresolved = [];
61
62
    /**
63
     * {@inheritDoc}
64
     */
65
    public function setReference(
66
        /*# string */ $start,
67
        /*# string */ $end
68
    ) {
69
        $this->ref_start = $start;
70
        $this->ref_end = $end;
71
72
        // build pattern
73
        $s = preg_quote($start);
74
        $e = preg_quote($end);
75
        $this->ref_pattern = sprintf(
76
            "~(%s((?:(?!%s|%s).)+?)%s)~", $s, $s, $e, $e
77
        );
78
79
        return $this;
80
    }
81
82
    /**
83
     * {@inheritDoc}
84
     */
85
    public function hasReference(
86
        /*# string */ $subject,
87
        array &$matched
88
    )/*# : bool */ {
89
        $m = [];
90
        if (is_string($subject) &&
91
            false !== strpos($subject, $this->ref_start) &&
92
            preg_match($this->ref_pattern, $subject, $m)
93
        ) {
94
            $matched[$m[1]] = $m[2];
95
            return true;
96
        }
97
        return false;
98
    }
99
100
    /**
101
     * {@inheritDoc}
102
     */
103
    public function deReference(/*# string */ $subject)
104
    {
105
        $loop = 0;
106
        $matched = [];
107
        while ($this->hasReference($subject, $matched)) {
108
            // resolving
109
            $val = $this->resolveReference($matched[1]);
110
111
            // loop found
112
            if ($loop++ > 10) {
0 ignored issues
show
Unused Code introduced by
This if statement is empty and can be removed.

This check looks for the bodies of if statements that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.

These if bodies can be removed. If you have an empty if but statements in the else branch, consider inverting the condition.

if (rand(1, 6) > 3) {
//print "Check failed";
} else {
    print "Check succeeded";
}

could be turned into

if (rand(1, 6) <= 3) {
    print "Check succeeded";
}

This is much more concise to read.

Loading history...
113
                // throw exception
114
115
            // matched whole target
116
            } elseif ($matched[0] === $subject) {
117
                return $val;
118
119
            // partial matched
120
            } elseif (is_string($val)) {
121
                $subject = str_replace($matched[0], $val, $subject);
122
123
            // malformed target
124
            } else {
0 ignored issues
show
Unused Code introduced by
This else statement is empty and can be removed.

This check looks for the else branches of if statements that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.

These else branches can be removed.

if (rand(1, 6) > 3) {
print "Check failed";
} else {
    //print "Check succeeded";
}

could be turned into

if (rand(1, 6) > 3) {
    print "Check failed";
}

This is much more concise to read.

Loading history...
125
                // throw exception
126
            }
127
        }
128
        return $subject;
129
    }
130
131
    /**
132
     * Resolve the reference $name
133
     *
134
     * @param  string $name
135
     * @return mixed
136
     * @access protected
137
     */
138
    protected function resolveReference(/*# string */ $name)
139
    {
140
        $val = $this->getReference($name);
141
142
        // not found
143
        if (is_null($val)) {
144
            $this->unresolved[$name] = true;
145
            return $this->resolveUnknown($name);
146
147
        // found it
148
        } else {
149
            return $val;
150
        }
151
    }
152
153
    /**
154
     * For unknown reference $name, NEED OVERLOAD
155
     *
156
     * @param  string $name
157
     * @return mixed
158
     * @access protected
159
     */
160
    protected function resolveUnknown(/*# string */ $name)
0 ignored issues
show
Unused Code introduced by
The parameter $name is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
161
    {
162
        return '';
163
    }
164
165
    /**
166
     * The real resolving method. return NULL for unknown reference
167
     *
168
     * @param  string $name
169
     * @return mixed
170
     * @access protected
171
     */
172
    abstract protected function getReference(/*# string */ $name);
173
}
174