ShowContent::execute()   B
last analyzed

Complexity

Conditions 8
Paths 18

Size

Total Lines 40
Code Lines 26

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 8
eloc 26
nc 18
nop 2
dl 0
loc 40
rs 8.4444
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * This file is part of Cecil.
5
 *
6
 * (c) Arnaud Ligny <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
declare(strict_types=1);
13
14
namespace Cecil\Command;
15
16
use Cecil\Command\ShowContent\FileExtensionFilter;
17
use Cecil\Command\ShowContent\FilenameRecursiveTreeIterator;
18
use Cecil\Exception\RuntimeException;
19
use Cecil\Util;
20
use RecursiveDirectoryIterator;
21
use RecursiveTreeIterator;
22
use Symfony\Component\Console\Input\InputArgument;
23
use Symfony\Component\Console\Input\InputInterface;
24
use Symfony\Component\Console\Input\InputOption;
25
use Symfony\Component\Console\Output\OutputInterface;
26
27
/**
28
 * ShowContent command.
29
 *
30
 * This command displays the website's content as a tree structure.
31
 * It can be used to quickly review the content files organized by type (pages, data).
32
 * It supports displaying content from specified directories and can filter files by their extensions.
33
 */
34
class ShowContent extends AbstractCommand
35
{
36
    /**
37
     * {@inheritdoc}
38
     */
39
    protected function configure()
40
    {
41
        $this
42
            ->setName('show:content')
43
            ->setDescription('Shows content as tree')
44
            ->setDefinition([
45
                new InputArgument('path', InputArgument::OPTIONAL, 'Use the given path as working directory'),
46
                new InputOption('config', 'c', InputOption::VALUE_REQUIRED, 'Set the path to an extra configuration file'),
47
            ])
48
            ->setHelp(
49
                <<<'EOF'
50
The <info>%command.name%</> command shows the website\'s content as a tree.
51
52
  <info>%command.full_name%</>
53
  <info>%command.full_name% path/to/the/working/directory</>
54
55
To show the content with an extra configuration file, run:
56
57
  <info>%command.full_name% --config=config.yml</>
58
EOF
59
            );
60
    }
61
62
    /**
63
     * {@inheritdoc}
64
     *
65
     * @throws RuntimeException
66
     */
67
    protected function execute(InputInterface $input, OutputInterface $output)
68
    {
69
        $count = 0;
70
        $contentTypes = ['pages', 'data'];
71
72
        // formating output
73
        $unicodeTreePrefix = function (RecursiveTreeIterator $tree) {
74
            $prefixParts = [
75
                RecursiveTreeIterator::PREFIX_LEFT         => ' ',
76
                RecursiveTreeIterator::PREFIX_MID_HAS_NEXT => '│ ',
77
                RecursiveTreeIterator::PREFIX_END_HAS_NEXT => '├ ',
78
                RecursiveTreeIterator::PREFIX_END_LAST     => '└ ',
79
            ];
80
            foreach ($prefixParts as $part => $string) {
81
                $tree->setPrefixPart($part, $string);
82
            }
83
        };
84
85
        try {
86
            foreach ($contentTypes as $type) {
87
                $dir = (string) $this->getBuilder()->getConfig()->get("$type.dir");
88
                if (is_dir(Util::joinFile($this->getPath(), $dir))) {
89
                    $output->writeln(\sprintf('<info>%s:</info>', $dir));
90
                    $pages = $this->getFilesTree($type);
91
                    if (!Util\Platform::isWindows()) {
92
                        $unicodeTreePrefix($pages);
93
                    }
94
                    foreach ($pages as $page) {
95
                        $output->writeln($page);
96
                        $count++;
97
                    }
98
                }
99
                if ($count < 1) {
100
                    $output->writeln(\sprintf('<comment>Nothing in "%s".</comment>', $dir));
101
                }
102
            }
103
104
            return 0;
105
        } catch (\Exception $e) {
106
            throw new RuntimeException(\sprintf($e->getMessage()));
107
        }
108
    }
109
110
    /**
111
     * Returns a console displayable tree of files.
112
     *
113
     * @throws RuntimeException
114
     */
115
    private function getFilesTree(string $contentType): FilenameRecursiveTreeIterator
116
    {
117
        $dir = (string) $this->getBuilder()->getConfig()->get("$contentType.dir");
118
        $ext = (array) $this->getBuilder()->getConfig()->get("$contentType.ext");
119
        $path = Util::joinFile($this->getPath(), $dir);
120
121
        if (!is_dir($path)) {
122
            throw new RuntimeException(\sprintf('Invalid directory: %s.', $path));
123
        }
124
125
        $dirIterator = new RecursiveDirectoryIterator($path, RecursiveDirectoryIterator::SKIP_DOTS);
126
        $dirIterator = new FileExtensionFilter($dirIterator, $ext);
127
        $files = new FilenameRecursiveTreeIterator(
128
            $dirIterator,
129
            FilenameRecursiveTreeIterator::SELF_FIRST
130
        );
131
132
        return $files;
133
    }
134
}
135