ConfigWriter::findConfigKeyValuePairAsTokens()   C
last analyzed

Complexity

Conditions 14
Paths 44

Size

Total Lines 50
Code Lines 29

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 14
eloc 29
nc 44
nop 3
dl 0
loc 50
rs 5.3716
c 0
b 0
f 0

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/*
3
 * This file is part of the Divergence package.
4
 *
5
 * (c) Henry Paradiz <[email protected]>
6
 *
7
 * For the full copyright and license information, please view the LICENSE
8
 * file that was distributed with this source code.
9
 */
10
namespace Divergence\CLI;
11
12
use Divergence\CLI\Command;
13
14
class ConfigWriter
15
{
16
17
    /*
18
     *  get source
19
     */
20
    public static function get_source($filename)
21
    {
22
        return file_get_contents($filename);
23
    }
24
25
    public static function set_source($filename, $source)
26
    {
27
        return file_put_contents($filename, $source);
28
    }
29
30
    /*
31
     *  get PHP tokens from filename
32
     */
33
    public static function get_tokens($filename)
34
    {
35
        return token_get_all(static::get_source($filename));
36
    }
37
38
    /*
39
     *  Rewrites db config based on passed in label and config
40
     */
41
    public static function configWriter($label, $config)
42
    {
43
        $climate = Command::getClimate();
44
45
        $climate->info(sprintf('Writing config: %s', $label));
46
        
47
        $existing = Env::getConfig(getcwd(), 'db');
48
        if ($existing[$label]) {
49
            $newConfig = static::editConfig($label, $config);
50
        } else {
51
            //  TODO: create new append
52
        }
53
        static::set_source(getcwd().'/config/db.php', $newConfig);
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $newConfig does not seem to be defined for all execution paths leading up to this point.
Loading history...
54
    }
55
56
    /*
57
     *  Tokenizes a config file replacing only the tokens we want to change and converts it back to PHP source
58
     *
59
     *  @returns string Divergence DB Config (PHP source code)
60
     */
61
    public static function editConfig($label, $config)
62
    {
63
        $climate = Command::getClimate();
64
        $climate->info('Config already exists so we need to rewrite.');
65
        $filename = getcwd().'/config/db.php';
66
        $tokens = static::get_tokens($filename);
67
        foreach ($config as $setting=>$value) {
68
            $tokens = ConfigWriter::tokenizedConfigValueRewriter($tokens, $label, $setting, $value);
69
        }
70
        return static::tokensToString($tokens);
71
    }
72
73
    /*
74
     *  Safely edits config tokens without changing human edits
75
     *
76
     *  @returns array  Edited tokens
77
     */
78
    public static function tokenizedConfigValueRewriter($tokens, $label, $setting, $value)
79
    {
80
        $climate = Command::getClimate();
81
        
82
        // find the key value pair we want in the existing config
83
        $found = static::findConfigKeyValuePairAsTokens($tokens, $label, $setting);
84
        if ($found) {
85
            $climate->info(sprintf('Rewriting tokens: %s[\'%s\'] = %s;', $label, $setting, $value)); // make for verbose mode
86
            // replace tokens and rebuild PHP file
87
            $index = $found['value']['index'];
88
            $token = $found['value']['token'];
89
            $value = addslashes($value);
90
            $token[1] = "'$value'";
91
            $tokens[$index] = $token;
92
        } else {
93
            // TODO: label exists but no key => value pair, create a new one at the end
94
        }
95
        
96
        return $tokens;
97
    }
98
99
    /*
100
     *  Converts tokens to PHP source code
101
     *
102
     *  @param  array $tokens Tokens in same format returned by token_get_all()
103
     *  @returns  string    PHP source code
104
     */
105
    public static function tokensToString($tokens)
106
    {
107
        $output;
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $output seems to be never defined.
Loading history...
108
        foreach ($tokens as $token) {
109
            if (is_array($token)) {
110
                $output .= $token[1];
111
            } else {
112
                $output .= $token;
113
            }
114
        }
115
        return $output;
116
    }
117
118
    /*
119
     *  Locates the key and value for the specific db config setting we want
120
     */
121
    public static function findConfigKeyValuePairAsTokens($tokens, $label, $setting)
122
    {
123
        //$climate = Command::getClimate();
124
        $depth = 0;
125
        $returnTokens = [];
126
        foreach ($tokens as $key=>$token) {
127
            if ($token == '[') {
128
                $depth++;
129
                continue;
130
            }
131
            // find config label
132
            if ($depth === 1 && $token[0]==323) { // T_CONSTANT_ENCAPSED_STRING
133
                $strValue = substr($token[1], 1, -1);
134
                if ($strValue == $label) {
135
                    $labelLine = $token[2]; // remember line # where the config we care about starts
136
                    $nextKey = true;
137
                }
138
            }
139
140
            // find key value pair
141
            if ($labelLine) {
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $labelLine does not seem to be defined for all execution paths leading up to this point.
Loading history...
142
                if ($depth === 2 && $token[0]==323) {
143
                    if ($nextKey) {
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $nextKey does not seem to be defined for all execution paths leading up to this point.
Loading history...
144
                        $nextKey = false;
145
                        // found key for setting
146
                        $strValue = substr($token[1], 1, -1);
147
                        if ($strValue === $setting) {
148
                            $returnTokens['key'] = ['token'=>$token,'index'=>$key];
149
                            //$climate->out(sprintf('Found key <yellow>%s</yellow> at line <green>%s</green>',$token[1],$token[2])); // make verbose mode
150
                            continue;
151
                        }
152
                    } else {
153
                        // next value once setting is found is the value we want
154
                        if ($returnTokens['key']) {
155
                            $strValue = substr($token[1], 1, -1);
0 ignored issues
show
Unused Code introduced by
The assignment to $strValue is dead and can be removed.
Loading history...
156
                            //$climate->out(sprintf('Found value <yellow>%s</yellow> at line <green>%s</green>',$token[1],$token[2])); // make verbose mode
157
                            $returnTokens['value'] = ['token'=>$token,'index'=>$key];
158
                            return $returnTokens;
159
                        }
160
                        $nextKey = true;
161
                    }
162
                }
163
            }
164
165
            // keep track of closing brackets so we can ignore things
166
            if ($token == ']') {
167
                $depth--;
168
169
                if ($depth === 1) {
170
                    unset($labelLine); // clear line number once we detect the end
171
                }
172
            }
173
        }
174
    }
175
}
176