ContentReplacer   A
last analyzed

Complexity

Total Complexity 19

Size/Duplication

Total Lines 163
Duplicated Lines 0 %

Test Coverage

Coverage 0%

Importance

Changes 3
Bugs 1 Features 0
Metric Value
eloc 56
c 3
b 1
f 0
dl 0
loc 163
ccs 0
cts 40
cp 0
rs 10
wmc 19

7 Methods

Rating   Name   Duplication   Size   Complexity  
A _addContent() 0 17 3
A copyAndReplace() 0 7 1
A addContent() 0 26 4
A distPath() 0 3 1
A writeFile() 0 27 6
A replace() 0 24 3
A sourcePath() 0 3 1
1
<?php
2
3
/**
4
 * This file is part of Blitz PHP framework.
5
 *
6
 * (c) 2022 Dimitri Sitchet Tomkeu <[email protected]>
7
 *
8
 * For the full copyright and license information, please view
9
 * the LICENSE file that was distributed with this source code.
10
 */
11
12
namespace BlitzPHP\Cli\Traits;
13
14
trait ContentReplacer
15
{
16
    /**
17
     * Chemin source
18
     */
19
    protected string $sourcePath = __DIR__ . '/../';
20
21
    /**
22
     * Chemin cible pour le replacement
23
     */
24
    protected string $distPath = APP_PATH;
25
26
    /**
27
     * Recupere le chemin source complet d'un fichier
28
     */
29
    protected function sourcePath(string $file): string
30
    {
31
        return str_replace('/', DS, rtrim($this->sourcePath, '/\\') . DS . $file);
32
    }
33
34
    /**
35
     * Recupere le chemin de destination complet d'un fichier
36
     */
37
    protected function distPath(string $file): string
38
    {
39
        return str_replace('/', DS, rtrim($this->distPath, '/\\') . DS . $file);
40
    }
41
42
    /**
43
     * @param string $file     Chemin de fichier relatif comme 'config/auth.php'.
44
     * @param array  $replaces [search => replace]
45
     */
46
    protected function copyAndReplace(string $file, array $replaces): void
47
    {
48
        $content = file_get_contents($this->sourcePath($file));
49
50
        $content = strtr($content, $replaces);
51
52
        $this->writeFile($file, $content);
53
    }
54
55
    /**
56
     * Écrivez un fichier, attrapez toutes les exceptions et affichez une erreur bien formatée.
57
     *
58
     * @param string $file Chemin de fichier relatif comme 'config/auth.php'.
59
     */
60
    protected function writeFile(string $file, string $content): void
61
    {
62
        helper('filesystem');
63
64
        $path      = $this->distPath($file);
65
        $cleanPath = clean_path($path);
66
67
        $directory = dirname($path);
68
69
        if (! is_dir($directory)) {
70
            mkdir($directory, 0o777, true);
71
        }
72
73
        if (file_exists($path)) {
74
            $overwrite = (bool) $this->option('f');
0 ignored issues
show
Bug introduced by
It seems like option() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

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

74
            $overwrite = (bool) $this->/** @scrutinizer ignore-call */ option('f');
Loading history...
75
76
            if (! $overwrite && ! $this->confirm("Le fichier '{$cleanPath}' existe déjà dans la destination. Le remplacé?")) {
0 ignored issues
show
Bug introduced by
It seems like confirm() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

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

76
            if (! $overwrite && ! $this->/** @scrutinizer ignore-call */ confirm("Le fichier '{$cleanPath}' existe déjà dans la destination. Le remplacé?")) {
Loading history...
77
                $this->error("{$cleanPath} sauté. Si vous souhaitez le remplacer, s'il vous plaît utiliser l'option '-f' ou répondre 'y' à l'invite.")->eol();
0 ignored issues
show
Bug introduced by
It seems like error() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

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

77
                $this->/** @scrutinizer ignore-call */ 
78
                       error("{$cleanPath} sauté. Si vous souhaitez le remplacer, s'il vous plaît utiliser l'option '-f' ou répondre 'y' à l'invite.")->eol();
Loading history...
78
79
                return;
80
            }
81
        }
82
83
        if (write_file($path, $content)) {
84
            $this->success($cleanPath, true, 'Crée:')->eol();
0 ignored issues
show
Bug introduced by
It seems like success() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

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

84
            $this->/** @scrutinizer ignore-call */ 
85
                   success($cleanPath, true, 'Crée:')->eol();
Loading history...
85
        } else {
86
            $this->error("Erreur de création: {$cleanPath}.")->eol();
87
        }
88
    }
89
90
    /**
91
     * @param string $file     Chemin de fichier relatif comme 'Controllers/BaseController.php'.
92
     * @param array  $replaces [search => replace]
93
     */
94
    protected function replace(string $file, array $replaces): bool
95
    {
96
        helper('filesystem');
97
98
        $path      = $this->distPath($file);
99
        $cleanPath = clean_path($path);
100
101
        $content = file_get_contents($path);
102
103
        $output = strtr($content, $replaces);
104
105
        if ($output === $content) {
106
            return false;
107
        }
108
109
        if (write_file($path, $output)) {
110
            $this->success($cleanPath, true, 'Modifié:')->eol();
111
112
            return true;
113
        }
114
115
        $this->error("Erreur lors de la mise à jour de {$cleanPath}.")->eol();
116
117
        return false;
118
    }
119
120
    /**
121
     * @param string $code Code a ajouter.
122
     * @param string $file hemin de fichier relatif comme 'Controllers/BaseController.php'.
123
     */
124
    protected function addContent(string $file, string $code, string $pattern, string $replace): void
125
    {
126
        helper('filesystem');
127
128
        $path      = $this->distPath($file);
129
        $cleanPath = clean_path($path);
130
131
        $content = file_get_contents($path);
132
133
        $output = $this->_addContent($content, $code, $pattern, $replace);
134
135
        if ($output === true) {
136
            $this->error("{$cleanPath} ignoré. Il a déjà été mis à jour.")->eol();
137
138
            return;
139
        }
140
        if ($output === false) {
141
            $this->error("Erreur lors de la vérification de {$cleanPath}.")->eol();
142
143
            return;
144
        }
145
146
        if (write_file($path, $output)) {
147
            $this->success($cleanPath, true, 'Modifié:')->eol();
148
        } else {
149
            $this->error("Erreur lors de la mise à jour de {$cleanPath}.")->eol();
150
        }
151
    }
152
153
    /**
154
     * @param string $text    Texte à ajouter.
155
     * @param string $pattern Modèle de recherche d'expression régulière.
156
     * @param string $replace Remplacement de Regexp incluant le texte à ajouter.
157
     *
158
     * @return bool|string true : déjà mis à jour, false : erreur d'expression régulière.
159
     */
160
    private function _addContent(string $content, string $text, string $pattern, string $replace)
161
    {
162
        $return = preg_match('/' . preg_quote($text, '/') . '/u', $content);
163
164
        if ($return === 1) {
165
            // Il a déjà été mis à jour.
166
167
            return true;
168
        }
169
170
        if ($return === false) {
171
            // Erreur d'expression régulière.
172
173
            return false;
174
        }
175
176
        return preg_replace($pattern, $replace, $content);
177
    }
178
}
179