Completed
Push — master ( d010a7...4c0f94 )
by Basil
03:20
created

ImportController::logValueToTable()   A

Complexity

Conditions 4
Paths 3

Size

Total Lines 18
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 18
rs 9.2
c 0
b 0
f 0
cc 4
eloc 12
nc 3
nop 1
1
<?php
2
3
namespace luya\console\commands;
4
5
use Yii;
6
use yii\console\widgets\Table;
7
use luya\Boot;
8
use luya\admin\models\Config;
9
use luya\console\Command;
10
use luya\console\interfaces\ImportControllerInterface;
11
12
/**
13
 * Import controller runs the module defined importer classes.
14
 *
15
 * The importer classes are defined inthe modules `import()` methods which inherits this class.
16
 *
17
 * ```sh
18
 * ./vendor/bin/luya import
19
 * ```
20
 *
21
 * Each of the importer classes must extend the {{\luya\console\Importer}} class.
22
 *
23
 * @author Basil Suter <[email protected]>
24
 * @since 1.0.0
25
 */
26
class ImportController extends Command implements ImportControllerInterface
27
{
28
    /**
29
     * @var array An array with all folder names inside an application/module to scan for files.
30
     */
31
    protected $scanFolders = ['blocks', 'filters', 'properties', 'blockgroups'];
32
33
    /**
34
     * @inheritdoc
35
     */
36
    public function init()
37
    {
38
        parent::init();
39
        
40
        // foreach scanFolders of all modules
41
        foreach (Yii::$app->getApplicationModules() as $id => $module) {
42
            foreach ($this->scanFolders as $folderName) {
43
                $this->addToDirectory($module->getBasePath().DIRECTORY_SEPARATOR.$folderName, $folderName, '\\'.$module->getNamespace().'\\'.$folderName, $module->id);
44
            }
45
        }
46
        // foreach scanFolder inside the app namespace
47
        foreach ($this->scanFolders as $folderName) {
48
            $this->addToDirectory(Yii::getAlias("@app/$folderName"), $folderName, '\\app\\'.$folderName, '@app');
0 ignored issues
show
Bug introduced by
It seems like \Yii::getAlias("@app/{$folderName}") targeting yii\BaseYii::getAlias() can also be of type boolean; however, luya\console\commands\Im...oller::addToDirectory() does only seem to accept string, maybe add an additional type check?

This check looks at variables that are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
49
        }
50
    }
51
52
    private $_dirs = [];
53
    
54
    /**
55
     * Add a given directory to the list of folders.
56
     *
57
     * @param string $path
58
     * @param string $folderName
59
     * @param string $ns
60
     * @param string $module The name/id of the module.
61
     */
62
    protected function addToDirectory($path, $folderName, $ns, $module)
63
    {
64
        if (file_exists($path)) {
65
            $this->_dirs[$folderName][] = [
66
                'ns' => $ns,
67
                'module' => $module,
68
                'folderPath' => $path.DIRECTORY_SEPARATOR,
69
                'files' => $this->scanDirectoryFiles($path, $ns, $module),
70
            ];
71
        }
72
    }
73
    
74
    /**
75
     * Scan a given directory path and return an array with namespace, module and file.
76
     *
77
     * @param string $path
78
     * @param string $ns
79
     * @param string $module The name/id of the module.
80
     * @return array
81
     */
82
    protected function scanDirectoryFiles($path, $ns, $module)
83
    {
84
        $files = [];
85
        foreach (scandir($path) as $file) {
86
            if (substr($file, 0, 1) !== '.') {
87
                $files[] = [
88
                    'file' => $file,
89
                    'module' => $module,
90
                    'ns' => $ns.'\\'.pathinfo($file, PATHINFO_FILENAME),
91
                ];
92
            }
93
        }
94
        
95
        return $files;
96
    }
97
    
98
    /**
99
     * @inheritdoc
100
     */
101
    public function getDirectoryFiles($folderName)
102
    {
103
        $files = [];
104
        if (array_key_exists($folderName, $this->_dirs)) {
105
            foreach ($this->_dirs[$folderName] as $folder) {
106
                foreach ($folder['files'] as $file) {
107
                    $files[] = $file;
108
                }
109
            }
110
        }
111
        
112
        return $files;
113
    }
114
    
115
    private $_log = [];
116
117
    /**
118
     * @inheritdoc
119
     */
120
    public function addLog($section, $value)
121
    {
122
        $this->_log[$section][] = $value;
123
    }
124
    
125
    /**
126
     * Get all log data.
127
     *
128
     * @return array
129
     */
130
    public function getLog()
131
    {
132
        return $this->_log;
133
    }
134
135
    /**
136
     * Get all importer objects with the assigned queue position.
137
     *
138
     * @return array If no importer objects are provided the array will is returned empty.
139
     */
140
    public function buildImporterQueue()
141
    {
142
        $queue = [];
143
        foreach (Yii::$app->getApplicationModules() as $id => $module) {
144
            $response = $module->import($this);
145
            // if there response is an array, the it will be added to the queue
146
            if (is_array($response)) {
147
                foreach ($response as $class) {
148
                    $object = Yii::createObject($class, [$this, $module]);
149
                    $position = $object->queueListPosition;
150
                    while (true) {
151
                        if (!array_key_exists($position, $queue)) {
152
                            break;
153
                        }
154
                        ++$position;
155
                    }
156
                    $queue[$position] = $object;
157
                }
158
            }
159
        }
160
        
161
        ksort($queue);
162
        return $queue;
163
    }
164
    
165
    /**
166
     * Run the import process.
167
     *
168
     * @return number
169
     */
170
    public function actionIndex()
171
    {
172
        $queue = $this->buildImporterQueue();
173
174
        foreach ($queue as $pos => $object) {
175
            $this->verbosePrint("Run importer object '{$object->className()}' on position '{$pos}'.", __METHOD__);
176
            $this->verbosePrint('Module context id: ' . $object->module->id);
177
            $object->run();
178
        }
179
180
        if (Yii::$app->hasModule('admin')) {
181
            Config::set(Config::CONFIG_LAST_IMPORT_TIMESTAMP, time());
182
            Config::set(Config::CONFIG_INSTALLER_VENDOR_TIMESTAMP, Yii::$app->packageInstaller->timestamp);
183
            Yii::$app->db->createCommand()->update('admin_user', ['force_reload' => 1])->execute();
184
        }
185
        
186
        $this->output('LUYA import command (based on LUYA ' . Boot::VERSION . ')');
187
        
188
        foreach ($this->getLog() as $section => $value) {
189
            $this->outputInfo(PHP_EOL . $section . ":");
190
            $this->logValueToTable($value);
191
        }
192
        
193
        return $this->outputSuccess("Importer run successful.");
194
    }
195
    
196
    /**
197
     * Print the log values as a table.
198
     *
199
     * @param array $logs
200
     * @since 1.0.8
201
     */
202
    private function logValueToTable(array $logs)
203
    {
204
        $table = new Table();
205
        $table->setHeaders(['Key', 'Value']);
206
        $rows = [];
207
     
208
        foreach ($logs as $key => $value) {
209
            if (is_array($value)) {
210
                foreach ($value as $kk => $kv) {
211
                    $rows[] = [$kk, $kv];
212
                }
213
            } else {
214
                $rows[] = [$key, $value];
215
            }
216
        }
217
        $table->setRows($rows);
218
        echo $table->run();
219
    }
220
}
221