Completed
Push — master ( 489545...8e653b )
by Basil
04:40
created

ImportController::logValueToTable()   B

Complexity

Conditions 5
Paths 3

Size

Total Lines 22
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 22
rs 8.6737
c 0
b 0
f 0
cc 5
eloc 15
nc 3
nop 1
1
<?php
2
3
namespace luya\console\commands;
4
5
use Yii;
6
7
use luya\admin\models\Config;
8
use luya\console\Command;
9
use luya\console\interfaces\ImportControllerInterface;
10
use luya\Boot;
11
use yii\console\widgets\Table;
12
use yii\helpers\VarDumper;
13
14
/**
15
 * Import controller runs the module defined importer classes.
16
 *
17
 * The importer classes are defined inthe modules `import()` methods which inherits this class.
18
 *
19
 * ```sh
20
 * ./vendor/bin/luya import
21
 * ```
22
 *
23
 * Each of the importer classes must extend the {{\luya\console\Importer}} class.
24
 *
25
 * @author Basil Suter <[email protected]>
26
 * @since 1.0.0
27
 */
28
class ImportController extends Command implements ImportControllerInterface
29
{
30
    private $_dirs = [];
31
32
    private $_log = [];
33
34
    private $_scanFolders = ['blocks', 'filters', 'properties', 'blockgroups'];
35
36
    /**
37
     * @inheritdoc
38
     */
39
    public function init()
40
    {
41
        parent::init();
42
        
43
        // foreach scanFolders of all modules
44
        foreach (Yii::$app->getApplicationModules() as $id => $module) {
45
            foreach ($this->_scanFolders as $folderName) {
46
                $this->addToDirectory($module->getBasePath().DIRECTORY_SEPARATOR.$folderName, $folderName, '\\'.$module->getNamespace().'\\'.$folderName, $module->id);
47
            }
48
        }
49
        // foreach scanFolder inside the app namespace
50
        foreach ($this->_scanFolders as $folderName) {
51
            $this->addToDirectory(Yii::getAlias("@app/$folderName"), $folderName, '\\app\\'.$folderName, '@app');
52
        }
53
    }
54
55
    private function scanDirectoryFiles($path, $ns, $module)
56
    {
57
        $files = [];
58
        foreach (scandir($path) as $file) {
59
            if (substr($file, 0, 1) !== '.') {
60
                $files[] = [
61
                    'file' => $file,
62
                    'module' => $module,
63
                    'ns' => $ns.'\\'.pathinfo($file, PATHINFO_FILENAME),
64
                ];
65
            }
66
        }
67
68
        return $files;
69
    }
70
71
    private function addToDirectory($path, $folderName, $ns, $module)
72
    {
73
        if (file_exists($path)) {
74
            $this->_dirs[$folderName][] = [
75
                'ns' => $ns,
76
                'module' => $module,
77
                'folderPath' => $path.DIRECTORY_SEPARATOR,
78
                'files' => $this->scanDirectoryFiles($path, $ns, $module),
79
            ];
80
        }
81
    }
82
    
83
    /**
84
     * @inheritdoc
85
     */
86
    public function getDirectoryFiles($folderName)
87
    {
88
        $files = [];
89
        if (array_key_exists($folderName, $this->_dirs)) {
90
            foreach ($this->_dirs[$folderName] as $folder) {
91
                foreach ($folder['files'] as $file) {
92
                    $files[] = $file;
93
                }
94
            }
95
        }
96
        
97
        return $files;
98
    }
99
100
    /**
101
     * @inheritdoc
102
     */
103
    public function addLog($section, $value)
104
    {
105
        $this->_log[$section][] = $value;
106
}
107
    
108
    /**
109
     * Get all log data.
110
     *
111
     * @return array
112
     */
113
    public function getLog()
114
    {
115
        return $this->_log;
116
    }
117
118
    /**
119
     * Get all importer objects with the assigned queue position.
120
     *
121
     * @return array If no importer objects are provided the array will is returned empty.
122
     */
123
    public function buildImporterQueue()
124
    {
125
        $queue = [];
126
        foreach (Yii::$app->getApplicationModules() as $id => $module) {
127
            $response = $module->import($this);
128
            // if there response is an array, the it will be added to the queue
129
            if (is_array($response)) {
130
                foreach ($response as $class) {
131
                    $object = new $class($this, $module);
132
                    $position = $object->queueListPosition;
133
                    while (true) {
134
                        if (!array_key_exists($position, $queue)) {
135
                            break;
136
                        }
137
                        ++$position;
138
                    }
139
                    $queue[$position] = $object;
140
                }
141
            }
142
        }
143
        
144
        ksort($queue);
145
        return $queue;
146
    }
147
    
148
    /**
149
     * Run the import process.
150
     *
151
     * @return number
152
     */
153
    public function actionIndex()
154
    {
155
        $queue = $this->buildImporterQueue();
156
157
        foreach ($queue as $pos => $object) {
158
            $this->verbosePrint("Run importer object '{$object->className()}' on position '{$pos}'.", __METHOD__);
159
            $this->verbosePrint('Module context id: ' . $object->module->id);
160
            $object->run();
161
        }
162
163
        if (Yii::$app->hasModule('admin')) {
164
            Config::set(Config::CONFIG_LAST_IMPORT_TIMESTAMP, time());
165
            Config::set(Config::CONFIG_INSTALLER_VENDOR_TIMESTAMP, Yii::$app->packageInstaller->timestamp);
166
            Yii::$app->db->createCommand()->update('admin_user', ['force_reload' => 1])->execute();
167
        }
168
        
169
        $this->output('LUYA import command (based on LUYA ' . Boot::VERSION . ')');
170
        
171
        foreach ($this->getLog() as $section => $value) {
172
            $this->outputInfo(PHP_EOL . $section . ":");
173
            $this->logValueToTable($value); 
174
        }
175
        
176
        return $this->outputSuccess("Importer run successful.");
177
    }
178
    
179
    private function logValueToTable(array $logs)
180
    {
181
        $table = new Table();
182
        $table->setHeaders(['Key', 'Value']);
183
        $rows = [];
184
     
185
        foreach ($logs as $key => $value) {
186
            if (is_array($value)) {
187
                foreach ($value as $kk => $kv) {
188
                    if (!is_scalar($kv)) {;
189
                        $rows[] = [$kk, VarDumper::dumpAsString($kv)];
190
                    } else {
191
                        $rows[] = [$kk, $kv];
192
                    }
193
                }
194
            } else {
195
                $rows[] = [$key, $value];
196
            }
197
        }
198
        $table->setRows($rows);
199
        echo $table->run();
200
    }
201
}
202