Passed
Push — fix_new_page ( 5b5079 )
by Arnaud
08:56 queued 05:01
created

NewPage   A

Complexity

Total Complexity 16

Size/Duplication

Total Lines 134
Duplicated Lines 0 %

Test Coverage

Coverage 0%

Importance

Changes 4
Bugs 2 Features 0
Metric Value
eloc 83
c 4
b 2
f 0
dl 0
loc 134
ccs 0
cts 65
cp 0
rs 10
wmc 16

3 Methods

Rating   Name   Duplication   Size   Complexity  
A configure() 0 16 1
C execute() 0 78 12
A findModel() 0 23 3
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * This file is part of Cecil.
7
 *
8
 * Copyright (c) Arnaud Ligny <[email protected]>
9
 *
10
 * For the full copyright and license information, please view the LICENSE
11
 * file that was distributed with this source code.
12
 */
13
14
namespace Cecil\Command;
15
16
use Cecil\Exception\RuntimeException;
17
use Cecil\Util;
18
use Symfony\Component\Console\Input\InputArgument;
19
use Symfony\Component\Console\Input\InputDefinition;
20
use Symfony\Component\Console\Input\InputInterface;
21
use Symfony\Component\Console\Input\InputOption;
22
use Symfony\Component\Console\Output\OutputInterface;
23
use Symfony\Component\Console\Question\ConfirmationQuestion;
24
25
/**
26
 * Creates a new page.
27
 */
28
class NewPage extends AbstractCommand
29
{
30
    /**
31
     * {@inheritdoc}
32
     */
33
    protected function configure()
34
    {
35
        $this
36
            ->setName('new:page')
37
            ->setDescription('Creates a new page')
38
            ->setDefinition(
39
                new InputDefinition([
40
                    new InputArgument('name', InputArgument::REQUIRED, 'New page name'),
41
                    new InputArgument('path', InputArgument::OPTIONAL, 'Use the given path as working directory'),
42
                    new InputOption('prefix', 'p', InputOption::VALUE_NONE, 'Prefix the file name with the current date (`YYYY-MM-DD`)'),
43
                    new InputOption('force', 'f', InputOption::VALUE_NONE, 'Override the file if already exist'),
44
                    new InputOption('open', 'o', InputOption::VALUE_NONE, 'Open editor automatically'),
45
                    new InputOption('editor', null, InputOption::VALUE_REQUIRED, 'Editor to use with open option'),
46
                ])
47
            )
48
            ->setHelp('Creates a new page file (with filename as title)');
49
    }
50
51
    /**
52
     * {@inheritdoc}
53
     *
54
     * @throws RuntimeException
55
     */
56
    protected function execute(InputInterface $input, OutputInterface $output)
57
    {
58
        $name = (string) $input->getArgument('name');
59
        $force = $input->getOption('force');
60
        $open = $input->getOption('open');
61
        $prefix = $input->getOption('prefix');
62
63
        try {
64
            $nameParts = pathinfo($name);
65
            $dirname = trim($nameParts['dirname'], '.');
66
            $basename = $nameParts['basename'];
67
            $extension = $nameParts['extension'];
68
            $title = substr($basename, 0, -strlen(".$extension"));
69
            $filename = $basename;
70
            if (!in_array($extension, $this->builder->getConfig()->get('pages.ext'))) {
0 ignored issues
show
Bug introduced by
It seems like $this->builder->getConfig()->get('pages.ext') can also be of type null; however, parameter $haystack of in_array() does only seem to accept array, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

70
            if (!in_array($extension, /** @scrutinizer ignore-type */ $this->builder->getConfig()->get('pages.ext'))) {
Loading history...
71
                $title = $filename;
72
                $filename = "$basename.md"; // force a valid extension
73
            }
74
            $title = ucfirst(str_replace('-', ' ', $title));
75
            $date = date('Y-m-d');
76
            // has date prefix?
77
            $datePrefix = '';
78
            if ($prefix) {
79
                $datePrefix = \sprintf('%s-', $date);
80
            }
81
            // path
82
            $fileRelativePath = \sprintf(
83
                '%s%s%s%s%s',
84
                (string) $this->getBuilder()->getConfig()->get('pages.dir'),
85
                DIRECTORY_SEPARATOR,
86
                empty($dirname) ? '' : $dirname.DIRECTORY_SEPARATOR,
87
                $datePrefix,
88
                $filename
89
            );
90
            $filePath = Util::joinFile($this->getPath(), $fileRelativePath);
91
92
            // file already exists?
93
            if ($this->fs->exists($filePath) && !$force) {
94
                $output->writeln(\sprintf(
95
                    '<comment>The file "%s" already exists.</comment>',
96
                    $fileRelativePath
97
                ));
98
                // ask to override file
99
                $helper = $this->getHelper('question');
100
                $question = new ConfirmationQuestion('Do you want to override it? [y/n]', false);
101
                if (!$helper->ask($input, $output, $question)) {
102
                    return 0;
103
                }
104
            }
105
106
            // creates a new file
107
            $model = $this->findModel(\sprintf('%s%s', empty($dirname) ? '' : $dirname.DIRECTORY_SEPARATOR, $filename));
108
            $fileContent = str_replace(
109
                ['%title%', '%date%'],
110
                [$title, $date],
111
                $model['content']
112
            );
113
            $this->fs->dumpFile($filePath, $fileContent);
114
            $output->writeln(\sprintf('<info>File "%s" created (with model "%s").</info>', $fileRelativePath, $model['name']));
115
116
            // open editor?
117
            if ($open) {
118
                if (null === $editor = $input->getOption('editor')) {
119
                    if (!$this->getBuilder()->getConfig()->has('editor')) {
120
                        $output->writeln('<comment>No editor configured.</comment>');
121
122
                        return 0;
123
                    }
124
                    $editor = (string) $this->getBuilder()->getConfig()->get('editor');
125
                }
126
                $output->writeln(\sprintf('<info>Opening file with %s...</info>', ucfirst($editor)));
127
                $this->openEditor($filePath, $editor);
128
            }
129
        } catch (\Exception $e) {
130
            throw new RuntimeException(\sprintf($e->getMessage()));
131
        }
132
133
        return 0;
134
    }
135
136
    /**
137
     * Finds the page model and returns its [name, content].
138
     */
139
    private function findModel(string $name): array
140
    {
141
        $name = strstr($name, DIRECTORY_SEPARATOR, true) ?: 'default';
142
        if (file_exists($model = Util::joinFile($this->getPath(), 'models', "$name.md"))) {
143
            return [
144
                'name'    => $name,
145
                'content' => Util\File::fileGetContents($model),
146
            ];
147
        }
148
149
        $content = <<<'EOT'
150
---
151
title: "%title%"
152
date: %date%
153
published: true
154
---
155
_Your content here_
156
157
EOT;
158
159
        return [
160
            'name'    => 'cecil',
161
            'content' => $content,
162
        ];
163
    }
164
}
165