Passed
Push — fix/serve-timeout ( 697f77...233bc8 )
by Arnaud
04:27
created

NewPage::hasEditor()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

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