Passed
Push — feature/open-with ( a1b551...a1d555 )
by Arnaud
10:49 queued 05:26
created

NewPage::hasEditor()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

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
ccs 0
cts 2
cp 0
crap 2
rs 10
1
<?php
2
/**
3
 * This file is part of the Cecil/Cecil package.
4
 *
5
 * Copyright (c) Arnaud Ligny <[email protected]>
6
 *
7
 * For the full copyright and license information, please view the LICENSE
8
 * file that was distributed with this source code.
9
 */
10
11
namespace Cecil\Command;
12
13
use Cecil\Exception\RuntimeException;
14
use Cecil\Util;
15
use Symfony\Component\Console\Input\InputArgument;
16
use Symfony\Component\Console\Input\InputDefinition;
17
use Symfony\Component\Console\Input\InputInterface;
18
use Symfony\Component\Console\Input\InputOption;
19
use Symfony\Component\Console\Output\OutputInterface;
20
use Symfony\Component\Console\Question\ConfirmationQuestion;
21
22
/**
23
 * Creates a new page.
24
 */
25
class NewPage extends AbstractCommand
26
{
27
    /**
28
     * {@inheritdoc}
29
     */
30
    protected function configure()
31
    {
32
        $this
33
            ->setName('new:page')
34
            ->setDescription('Creates a new page')
35
            ->setDefinition(
36
                new InputDefinition([
37
                    new InputArgument('name', InputArgument::REQUIRED, 'New page name'),
38
                    new InputArgument('path', InputArgument::OPTIONAL, 'Use the given path as working directory'),
39
                    new InputOption('force', 'f', InputOption::VALUE_NONE, 'Override the file if already exist'),
40
                    new InputOption('open', 'o', InputOption::VALUE_NONE, 'Open editor automatically'),
41
                    new InputOption('prefix', 'p', InputOption::VALUE_NONE, 'Prefix the file name with the current date (`YYYY-MM-DD`)'),
42
                ])
43
            )
44
            ->setHelp('Creates a new page file (with filename as title and the current date)');
45
    }
46
47
    /**
48
     * {@inheritdoc}
49
     *
50
     * @throws RuntimeException
51
     */
52
    protected function execute(InputInterface $input, OutputInterface $output)
53
    {
54
        $name = (string) $input->getArgument('name');
55
        $force = $input->getOption('force');
56
        $open = $input->getOption('open');
57
        $prefix = $input->getOption('prefix');
58
59
        try {
60
            $nameParts = pathinfo($name);
61
            $dirname = trim($nameParts['dirname'], '.');
62
            $filename = $nameParts['filename'];
63
            $date = date('Y-m-d');
64
            $title = ucfirst($filename);
65
            // has date prefix?
66
            $datePrefix = '';
67
            if ($prefix) {
68
                $datePrefix = sprintf('%s-', $date);
69
            }
70
            // path
71
            $fileRelativePath = sprintf(
72
                '%s%s%s%s%s.md',
73
                (string) $this->getBuilder()->getConfig()->get('content.dir'),
74
                DIRECTORY_SEPARATOR,
75
                empty($dirname) ? '' : $dirname.DIRECTORY_SEPARATOR,
76
                $datePrefix,
77
                $filename
78
            );
79
            $filePath = Util::joinFile($this->getPath(), $fileRelativePath);
80
81
            // file already exists?
82
            if ($this->fs->exists($filePath) && !$force) {
83
                $output->writeln(\sprintf(
84
                    '<comment>The file "%s" already exists.</comment>',
85
                    $fileRelativePath
86
                ));
87
                // ask to override file
88
                $helper = $this->getHelper('question');
89
                $question = new ConfirmationQuestion('Do you want to override it? [y/n]', false);
90
                if (!$helper->ask($input, $output, $question)) {
91
                    return 0;
92
                }
93
            }
94
95
            // creates a new file
96
            $model = $this->findModel(\sprintf('%s%s', empty($dirname) ? '' : $dirname.DIRECTORY_SEPARATOR, $filename));
97
            $fileContent = str_replace(
98
                ['%title%', '%date%'],
99
                [$title, $date],
100
                $model['content']
101
            );
102
            $this->fs->dumpFile($filePath, $fileContent);
103
            $output->writeln(\sprintf('<info>File "%s" created (with model "%s").</info>', $fileRelativePath, $model['name']));
104
105
            // open editor?
106
            if ($open) {
107
                if (!$this->hasEditor()) {
108
                    $output->writeln('<comment>No editor configured.</comment>');
109
110
                    return 0;
111
                }
112
                $output->writeln(\sprintf('<info>Opening file with %s...</info>', (string) $this->getBuilder()->getConfig()->get('editor')));
113
                $this->openEditor($filePath);
114
            }
115
        } catch (\Exception $e) {
116
            throw new RuntimeException(\sprintf($e->getMessage()));
117
        }
118
119
        return 0;
120
    }
121
122
    /**
123
     * Finds the page model and returns its [name, content].
124
     */
125
    private function findModel(string $name): array
126
    {
127
        $name = strstr($name, DIRECTORY_SEPARATOR, true) ?: 'default';
128
        if (file_exists($model = Util::joinFile($this->getPath(), 'models', "$name.md"))) {
129
            return [
130
                'name'    => $name,
131
                'content' => Util\File::fileGetContents($model),
132
            ];
133
        }
134
135
        $content = <<<'EOT'
136
---
137
title: "%title%"
138
date: %date%
139
published: true
140
---
141
_Your content here_
142
143
EOT;
144
145
        return [
146
            'name'    => 'cecil',
147
            'content' => $content,
148
        ];
149
    }
150
}
151