Completed
Push — master ( 6695d4...9bc3b7 )
by Harry
04:41
created

ConvertEncoding::toEncoding()   B

Complexity

Conditions 2
Paths 2

Size

Total Lines 30
Code Lines 20

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 19
CRAP Score 2

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 30
ccs 19
cts 19
cp 1
rs 8.8571
cc 2
eloc 20
nc 2
nop 3
crap 2
1
<?php
2
3
namespace Graze\DataFile\Modify;
4
5
use Graze\DataFile\Helper\GetOptionTrait;
6
use Graze\DataFile\Helper\OptionalLoggerTrait;
7
use Graze\DataFile\Helper\Process\ProcessFactoryAwareInterface;
8
use Graze\DataFile\Node\FileNodeInterface;
9
use Graze\DataFile\Node\LocalFile;
10
use InvalidArgumentException;
11
use Psr\Log\LoggerAwareInterface;
12
use Psr\Log\LogLevel;
13
use Symfony\Component\Process\Exception\ProcessFailedException;
14
15
/**
16
 * Convert the Encoding of a file
17
 *
18
 * For a list of the supported encodings run:
19
 *
20
 * ```bash
21
 * iconv -l
22
 * ```
23
 */
24
class ConvertEncoding implements FileModifierInterface, LoggerAwareInterface, ProcessFactoryAwareInterface
25
{
26
    use OptionalLoggerTrait;
27
    use FileProcessTrait;
28
    use GetOptionTrait;
29
30
    /**
31
     * @extend Graze\DataFile\Node\File\LocalFile Only apply to local files
32
     *
33
     * @param LocalFile $file
34
     * @param string    $encoding             Encoding as defined by iconv
35
     * @param array     $options              -postfix <string> (Default: toEncoding)
36
     *                                        -keepOldFile <bool> (Default: true)
37
     *
38
     * @return LocalFile
39
     */
40 6
    public function toEncoding(LocalFile $file, $encoding, array $options = [])
41
    {
42 6
        $this->options = $options;
43
44 6
        $pathInfo = pathinfo($file->getPath());
45
46 6
        $outputFileName = sprintf(
47 6
            '%s-%s.%s',
48 6
            $pathInfo['filename'],
49 6
            $this->getOption('postfix', $encoding),
50 6
            $pathInfo['extension']
51
        );
52
53 6
        $output = $file->getClone()
54 6
                       ->setPath($pathInfo['dirname'] . '/' . $outputFileName)
55 6
                       ->setEncoding($encoding);
56
57
        $cmd = "iconv " .
58 6
            ($file->getEncoding() ? "--from-code={$file->getEncoding()} " : '') .
59 6
            "--to-code={$encoding} " .
60 6
            "{$file->getPath()} " .
61 6
            "> {$output->getPath()}";
62
63 6
        $this->log(LogLevel::INFO, "Converting file: '{file}' encoding to '{encoding}'", [
64 6
            'file'     => $file,
65 6
            'encoding' => $encoding,
66
        ]);
67
68 6
        return $this->processFile($file, $output, $cmd, $this->getOption('keepOldFile', true));
69
    }
70
71
    /**
72
     * Can this file be modified by this modifier
73
     *
74
     * @param FileNodeInterface $file
75
     *
76
     * @return bool
77
     */
78 1
    public function canModify(FileNodeInterface $file)
79
    {
80
        return (
81 1
            ($file instanceof localFile) &&
82 1
            ($file->exists())
83
        );
84
    }
85
86
    /**
87
     * Modify the file
88
     *
89
     * @param FileNodeInterface $file
90
     * @param array             $options List of options:
91
     *                                   -encoding <string>
92
     *                                   -postfix <string> (Default: toEncoding) Set this to blank to replace inline
93
     *                                   -keepOldFile <bool> (Default: true)
94
     *
95
     * @return FileNodeInterface
96
     */
97
    public function modify(FileNodeInterface $file, array $options = [])
98
    {
99
        if (!$this->canModify($file)) {
100
            throw new InvalidArgumentException("Supplied: $file is not a valid LocalFile");
101
        }
102
103
        $this->options = $options;
104
        $encoding = $this->requireOption('encoding');
105
        unset($options['encoding']);
106
107
        return $this->toEncoding($file, $encoding, $options);
0 ignored issues
show
Compatibility introduced by
$file of type object<Graze\DataFile\Node\FileNodeInterface> is not a sub-type of object<Graze\DataFile\Node\LocalFile>. It seems like you assume a concrete implementation of the interface Graze\DataFile\Node\FileNodeInterface to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
108
    }
109
}
110