Write::appendUnlessMatches()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 5
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 2
1
<?php
2
3
namespace Robo\Task\File;
4
5
use Robo\Result;
6
use Robo\Task\BaseTask;
7
8
/**
9
 * Writes to file.
10
 *
11
 * ``` php
12
 * <?php
13
 * $this->taskWriteToFile('blogpost.md')
14
 *      ->line('-----')
15
 *      ->line(date('Y-m-d').' '.$title)
16
 *      ->line('----')
17
 *      ->run();
18
 * ?>
19
 * ```
20
 */
21
class Write extends BaseTask
22
{
23
    /**
24
     * @var array
25
     */
26
    protected $stack = [];
27
28
    /**
29
     * @var string
30
     */
31
    protected $filename;
32
33
    /**
34
     * @var bool
35
     */
36
    protected $append = false;
37
38
    /**
39
     * @var null|string
40
     */
41
    protected $originalContents = null;
42
43
    /**
44
     * @param string $filename
45
     */
46
    public function __construct($filename)
47
    {
48
        $this->filename = $filename;
49
    }
50
51
    /**
52
     * @param string $filename
53
     *
54
     * @return $this
55
     */
56
    public function filename($filename)
57
    {
58
        $this->filename = $filename;
59
        return $this;
60
    }
61
62
    /**
63
     * @param bool $append
64
     *
65
     * @return $this
66
     */
67
    public function append($append = true)
68
    {
69
        $this->append = $append;
70
        return $this;
71
    }
72
73
    /**
74
     * add a line.
75
     *
76
     * @param string $line
77
     *
78
     * @return $this
79
     *   The current instance.
80
     */
81
    public function line($line)
82
    {
83
        $this->text($line . "\n");
84
        return $this;
85
    }
86
87
    /**
88
     * add more lines.
89
     *
90
     * @param array $lines
91
     *
92
     * @return $this
93
     *   The current instance.
94
     */
95
    public function lines(array $lines)
96
    {
97
        $this->text(implode("\n", $lines) . "\n");
98
        return $this;
99
    }
100
101
    /**
102
     * add a text.
103
     *
104
     * @param string $text
105
     *
106
     * @return $this
107
     *   The current instance.
108
     */
109
    public function text($text)
0 ignored issues
show
Unused Code introduced by
The parameter $text is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
110
    {
111
        $this->stack[] = array_merge([__FUNCTION__ . 'Collect'], func_get_args());
112
        return $this;
113
    }
114
115
    /**
116
     * add a text from a file.
117
     *
118
     * Note that the file is read in the run() method of this task.
119
     * To load text from the current state of a file (e.g. one that may
120
     * be deleted or altered by other tasks prior the execution of this one),
121
     * use:
122
     *       $task->text(file_get_contents($filename));
123
     *
124
     * @param string $filename
125
     *
126
     * @return $this
127
     *   The current instance.
128
     */
129
    public function textFromFile($filename)
0 ignored issues
show
Unused Code introduced by
The parameter $filename is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
130
    {
131
        $this->stack[] = array_merge([__FUNCTION__ . 'Collect'], func_get_args());
132
        return $this;
133
    }
134
135
    /**
136
     * substitute a placeholder with value, placeholder must be enclosed by `{}`.
137
     *
138
     * @param string $name
139
     * @param string $val
140
     *
141
     * @return $this
142
     *   The current instance.
143
     */
144
    public function place($name, $val)
145
    {
146
        $this->replace('{' . $name . '}', $val);
147
148
        return $this;
149
    }
150
151
    /**
152
     * replace any string with value.
153
     *
154
     * @param string $string
155
     * @param string $replacement
156
     *
157
     * @return $this
158
     *   The current instance.
159
     */
160
    public function replace($string, $replacement)
0 ignored issues
show
Unused Code introduced by
The parameter $string is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $replacement is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
161
    {
162
        $this->stack[] = array_merge([__FUNCTION__ . 'Collect'], func_get_args());
163
        return $this;
164
    }
165
166
    /**
167
     * replace any string with value using regular expression.
168
     *
169
     * @param string $pattern
170
     * @param string $replacement
171
     *
172
     * @return $this
173
     *   The current instance.
174
     */
175
    public function regexReplace($pattern, $replacement)
0 ignored issues
show
Unused Code introduced by
The parameter $pattern is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $replacement is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
176
    {
177
        $this->stack[] = array_merge([__FUNCTION__ . 'Collect'], func_get_args());
178
        return $this;
179
    }
180
181
    /**
182
     * Append the provided text to the end of the buffer if the provided
183
     * regex pattern matches any text already in the buffer.
184
     *
185
     * @param string $pattern
186
     * @param string $text
187
     *
188
     * @return $this
189
     */
190
    public function appendIfMatches($pattern, $text)
191
    {
192
        $this->stack[] = array_merge(['appendIfMatchesCollect'], [$pattern, $text, true]);
193
        return $this;
194
    }
195
196
    /**
197
     * Append the provided text to the end of the buffer unless the provided
198
     * regex pattern matches any text already in the buffer.
199
     *
200
     * @param string $pattern
201
     * @param string $text
202
     *
203
     * @return $this
204
     */
205
    public function appendUnlessMatches($pattern, $text)
206
    {
207
        $this->stack[] = array_merge(['appendIfMatchesCollect'], [$pattern, $text, false]);
208
        return $this;
209
    }
210
211
    /**
212
     * @param string $contents
213
     * @param string $filename
214
     *
215
     * @return string
216
     */
217
    protected function textFromFileCollect($contents, $filename)
218
    {
219
        if (file_exists($filename)) {
220
            $contents .= file_get_contents($filename);
221
        }
222
        return $contents;
223
    }
224
225
    /**
226
     * @param string|string[] $contents
227
     * @param string|string[] $string
228
     * @param string|string[] $replacement
229
     *
230
     * @return string|string[]
231
     */
232
    protected function replaceCollect($contents, $string, $replacement)
233
    {
234
        return str_replace($string, $replacement, $contents);
235
    }
236
237
    /**
238
     * @param string|string[] $contents
239
     * @param string|string[] $pattern
240
     * @param string|string[] $replacement
241
     *
242
     * @return string|string[]
243
     */
244
    protected function regexReplaceCollect($contents, $pattern, $replacement)
245
    {
246
        return preg_replace($pattern, $replacement, $contents);
247
    }
248
249
    /**
250
     * @param string $contents
251
     * @param string $text
252
     *
253
     * @return string
254
     */
255
    protected function textCollect($contents, $text)
256
    {
257
        return $contents . $text;
258
    }
259
260
    /**
261
     * @param string $contents
262
     * @param string $pattern
263
     * @param string $text
264
     * @param bool $shouldMatch
265
     *
266
     * @return string
267
     */
268
    protected function appendIfMatchesCollect($contents, $pattern, $text, $shouldMatch)
269
    {
270
        if (preg_match($pattern, $contents) == $shouldMatch) {
271
            $contents .= $text;
272
        }
273
        return $contents;
274
    }
275
276
    /**
277
     * @return string
278
     */
279
    public function originalContents()
280
    {
281
        if (!isset($this->originalContents)) {
282
            $this->originalContents = '';
283
            if (file_exists($this->filename)) {
284
                $this->originalContents = file_get_contents($this->filename);
285
            }
286
        }
287
        return $this->originalContents;
288
    }
289
290
    /**
291
     * @return bool
292
     */
293
    public function wouldChange()
294
    {
295
        return $this->originalContents() != $this->getContentsToWrite();
296
    }
297
298
    /**
299
     * @return string
300
     */
301
    protected function getContentsToWrite()
302
    {
303
        $contents = "";
304
        if ($this->append) {
305
            $contents = $this->originalContents();
306
        }
307
        foreach ($this->stack as $action) {
308
            $command = array_shift($action);
309
            if (method_exists($this, $command)) {
310
                array_unshift($action, $contents);
311
                $contents = call_user_func_array([$this, $command], $action);
312
            }
313
        }
314
        return $contents;
315
    }
316
317
    /**
318
     * {@inheritdoc}
319
     */
320
    public function run()
321
    {
322
        $this->printTaskInfo("Writing to {filename}.", ['filename' => $this->filename]);
323
        $contents = $this->getContentsToWrite();
324
        if (!file_exists(dirname($this->filename))) {
325
            mkdir(dirname($this->filename), 0777, true);
326
        }
327
        $res = file_put_contents($this->filename, $contents);
328
        if ($res === false) {
329
            return Result::error($this, "File {$this->filename} couldn't be created");
330
        }
331
332
        return Result::success($this);
333
    }
334
335
    /**
336
     * @return string
337
     */
338
    public function getPath()
339
    {
340
        return $this->filename;
341
    }
342
}
343