Completed
Push — master ( 630231...6cd933 )
by Harry
03:23
created

ReFormat::reFormat()   C

Complexity

Conditions 8
Paths 24

Size

Total Lines 39
Code Lines 23

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 17
CRAP Score 8

Importance

Changes 2
Bugs 0 Features 1
Metric Value
c 2
b 0
f 1
dl 0
loc 39
ccs 17
cts 17
cp 1
rs 5.3846
cc 8
eloc 23
nc 24
nop 5
crap 8
1
<?php
2
/**
3
 * This file is part of graze/data-file
4
 *
5
 * Copyright (c) 2016 Nature Delivered Ltd. <https://www.graze.com>
6
 *
7
 * For the full copyright and license information, please view the LICENSE
8
 * file that was distributed with this source code.
9
 *
10
 * @license https://github.com/graze/data-file/blob/master/LICENSE.md
11
 * @link    https://github.com/graze/data-file
12
 */
13
14
namespace Graze\DataFile\Modify;
15
16
use Graze\DataFile\Format\FormatAwareInterface;
17
use Graze\DataFile\Format\FormatInterface;
18
use Graze\DataFile\Format\Formatter\FormatterFactory;
19
use Graze\DataFile\Format\Formatter\FormatterFactoryInterface;
20
use Graze\DataFile\Format\Parser\ParserFactory;
21
use Graze\DataFile\Format\Parser\ParserFactoryInterface;
22
use Graze\DataFile\Helper\Builder\BuilderAwareInterface;
23
use Graze\DataFile\Helper\Builder\BuilderInterface;
24
use Graze\DataFile\Helper\FileHelper;
25
use Graze\DataFile\Helper\GetOptionTrait;
26
use Graze\DataFile\Helper\OptionalLoggerTrait;
27
use Graze\DataFile\IO\FileReader;
28
use Graze\DataFile\IO\FileWriter;
29
use Graze\DataFile\Node\FileNodeInterface;
30
use Graze\DataFile\Node\LocalFileNodeInterface;
31
use InvalidArgumentException;
32
use Psr\Log\LoggerAwareInterface;
33
use Psr\Log\LogLevel;
34
35
class ReFormat implements FileModifierInterface, LoggerAwareInterface, BuilderAwareInterface
36
{
37
    use OptionalLoggerTrait;
38
    use GetOptionTrait;
39
    use FileProcessTrait;
40
    use FileHelper;
41
42
    /** @var FormatterFactoryInterface */
43
    private $formatterFactory;
44
    /** @var ParserFactoryInterface */
45
    private $parserFactory;
46
47
    /**
48
     * ReFormat constructor.
49
     *
50
     * @param FormatterFactoryInterface|null $formatterFactory
51
     * @param ParserFactoryInterface|null    $parserFactory
52
     * @param BuilderInterface|null          $builder
53
     */
54 12
    public function __construct(
55
        FormatterFactoryInterface $formatterFactory = null,
56
        ParserFactoryInterface $parserFactory = null,
57
        BuilderInterface $builder = null
58
    ) {
59 12
        $this->builder = $builder;
60 12
        $this->formatterFactory = $formatterFactory ?: $this->getBuilder()->build(FormatterFactory::class);
61 12
        $this->parserFactory = $parserFactory ?: $this->getBuilder()->build(ParserFactory::class);
62 12
    }
63
64
    /**
65
     * Can this file be modified by this modifier
66
     *
67
     * @param FileNodeInterface $file
68
     *
69
     * @return bool
70
     */
71 2
    public function canModify(FileNodeInterface $file)
72
    {
73 2
        return ($file->exists()
74 2
            && $file instanceof FormatAwareInterface
75 2
            && $file->getFormat() !== null
76 2
            && $this->parserFactory->getParser($file->getFormat()) !== null);
77
    }
78
79
    /**
80
     * Modify the file
81
     *
82
     * @param FileNodeInterface $file
83
     * @param array             $options -output <LocalFileNodeInterface> Output file to write to
84
     *                                   -format <FormatInterface> Format to use for the output
85
     *                                   -postfix <string> (Default: 'format') string to use when creating a copied
86
     *                                   field (if applicable)
87
     *                                   -keepOldFile <bool> (Default: true) keep or delete the input file
88
     *
89
     * @return FileNodeInterface
90
     */
91 3
    public function modify(FileNodeInterface $file, array $options = [])
92
    {
93 3
        $this->options = $options;
94
95 3
        $format = $this->getOption('format', null);
96 3
        $output = $this->getOption('output', null);
97 3
        if ((is_null($format) || (!$format instanceof FormatInterface))
98 3
            && (is_null($output) || (!$output instanceof LocalFileNodeInterface))
99
        ) {
100 1
            throw new InvalidArgumentException("Missing a Required option: 'format' or 'output'");
101
        }
102
103 2
        return $this->reFormat($file, $format, $output, null, $options);
104
    }
105
106
    /**
107
     * @param FileNodeInterface      $file
108
     * @param FormatInterface|null   $outputFormat
109
     * @param FileNodeInterface|null $output
110
     * @param FormatInterface|null   $inputFormat
111
     * @param array                  $options -postfix <string> (Default: 'format') string to use when creating a
112
     *                                        copied field (if applicable)
113
     *                                        -keepOldFile <bool> (Default: true) keep or delete the input file
114
     *
115
     * @return FileNodeInterface
116
     */
117 8
    public function reFormat(
118
        FileNodeInterface $file,
119
        FormatInterface $outputFormat = null,
120
        FileNodeInterface $output = null,
121
        FormatInterface $inputFormat = null,
122
        array $options = []
123
    ) {
124 8
        $this->options = $options;
125
126 8
        if (is_null($output)) {
127 3
            if ($file instanceof LocalFileNodeInterface) {
128 2
                $output = $this->getTargetFile($file, $this->getOption('postfix', 'format'));
129
            } else {
130 1
                $output = $this->getTemporaryFile();
131
            }
132
        }
133
134 8
        if ($output instanceof FormatAwareInterface
135 8
            && $outputFormat != null
136
        ) {
137 3
            $output->setFormat($outputFormat);
138
        }
139
140
        /** @var FileReader $reader */
141 8
        $reader = $this->getBuilder()->build(FileReader::class, $file, $inputFormat, $this->parserFactory);
142
        /** @var FileWriter $writer */
143 8
        $writer = $this->getBuilder()->build(FileWriter::class, $output, $outputFormat, $this->formatterFactory);
144
145 8
        foreach ($reader->fetch() as $row) {
146 8
            $writer->insertOne($row);
147
        }
148
149 8
        if ($file->exists() && !$this->getOption('keepOldFile', true)) {
150 1
            $this->log(LogLevel::DEBUG, "Deleting old file: '{file}'", ['file' => $file]);
151 1
            $file->delete();
152
        }
153
154 8
        return $output;
155
    }
156
}
157