Passed
Push — master ( 75a1fc...ca2b73 )
by Andreas
03:14
created

Joiner::sortFiles()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
eloc 1
dl 0
loc 3
ccs 2
cts 2
cp 1
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 1
crap 1
1
<?php
2
/**
3
 * PDFtk wrapper
4
 *
5
 * @copyright 2014-2018 Institute of Legal Medicine, Medical University of Innsbruck
6
 * @author Andreas Erhard <[email protected]>
7
 * @author Nikola Vrlazic <[email protected]>
8
 * @license LGPL-3.0-only
9
 * @link http://www.gerichtsmedizin.at/
10
 *
11
 * @package pdftk
12
 */
13
14
namespace Gmi\Toolkit\Pdftk;
15
16
use Symfony\Component\Finder\Finder;
17
use Symfony\Component\Process\Process;
18
19
use Gmi\Toolkit\Pdftk\Exception\JoinException;
20
use Gmi\Toolkit\Pdftk\Exception\FileNotFoundException;
21
use Gmi\Toolkit\Sorter\FileSorterInterface;
22
use Gmi\Toolkit\Sorter\NaturalFileSorter;
23
24
use Exception;
25
use SplFileInfo;
26
27
/**
28
 * Searches folder, and naturally sorts PDF files. After sorting the PDFs, all PDFs will be combined to one file.
29
 *
30
 * <pre>
31
 * $joiner = new PdfJoiner();
32
 * $joiner->joinByPattern('/var/www/test/foo', '/^FILE123456_.*\.pdf$', '/tmp/my_file.pdf');
33
 * </pre>
34
 */
35
class Joiner
36
{
37
    /**
38
     * @var Finder
39
     */
40
    private $finder;
41
42
    /**
43
     * @var FileSorterInterface
44
     */
45
    private $sorter;
46
47
    /**
48
     * @var PdftkWrapper
49
     */
50
    private $wrapper;
51
52
    /**
53
     * Constructor.
54
     *
55
     * @param PdftkWrapper        $wrapper
56
     * @param Finder              $finder
57
     * @param FileSorterInterface $sorter
58
     */
59 11
    public function __construct(PdftkWrapper $wrapper = null, Finder $finder = null, FileSorterInterface $sorter = null)
60
    {
61 11
        $this->wrapper = $wrapper ?: new PdftkWrapper();
62 11
        $this->finder = $finder ?: new Finder();
63 11
        $this->sorter = $sorter ?: new NaturalFileSorter();
64 11
    }
65
66
    /**
67
     * Joins all PDFs in a folder matching a pattern, naturally sorted, to one file.
68
     *
69
     * @param string $inputFolder
70
     * @param string $pattern
71
     * @param string $output
72
     *
73
     * @throws FileNotFoundException if no matching input files are found in the input folder
74
     * @throws JoinException if the PDF join fails
75
     */
76 6
    public function joinByPattern($inputFolder, $pattern, $output)
77
    {
78
        // array of files which match the pattern
79 6
        $foundFiles = $this->getFiles($inputFolder, $pattern);
80
81 6
        if (count($foundFiles) === 0) {
82 1
            throw new FileNotFoundException(
83 1
                sprintf(
84 1
                    'No files in "%s" are matching to the pattern "%s".',
85 1
                    $inputFolder,
86
                    $pattern
87 1
                )
88 1
            );
89
        }
90
91
        // array of sorted files
92 5
        $files = $this->sorter->sort($foundFiles);
93
94 5
        return $this->join($files, $output);
0 ignored issues
show
Bug introduced by
Are you sure the usage of $this->join($files, $output) targeting Gmi\Toolkit\Pdftk\Joiner::join() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
95
    }
96
97
    /**
98
     * Joins a list of PDFs (represented by SplFileInfo instances) to one file.
99
     *
100
     * @param SplFileInfo[] $files
101
     * @param string        $output
102
     *
103
     * @throws JoinException if the PDF join fails
104
     */
105 5
    public function join($files, $output)
106
    {
107 5
        $filePaths = [];
108 5
        foreach ($files as $file) {
109 5
            $filePaths[] = escapeshellarg($file->getPathname());
110 5
        }
111
112 5
        $fileList = implode(' ', $filePaths);
113
114 5
        $commandLine = sprintf('%s %s cat output %s', $this->wrapper->getBinary(), $fileList, escapeshellarg($output));
115
116
        /**
117
         * @var Process
118
         */
119 5
        $process = $this->wrapper->createProcess($commandLine);
120 5
        $process->setTimeout(300);
121
122
        try {
123 5
            $process->mustRun();
124 5
        } catch (Exception $e) {
125 2
            throw new JoinException(
126 2
                sprintf('Failed to join PDF "%s"! Error: %s', $output, $e->getMessage()),
127 2
                0,
128 2
                $e,
129 2
                $process->getErrorOutput(),
130 2
                $process->getOutput()
131 2
            );
132
        }
133
134 3
        $process->getOutput();
135 3
    }
136
137
    /**
138
     * Finds all files inside the folder with specific pattern.
139
     *
140
     * @param string $folder
141
     * @param string $pattern
142
     *
143
     * @return SplFileInfo[]
144
     */
145 6
    private function getFiles($folder, $pattern)
146
    {
147 6
        $files = $this->finder->files()->name($pattern)->in($folder);
148
149 6
        $results = [];
150
151 6
        foreach ($files as $file) {
152 5
            $results[] = $file;
153 6
        }
154
155 6
        return $results;
156
    }
157
}
158