Passed
Push — cli ( d3573e...6f6b3b )
by Arnaud
03:47
created

NewPage::execute()   F

Complexity

Conditions 15
Paths 473

Size

Total Lines 83
Code Lines 56

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 15
eloc 56
nc 473
nop 2
dl 0
loc 83
rs 2.4819
c 1
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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
24
/**
25
 * Creates a new page.
26
 */
27
class NewPage extends AbstractCommand
28
{
29
    /**
30
     * {@inheritdoc}
31
     */
32
    protected function configure()
33
    {
34
        $this
35
            ->setName('new:page')
36
            ->setDescription('Creates a new page')
37
            ->setDefinition(
38
                new InputDefinition([
39
                    new InputArgument('path', InputArgument::OPTIONAL, 'Use the given path as working directory'),
40
                    new InputOption('name', null, InputOption::VALUE_REQUIRED, 'Page path name'),
41
                    new InputOption('prefix', 'p', InputOption::VALUE_NONE, 'Prefix the file name with the current date (`YYYY-MM-DD`)'),
42
                    new InputOption('force', 'f', InputOption::VALUE_NONE, 'Override the file if already exist'),
43
                    new InputOption('open', 'o', InputOption::VALUE_NONE, 'Open editor automatically'),
44
                    new InputOption('editor', null, InputOption::VALUE_REQUIRED, 'Editor to use with open option'),
45
                ])
46
            )
47
            ->setHelp('Creates a new page file (with filename as title)');
48
    }
49
50
    /**
51
     * {@inheritdoc}
52
     *
53
     * @throws RuntimeException
54
     */
55
    protected function execute(InputInterface $input, OutputInterface $output)
56
    {
57
        $name = (string) $input->getOption('name');
58
        $prefix = $input->getOption('prefix');
59
        $force = $input->getOption('force');
60
        $open = $input->getOption('open');
61
        $editor = $input->getOption('editor');
62
63
        try {
64
            // ask
65
            if (empty($name)) {
66
                $name = $this->io->ask('What is the name of the page file?', 'new-page.md');
67
                $prefix = $this->io->confirm('Add date prefix to the filename?', false);
68
                $open = $this->io->confirm('Do you want open the created file with your editor?', false);
69
                if ($open && !$this->getBuilder()->getConfig()->has('editor')) {
70
                    $editor = $this->io->ask('Which editor?');
71
                }
72
            }
73
            // parse given path name
74
            $nameParts = pathinfo($name);
75
            $dirname = trim($nameParts['dirname'], '.');
76
            $basename = $nameParts['basename'];
77
            $extension = $nameParts['extension'];
78
            $title = substr($basename, 0, -\strlen(".$extension"));
79
            $filename = $basename;
80
            if (!\in_array($extension, (array) $this->getBuilder()->getConfig()->get('pages.ext'))) {
81
                $title = $filename;
82
                $filename = "$basename.md"; // force a valid extension
83
            }
84
            $title = ucfirst(str_replace('-', ' ', $title));
85
            $date = date('Y-m-d');
86
            // date prefix?
87
            $datePrefix = '';
88
            if ($prefix) {
89
                $datePrefix = sprintf('%s-', $date);
90
            }
91
            // path
92
            $fileRelativePath = sprintf(
93
                '%s%s%s%s%s',
94
                (string) $this->getBuilder()->getConfig()->get('pages.dir'),
95
                DIRECTORY_SEPARATOR,
96
                empty($dirname) ? '' : $dirname . DIRECTORY_SEPARATOR,
97
                $datePrefix,
98
                $filename
99
            );
100
            $filePath = Util::joinFile($this->getPath(), $fileRelativePath);
101
102
            // ask to override existing file?
103
            if (Util\File::getFS()->exists($filePath) && !$force) {
104
                $output->writeln(sprintf('<comment>The file "%s" already exists.</comment>', $fileRelativePath));
105
                if (!$this->io->confirm('Do you want to override it?', false)) {
106
                    return 0;
107
                }
108
            }
109
110
            // creates a new file
111
            $model = $this->findModel(sprintf('%s%s', empty($dirname) ? '' : $dirname . DIRECTORY_SEPARATOR, $filename));
112
            $fileContent = str_replace(
113
                ['%title%', '%date%'],
114
                [$title, $date],
115
                $model['content']
116
            );
117
            Util\File::getFS()->dumpFile($filePath, $fileContent);
118
            $output->writeln(sprintf('<info>File "%s" created (with model "%s").</info>', $fileRelativePath, $model['name']));
119
120
            // open editor?
121
            if ($open) {
122
                if ($editor === null) {
123
                    if (!$this->getBuilder()->getConfig()->has('editor')) {
124
                        $output->writeln('<comment>No editor configured.</comment>');
125
126
                        return 0;
127
                    }
128
                    $editor = (string) $this->getBuilder()->getConfig()->get('editor');
129
                }
130
                $output->writeln(sprintf('<info>Opening file with %s...</info>', ucfirst($editor)));
131
                $this->openEditor($filePath, $editor);
132
            }
133
        } catch (\Exception $e) {
134
            throw new RuntimeException(sprintf($e->getMessage()));
135
        }
136
137
        return 0;
138
    }
139
140
    /**
141
     * Finds the page model and returns its [name, content].
142
     */
143
    private function findModel(string $name): array
144
    {
145
        $name = strstr($name, DIRECTORY_SEPARATOR, true) ?: 'default';
146
        if (file_exists($model = Util::joinFile($this->getPath(), 'models', "$name.md"))) {
147
            return [
148
                'name'    => $name,
149
                'content' => Util\File::fileGetContents($model),
150
            ];
151
        }
152
153
        $content = <<<'EOT'
154
---
155
title: "%title%"
156
date: %date%
157
published: true
158
---
159
_Your content here_
160
161
EOT;
162
163
        return [
164
            'name'    => 'cecil',
165
            'content' => $content,
166
        ];
167
    }
168
}
169