Passed
Push — main ( 2e52e3...625462 )
by Dimitri
03:32
created

ContentReplacer::replace()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 23
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 3
eloc 12
c 1
b 0
f 0
nc 3
nop 2
dl 0
loc 23
rs 9.8666
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 = '';
20
21
    /**
22
     * Chemin cible pour le replacement
23
     */
24
    protected string $distPath = APP_PATH;
25
    
26
    /**
27
     * @param string $file     Chemin de fichier relatif comme 'config/auth.php'.
28
     * @param array  $replaces [search => replace]
29
     */
30
    protected function copyAndReplace(string $file, array $replaces): void
31
    {
32
        $path = rtrim($this->sourcePath, '/\\') . DS . $file;
33
34
        $content = file_get_contents($path);
35
36
        $content = $this->replace($content, $replaces);
37
38
        $this->writeFile($file, $content);
0 ignored issues
show
Bug introduced by
$content of type boolean is incompatible with the type string expected by parameter $content of BlitzPHP\Cli\Traits\ContentReplacer::writeFile(). ( Ignorable by Annotation )

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

38
        $this->writeFile($file, /** @scrutinizer ignore-type */ $content);
Loading history...
39
    }
40
    
41
    /**
42
     * Écrivez un fichier, attrapez toutes les exceptions et affichez une erreur bien formatée.
43
     *
44
     * @param string $file Chemin de fichier relatif comme 'config/auth.php'.
45
     */
46
    protected function writeFile(string $file, string $content): void
47
    {
48
        helper('filesystem');
49
50
        $path      = rtrim($this->distPath, '/\\') . DS . $file;
51
        $cleanPath = clean_path($path);
52
53
        $directory = dirname($path);
54
55
        if (! is_dir($directory)) {
56
            mkdir($directory, 0777, true);
57
        }
58
59
        if (file_exists($path)) {
60
            $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

60
            $overwrite = (bool) $this->/** @scrutinizer ignore-call */ option('f');
Loading history...
61
62
            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

62
            if (! $overwrite && ! $this->/** @scrutinizer ignore-call */ confirm("File '{$cleanPath}' already exists in destination. Overwrite?")) {
Loading history...
63
                $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

63
                $this->/** @scrutinizer ignore-call */ 
64
                       error("Skipped {$cleanPath}. If you wish to overwrite, please use the '-f' option or reply 'y' to the prompt.");
Loading history...
64
65
                return;
66
            }
67
        }
68
69
        if (write_file($path, $content)) {
70
            $this->writer->boldWhiteBgGreen(' Created: ');
71
            $this->write(' ' . $cleanPath, true);
0 ignored issues
show
Bug introduced by
The method write() does not exist on BlitzPHP\Cli\Traits\ContentReplacer. Did you maybe mean writeFile()? ( Ignorable by Annotation )

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

71
            $this->/** @scrutinizer ignore-call */ 
72
                   write(' ' . $cleanPath, true);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

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