Passed
Push — main ( 625462...aa68b0 )
by Dimitri
03:08
created

ContentReplacer::sourcePath()   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 1
dl 0
loc 3
rs 10
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
28
    /**
29
     * Recupere le chemin source complet d'un fichier
30
     */
31
    protected function sourcePath(string $file): string
32
    {
33
        return str_replace('/', DS, rtrim($this->sourcePath, '/\\') . DS . $file);
34
    }
35
36
    /**
37
     * Recupere le chemin de destination complet d'un fichier
38
     */
39
    protected function distPath(string $file): string
40
    {
41
        return str_replace('/', DS, rtrim($this->distPath, '/\\') . DS . $file);
42
    }
43
44
    /**
45
     * @param string $file     Chemin de fichier relatif comme 'config/auth.php'.
46
     * @param array  $replaces [search => replace]
47
     */
48
    protected function copyAndReplace(string $file, array $replaces): void
49
    {
50
        $content = file_get_contents($this->sourcePath($file));
51
        
52
        $content = strtr($content, $replaces);
53
54
        $this->writeFile($file, $content);
55
    }
56
    
57
    /**
58
     * Écrivez un fichier, attrapez toutes les exceptions et affichez une erreur bien formatée.
59
     *
60
     * @param string $file Chemin de fichier relatif comme 'config/auth.php'.
61
     */
62
    protected function writeFile(string $file, string $content): void
63
    {
64
        helper('filesystem');
65
66
        $path      = $this->distPath($file);
67
        $cleanPath = clean_path($path);
68
69
        $directory = dirname($path);
70
71
        if (! is_dir($directory)) {
72
            mkdir($directory, 0777, true);
73
        }
74
75
        if (file_exists($path)) {
76
            $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

76
            $overwrite = (bool) $this->/** @scrutinizer ignore-call */ option('f');
Loading history...
77
78
            if (! $overwrite && ! $this->confirm("File '{$cleanPath}' already exists in destination. Overwrite?")) {
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

78
            if (! $overwrite && ! $this->/** @scrutinizer ignore-call */ confirm("File '{$cleanPath}' already exists in destination. Overwrite?")) {
Loading history...
79
                $this->error("Skipped {$cleanPath}. If you wish to overwrite, please use the '-f' option or reply 'y' to the prompt.");
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

79
                $this->/** @scrutinizer ignore-call */ 
80
                       error("Skipped {$cleanPath}. If you wish to overwrite, please use the '-f' option or reply 'y' to the prompt.");
Loading history...
80
81
                return;
82
            }
83
        }
84
85
        if (write_file($path, $content)) {
86
            $this->success($cleanPath, true, 'Created:');
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

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