Completed
Push — master ( 1f7a6d...d6c443 )
by P.R.
03:14
created

Audit::unknownTables()   A

Complexity

Conditions 6
Paths 6

Size

Total Lines 26
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 11
CRAP Score 6

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 6
eloc 12
c 1
b 0
f 0
nc 6
nop 0
dl 0
loc 26
ccs 11
cts 11
cp 1
crap 6
rs 9.2222
1
<?php
2
declare(strict_types=1);
3
4
namespace SetBased\Audit\Audit;
5
6
use SetBased\Audit\AuditTable;
7
use SetBased\Audit\Metadata\TableColumnsMetadata;
8
use SetBased\Audit\MySql\AuditDataLayer;
9
use SetBased\Audit\Style\AuditStyle;
10
use SetBased\Config\TypedConfig;
11
use SetBased\Stratum\Helper\RowSetHelper;
12
13
/**
14
 * Class for executing auditing actions for tables.
15
 */
16
class Audit
17
{
18
  //--------------------------------------------------------------------------------------------------------------------
19
  /**
20
   * The metadata of the additional audit columns.
21
   *
22
   * @var TableColumnsMetadata
23
   */
24
  private $additionalAuditColumns;
25
26
  /**
27
   * The names of all tables in audit schema.
28
   *
29
   * @var array
30
   */
31
  private $auditSchemaTables;
32
33
  /**
34
   * The strong typed configuration reader and writer.
35
   *
36
   * @var TypedConfig
37
   */
38
  private $config;
39
40
  /**
41
   * The names of all tables in data schema.
42
   *
43
   * @var array
44
   */
45
  private $dataSchemaTables;
46
47
  /**
48
   * The Output decorator.
49
   *
50
   * @var AuditStyle
51
   */
52
  private $io;
53
54
  //--------------------------------------------------------------------------------------------------------------------
55
  /**
56
   * Object constructor.
57
   *
58
   * @param TypedConfig $config The strong typed configuration reader and writer.
59
   * @param AuditStyle  $io     The Output decorator.
60
   */
61 29
  public function __construct(TypedConfig $config, AuditStyle $io)
62
  {
63 29
    $this->config = $config;
64 29
    $this->io     = $io;
65
66 29
    $this->additionalAuditColumns =
67 29
      AuditDataLayer::resolveCanonicalAdditionalAuditColumns($this->config->getManString('database.audit_schema'),
68 29
                                                             $this->config->getManArray('audit_columns'));
69 29
  }
70
71
  //--------------------------------------------------------------------------------------------------------------------
72
  /**
73
   * Getting list of all tables from information_schema of database from config file.
74
   */
75 29
  public function listOfTables(): void
76
  {
77 29
    $this->dataSchemaTables  = AuditDataLayer::getTablesNames($this->config->getManString('database.data_schema'));
78 29
    $this->auditSchemaTables = AuditDataLayer::getTablesNames($this->config->getManString('database.audit_schema'));
79 29
  }
80
81
  //--------------------------------------------------------------------------------------------------------------------
82
  /**
83
   * The main method: executes the auditing actions for tables.
84
   */
85 29
  public function main(): void
86
  {
87 29
    $this->listOfTables();
88
89 29
    $this->unknownTables();
90
91 29
    $this->obsoleteTables();
92
93 29
    $this->knownTables();
94 29
  }
95
96
  //--------------------------------------------------------------------------------------------------------------------
97
  /**
98
   * Removes tables listed in the config file that are not longer in the data schema from the config file.
99
   */
100 29
  public function obsoleteTables(): void
101
  {
102 29
    foreach ($this->config->getManArray('tables') as $tableName => $dummy)
103
    {
104 28
      if (RowSetHelper::searchInRowSet($this->dataSchemaTables, 'table_name', $tableName)===null)
105
      {
106 8
        $this->io->writeln(sprintf('<info>Removing obsolete table %s from config file</info>', $tableName));
107
108
        // Unset table (work a round bug in \Noodlehaus\Config::remove()).
109 8
        $config = $this->config->getConfig();
110 8
        $tables = $config['tables'];
111 8
        unset($tables[$tableName]);
112 28
        $config->set('tables', $tables);
113
      }
114
    }
115 29
  }
116
117
  //--------------------------------------------------------------------------------------------------------------------
118
  /**
119
   * Compares the tables listed in the config file and the tables found in the data schema.
120
   */
121 29
  public function unknownTables(): void
122
  {
123 29
    foreach ($this->dataSchemaTables as $table)
124
    {
125 28
      if ($this->config->getOptArray('tables.'.$table['table_name'])!==null)
126
      {
127 28
        if ($this->config->getOptBool('tables.'.$table['table_name'].'.audit')===null)
128
        {
129 1
          $this->io->writeln(sprintf('<info>Audit not set for table %s</info>', $table['table_name']));
130
        }
131
        else
132
        {
133 28
          if ($this->config->getManBool('tables.'.$table['table_name'].'.audit'))
134
          {
135 28
            if ($this->config->getOptString('tables.'.$table['table_name'].'.alias')===null)
136
            {
137 28
              $this->config->getConfig()->set('tables.'.$table['table_name'].'.alias', AuditTable::getRandomAlias());
138
            }
139
          }
140
        }
141
      }
142
      else
143
      {
144 1
        $this->io->writeln(sprintf('<info>Found new table %s</info>', $table['table_name']));
145 1
        $config = $this->config->getConfig();
146 28
        $config->set('tables.'.$table['table_name'], ['audit' => null, 'alias' => null, 'skip' => null]);
147
      }
148
    }
149 29
  }
150
151
  //--------------------------------------------------------------------------------------------------------------------
152
  /**
153
   * Processed known tables.
154
   */
155 29
  private function knownTables(): void
156
  {
157 29
    foreach ($this->dataSchemaTables as $table)
158
    {
159 28
      $audit = $this->config->getOptBool('tables.'.$table['table_name'].'.audit');
160 28
      if ($audit===true)
161
      {
162 28
        $currentTable = new AuditTable($this->io,
163 28
                                       $this->config->getManString('database.data_schema'),
164 28
                                       $this->config->getManString('database.audit_schema'),
165 28
                                       $table['table_name'],
166 28
                                       $this->additionalAuditColumns,
167 28
                                       $this->config->getOptString('tables.'.$table['table_name'].'.alias'),
168 28
                                       $this->config->getOptString('tables.'.$table['table_name'].'.skip'));
169
170
        // Ensure the audit table exists.
171 28
        if (RowSetHelper::searchInRowSet($this->auditSchemaTables, 'table_name', $table['table_name'])===null)
172
        {
173 25
          $currentTable->createAuditTable();
174
        }
175
176
        // Drop and create audit triggers and add new columns to the audit table.
177 28
        $currentTable->main($this->config->getManArray('additional_sql'));
178
      }
179 2
      elseif ($audit===false)
180
      {
181 1
        AuditTable::dropAuditTriggers($this->io,
182 1
                                      $this->config->getManString('database.data_schema'),
183 1
                                      $table['table_name']);
184
      }
185
      else /* $audit===null */
186
      {
187 28
        $this->io->logVerbose('Ignoring table <dbo>%s</dbo>', $table['table_name']);
188
      }
189
    }
190 29
  }
191
192
  //--------------------------------------------------------------------------------------------------------------------
193
}
194
195
//----------------------------------------------------------------------------------------------------------------------
196