Completed
Push — master ( 2f4f79...77df0a )
by P.R.
07:18
created

BaseCommand::rewriteConfig()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 7
rs 9.4285
cc 2
eloc 3
nc 2
nop 0
1
<?php
2
//----------------------------------------------------------------------------------------------------------------------
3
namespace SetBased\Audit\Command;
4
5
use SetBased\Exception\RuntimeException;
6
use SetBased\Stratum\Style\StratumStyle;
7
use Symfony\Component\Console\Command\Command;
8
use Symfony\Component\Console\Formatter\OutputFormatter;
9
10
//----------------------------------------------------------------------------------------------------------------------
11
/**
12
 * Base command for other commands of AuditApplication.
13
 */
14
class BaseCommand extends Command
15
{
16
  //--------------------------------------------------------------------------------------------------------------------
17
  /**
18
   * All config file as array.
19
   *
20
   * @var array
21
   */
22
  protected $config;
23
24
  /**
25
   * The name of the configuration file.
26
   *
27
   * @var string
28
   */
29
  protected $configFileName;
30
31
  /**
32
   * The Output decorator.
33
   *
34
   * @var StratumStyle
35
   */
36
  protected $io;
37
38
  /**
39
   * If set (the default) the config file must be rewritten. Set to false for testing only.
40
   *
41
   * @var bool
42
   */
43
  private $rewriteConfigFile = true;
44
45
  //--------------------------------------------------------------------------------------------------------------------
46
  /**
47
   * Returns the value of a setting.
48
   *
49
   * @param array  $settings    The settings as returned by parse_ini_file.
50
   * @param bool   $mandatory   If set and setting $settingName is not found in section $sectionName an exception
51
   *                            will be thrown.
52
   * @param string $sectionName The name of the section of the requested setting.
53
   * @param string $settingName The name of the setting of the requested setting.
54
   *
55
   * @return null|string
56
   *
57
   * @throws RuntimeException
58
   */
59
  protected static function getSetting($settings, $mandatory, $sectionName, $settingName)
60
  {
61
    // Test if the section exists.
62 View Code Duplication
    if (!array_key_exists($sectionName, $settings))
1 ignored issue
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
63
    {
64
      if ($mandatory)
65
      {
66
        throw new RuntimeException("Section '%s' not found in configuration file.", $sectionName);
67
      }
68
      else
69
      {
70
        return null;
71
      }
72
    }
73
74
    // Test if the setting in the section exists.
75 View Code Duplication
    if (!array_key_exists($settingName, $settings[$sectionName]))
1 ignored issue
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
76
    {
77
      if ($mandatory)
78
      {
79
        throw new RuntimeException("Setting '%s' not found in section '%s' configuration file.",
80
                                   $settingName,
81
                                   $sectionName);
82
      }
83
      else
84
      {
85
        return null;
86
      }
87
    }
88
89
    return $settings[$sectionName][$settingName];
90
  }
91
92
  //--------------------------------------------------------------------------------------------------------------------
93
  /**
94
   * Reads configuration parameters from the configuration file.
95
   */
96
  public function readConfigFile()
97
  {
98
    $content = file_get_contents($this->configFileName);
99
100
    $this->config = (array)json_decode($content, true);
101
    if (json_last_error()!=JSON_ERROR_NONE)
102
    {
103
      throw new RuntimeException("Error decoding JSON: '%s'.", json_last_error_msg());
104
    }
105
106
    if (!is_array($this->config['audit_columns']))
107
    {
108
      $this->config['audit_columns'] = [];
109
    }
110
111
    if (!is_array($this->config['additional_sql']))
112
    {
113
      $this->config['additional_sql'] = [];
114
    }
115
116
    if (!is_array($this->config['tables']))
117
    {
118
      $this->config['tables'] = [];
119
    }
120
121
    foreach ($this->config['tables'] as $table_name => $params)
122
    {
123
      $this->config['tables'][$table_name]['audit'] = filter_var($params['audit'], FILTER_VALIDATE_BOOLEAN);
124
    }
125
  }
126
127
  //--------------------------------------------------------------------------------------------------------------------
128
  /**
129
   * Use for testing only.
130
   *
131
   * @param bool $rewriteConfigFile If true the config file must be rewritten. Otherwise the config must not be
132
   *                                rewritten.
133
   */
134
  public function setRewriteConfigFile($rewriteConfigFile)
135
  {
136
    $this->rewriteConfigFile = $rewriteConfigFile;
137
  }
138
139
  //--------------------------------------------------------------------------------------------------------------------
140
  /**
141
   * Rewrites the config file with updated data.
142
   */
143
  protected function rewriteConfig()
144
  {
145
    // Return immediately when the config file must not be rewritten. 
146
    if (!$this->rewriteConfigFile) return;
147
148
    $this->writeTwoPhases($this->configFileName, json_encode($this->config, JSON_PRETTY_PRINT));
149
  }
150
151
  //--------------------------------------------------------------------------------------------------------------------
152
  /**
153
   * Writes a file in two phase to the filesystem.
154
   *
155
   * First write the data to a temporary file (in the same directory) and than renames the temporary file. If the file
156
   * already exists and its content is equal to the data that must be written no action  is taken. This has the
157
   * following advantages:
158
   * * In case of some write error (e.g. disk full) the original file is kept in tact and no file with partially data
159
   * is written.
160
   * * Renaming a file is atomic. So, running processes will never read a partially written data.
161
   *
162
   * @param string $filename The name of the file were the data must be stored.
163
   * @param string $data     The data that must be written.
164
   */
165
  protected function writeTwoPhases($filename, $data)
166
  {
167
    $write_flag = true;
168
    if (file_exists($filename))
169
    {
170
      $old_data = file_get_contents($filename);
171
      if ($data==$old_data) $write_flag = false;
172
    }
173
174
    if ($write_flag)
175
    {
176
      $tmp_filename = $filename.'.tmp';
177
      file_put_contents($tmp_filename, $data);
178
      rename($tmp_filename, $filename);
179
180
      $this->io->text(sprintf('Wrote <fso>%s</fso>', OutputFormatter::escape($filename)));
181
    }
182
    else
183
    {
184
      $this->io->text(sprintf('File <fso>%s</fso> is up to date', OutputFormatter::escape($filename)));
185
    }
186
  }
187
188
  //--------------------------------------------------------------------------------------------------------------------
189
}
190
191
//----------------------------------------------------------------------------------------------------------------------
192