Passed
Branch master (bbfb46)
by Jan
22:41 queued 14:44
created

ConvertMarkdownDocsCommand   A

Complexity

Total Complexity 17

Size/Duplication

Total Lines 145
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 85
dl 0
loc 145
rs 10
c 0
b 0
f 0
wmc 17
1
<?php declare(strict_types=1);
2
3
namespace Shopware\Docs\Command;
4
5
use Shopware\Docs\Convert\Document;
6
use Shopware\Docs\Convert\DocumentTree;
7
use Shopware\Docs\Convert\WikiApiService;
8
use Symfony\Component\Console\Command\Command;
9
use Symfony\Component\Console\Input\InputInterface;
10
use Symfony\Component\Console\Input\InputOption;
11
use Symfony\Component\Console\Output\OutputInterface;
12
use Symfony\Component\Filesystem\Filesystem;
13
use Symfony\Component\Finder\Finder;
14
use Symfony\Component\Finder\SplFileInfo;
15
16
class ConvertMarkdownDocsCommand extends Command
17
{
18
    private const CATEGORY_SITE_FILENAME = '__categoryInfo.md';
19
20
    private const BLACKLIST = 'article.blacklist';
21
22
    private const CREDENTIAL_PATH = __DIR__ . '/wiki.secret';
23
24
    protected function configure(): void
25
    {
26
        $this->setName('docs:convert')
27
            ->addOption('input', 'i', InputOption::VALUE_REQUIRED, 'The path to parse for markdown files.', './platform/src/Docs/Resources/current/')
28
            ->addOption('output', 'o', InputOption::VALUE_REQUIRED, 'The path in which the resulting hmtl files will be saved.')
29
            ->addOption('baseurl', 'u', InputOption::VALUE_REQUIRED, '', '/shopware-platform')
30
            ->addOption('sync', 's', InputOption::VALUE_NONE)
31
            ->setDescription('Converts Markdown to Wikihtml');
32
    }
33
34
    protected function execute(InputInterface $input, OutputInterface $output)
35
    {
36
        $inPath = $input->getOption('input');
37
        $outPath = $input->getOption('output');
38
        $baseUrl = $input->getOption('baseurl');
39
        $isSync = $input->getOption('sync');
40
41
        $blacklist = [];
42
        $blacklistFile = $inPath . self::BLACKLIST;
43
        if (is_file($blacklistFile)) {
44
            $blacklist = file($blacklistFile);
45
        }
46
47
        $output->writeln('Scanning \"' . $inPath . '" for .md files ...');
48
        $tree = $this->loadDocuments($inPath, $baseUrl, $blacklist);
49
        $output->writeln('Read ' . count($tree->getAll()) . ' markdown files');
50
51
        if ($outPath === null) {
52
            throw new \RuntimeException('No output path specified');
53
        }
54
55
        $fs = new Filesystem();
56
57
        /** @var Document $document */
58
        foreach (array_merge($tree->getAll(), [$tree->getRoot()]) as $document) {
59
            $path = $outPath . '/' . $document->getFile()->getRelativePath();
60
61
            $htmlFile = $path . '/' . $document->getFile()->getBasename('.md') . '.html';
62
            $phpFile = $path . '/' . $document->getFile()->getBasename('.md') . '.php';
63
64
            $fs->mkdir($outPath);
65
            $fs->dumpFile($htmlFile, $document->getHtml()->render($tree)->getContents());
66
            $fs->dumpFile($phpFile, '<?php return ' . var_export($document->getMetadata()->toArray($tree), true) . ';');
67
        }
68
69
        if (!$isSync || !file_exists(self::CREDENTIAL_PATH)) {
70
            return;
71
        }
72
73
        $credentialsContents = (file_get_contents(self::CREDENTIAL_PATH));
74
        $credentials = json_decode($credentialsContents, true);
75
        $token = $credentials['token'];
76
        $server = $credentials['url'];
77
        $rootCategory = $credentials['rootCategoryId'];
78
79
        $syncService = new WikiApiService($token, $server, $rootCategory);
80
        $syncService->syncFilesWithServer($tree);
81
    }
82
83
    protected function readAllFiles(array $files): array
84
    {
85
        $allContents = [];
86
        foreach ($files as $file) {
87
            $content = file_get_contents($file);
88
            if ($content === '') {
89
                continue;
90
            }
91
            $allContents[$file] = $content;
92
        }
93
94
        return $allContents;
95
    }
96
97
    private function loadDocuments(string $fromPath, string $baseUrl, array $blacklist): DocumentTree
98
    {
99
        $files = (new Finder())
100
            ->files()
101
            ->in($fromPath)
102
            ->sortByName()
103
            ->depth('>=1')
104
            ->name('*.md');
105
106
        $documents = [];
107
108
        /** @var SplFileInfo $file */
109
        foreach ($files as $file) {
110
            foreach ($blacklist as $blacklistedFile) {
111
                $blacklistedFile = trim($blacklistedFile);
112
                if (strpos($file->getRelativePathname(), $blacklistedFile) === 0) {
113
                    echo 'Blacklisted ' . $file->getRelativePathname() . "\n";
114
                    continue 2;
115
                }
116
            }
117
118
            $documents[$file->getRelativePathname()] = new Document(
119
                $file,
120
                $file->getFilename() === self::CATEGORY_SITE_FILENAME,
121
                $baseUrl
122
            );
123
        }
124
125
        //compile into tree
126
        $tree = new DocumentTree();
127
        /** @var Document $document */
128
        foreach ($documents as $path => $document) {
129
            if ($document->isCategory()) {
130
                $parentPath = dirname($document->getFile()->getRelativePath()) . '/' . self::CATEGORY_SITE_FILENAME;
131
            } else {
132
                $parentPath = $document->getFile()->getRelativePath() . '/' . self::CATEGORY_SITE_FILENAME;
133
            }
134
135
            $tree->add($document);
136
137
            //find parent
138
            if (!isset($documents[$parentPath])) {
139
                // found a root, but not necessarily THE root so we skip here
140
                continue;
141
            }
142
143
            /** @var Document $parent */
144
            $parent = $documents[$parentPath];
145
            $document->setParent($parent);
146
            $parent->addChild($document);
147
        }
148
149
        $root = new Document(
150
            new SplFileInfo(
151
                $fromPath . '/__categoryInfo.md',
152
                '',
153
                '__categoryInfo.md'
154
            ),
155
            true,
156
            $baseUrl
157
        );
158
        $tree->setRoot($root);
159
160
        return $tree;
161
    }
162
}
163