Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
66.67% covered (warning)
66.67%
14 / 21
33.33% covered (danger)
33.33%
1 / 3
CRAP
0.00% covered (danger)
0.00%
0 / 1
DestinationPreparationTrait
66.67% covered (warning)
66.67%
14 / 21
33.33% covered (danger)
33.33%
1 / 3
13.70
0.00% covered (danger)
0.00%
0 / 1
 getDestination
n/a
0 / 0
n/a
0 / 0
0
 logLn
n/a
0 / 0
n/a
0 / 0
0
 createWritableDestinationFolder
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
1 / 1
3
 checkDestinationWritable
44.44% covered (danger)
44.44%
4 / 9
0.00% covered (danger)
0.00%
0 / 1
6.74
 removeExistingDestinationIfExists
60.00% covered (warning)
60.00%
3 / 5
0.00% covered (danger)
0.00%
0 / 1
3.58
1<?php
2
3namespace WebPConvert\Convert\Converters\BaseTraits;
4
5use WebPConvert\Convert\Exceptions\ConversionFailed\FileSystemProblems\CreateDestinationFileException;
6use WebPConvert\Convert\Exceptions\ConversionFailed\FileSystemProblems\CreateDestinationFolderException;
7
8/**
9 * Trait for handling options
10 *
11 * This trait is currently only used in the AbstractConverter class. It has been extracted into a
12 * trait in order to bundle the methods concerning options.
13 *
14 * @package    WebPConvert
15 * @author     Bjørn Rosell <it@rosell.dk>
16 * @since      Class available since Release 2.0.0
17 */
18trait DestinationPreparationTrait
19{
20
21    abstract public function getDestination();
22    abstract public function logLn($msg, $style = '');
23
24    /**
25     * Create writable folder in provided path (if it does not exist already)
26     *
27     * @throws CreateDestinationFolderException  if folder cannot be removed
28     * @return void
29     */
30    private function createWritableDestinationFolder()
31    {
32        $destination = $this->getDestination();
33
34        $folder = dirname($destination);
35        if (!file_exists($folder)) {
36            $this->logLn('Destination folder does not exist. Creating folder: ' . $folder);
37            // TODO: what if this is outside open basedir?
38            // see http://php.net/manual/en/ini.core.php#ini.open-basedir
39
40            // Trying to create the given folder (recursively)
41            if (!mkdir($folder, 0777, true)) {
42                throw new CreateDestinationFolderException(
43                    'Failed creating folder. Check the permissions!',
44                    'Failed creating folder: ' . $folder . '. Check permissions!'
45                );
46            }
47        }
48    }
49
50    /**
51     * Check that we can write file at destination.
52     *
53     * It is assumed that the folder already exists (that ::createWritableDestinationFolder() was called first)
54     *
55     * @throws CreateDestinationFileException  if file cannot be created at destination
56     * @return void
57     */
58    private function checkDestinationWritable()
59    {
60        $destination = $this->getDestination();
61        $dirName = dirname($destination);
62
63        if (@is_writable($dirName) && @is_executable($dirName)) {
64            // all is well
65            return;
66        }
67
68        // The above might fail on Windows, even though dir is writable
69        // So, to be absolute sure that we cannot write, we make an actual write test (writing a dummy file)
70        // No harm in doing that for non-Windows systems either.
71        if (file_put_contents($destination, 'dummy') !== false) {
72            // all is well, after all
73            unlink($destination);
74            return;
75        }
76
77        throw new CreateDestinationFileException(
78            'Cannot create file: ' . basename($destination) . ' in dir:' . dirname($destination)
79        );
80    }
81
82    /**
83     * Remove existing destination.
84     *
85     * @throws CreateDestinationFileException  if file cannot be removed
86     * @return void
87     */
88    private function removeExistingDestinationIfExists()
89    {
90        $destination = $this->getDestination();
91        if (file_exists($destination)) {
92            // A file already exists in this folder...
93            // We delete it, to make way for a new webp
94            if (!unlink($destination)) {
95                throw new CreateDestinationFileException(
96                    'Existing file cannot be removed: ' . basename($destination)
97                );
98            }
99        }
100    }
101}