Passed
Push — master ( 15bd82...8d13e1 )
by Christian
01:45
created

Configuration::isNotWritableFile()   A

Complexity

Conditions 5
Paths 1

Size

Total Lines 9
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 5

Importance

Changes 0
Metric Value
cc 5
eloc 6
nc 1
nop 0
dl 0
loc 9
ccs 5
cts 5
cp 1
crap 5
rs 9.6111
c 0
b 0
f 0
1
<?php
2
3
namespace Scheb\Tombstone\Analyzer\Config;
4
5
use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition;
6
use Symfony\Component\Config\Definition\Builder\TreeBuilder;
7
use Symfony\Component\Config\Definition\ConfigurationInterface;
8
9
class Configuration implements ConfigurationInterface
10
{
11
    public const CONFIG_ROOT = 'analyzer';
12
13 11
    public function getConfigTreeBuilder()
14
    {
15 11
        $treeBuilder = new TreeBuilder(self::CONFIG_ROOT);
16 11
        $rootNode = $treeBuilder->getRootNode();
17
18
        /* @var ArrayNodeDefinition $rootNode */
19
        $rootNode
20 11
            ->ignoreExtraKeys(false)
21 11
            ->children()
22 11
                ->arrayNode('source')
23 11
                    ->children()
24 11
                        ->arrayNode('directories')
25 11
                            ->isRequired()
26 11
                            ->requiresAtLeastOneElement()
27 11
                            ->scalarPrototype()
28 11
                                ->validate()
29 11
                                    ->ifTrue($this->isNoDirectory())
30 11
                                    ->thenInvalid('Must be a valid directory path, given: %s')
31 11
                                ->end()
32 11
                            ->end()
33 11
                        ->end()
0 ignored issues
show
Bug introduced by Christian Scheb
The method end() does not exist on Symfony\Component\Config...der\NodeParentInterface. It seems like you code against a sub-type of said class. However, the method does not exist in Symfony\Component\Config...ion\Builder\TreeBuilder. Are you sure you never get one of those? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

33
                        ->/** @scrutinizer ignore-call */ end()
Loading history...
34 11
                        ->arrayNode('excludes')
35 11
                            ->scalarPrototype()->end()
36 11
                        ->end()
37 11
                        ->arrayNode('names')
38 11
                            ->scalarPrototype()->end()
39 11
                        ->end()
40 11
                        ->arrayNode('notNames')
41 11
                            ->scalarPrototype()->end()
42 11
                        ->end()
43 11
                    ->end()
44 11
                ->end()
45 11
                ->scalarNode('rootDir')
46 11
                    ->isRequired()
47 11
                    ->validate()
48 11
                        ->ifTrue($this->isNoDirectory())
49 11
                        ->thenInvalid('Must be a valid directory path, given: %s')
50 11
                    ->end()
51 11
                ->end()
52 11
                ->arrayNode('logs')
53 11
                    ->children()
54 11
                        ->scalarNode('directory')
55 11
                            ->isRequired()
56 11
                            ->cannotBeEmpty()
57 11
                            ->validate()
58 11
                                ->ifTrue($this->isNoDirectory())
59 11
                                ->thenInvalid('Must be a valid directory path, given: %s')
60 11
                            ->end()
61 11
                        ->end()
62 11
                    ->end()
63 11
                ->end()
64 11
                ->arrayNode('report')
65 11
                    ->children()
66 11
                        ->scalarNode('php')
67 11
                            ->defaultNull()
68 11
                            ->validate()
69 11
                                ->ifTrue($this->isNotWritableFile())
70 11
                                ->thenInvalid('Must be a writable file path, given: %s')
71 11
                            ->end()
72 11
                        ->end()
73 11
                        ->scalarNode('html')
74 11
                            ->defaultNull()
75 11
                            ->validate()
76 11
                                ->ifTrue($this->isNoWritableDirectory())
77 11
                                ->thenInvalid('Must be a writable directory, given: %s')
78 11
                            ->end()
79 11
                        ->end()
80 11
                        ->scalarNode('console')->defaultFalse()->end()
81 11
                    ->end()
82 11
                ->end()
83 11
            ->end()
84
        ;
85
86 11
        return $treeBuilder;
87
    }
88
89 11
    private function isNoDirectory(): callable
90
    {
91
        return function ($path): bool {
92 9
            $path = realpath($path);
93
94 9
            return !(false !== $path && is_dir($path));
95 11
        };
96
    }
97
98 11
    private function isNotWritableFile(): callable
99
    {
100
        return function ($path): bool {
101 4
            $fileRealPath = realpath($path);
102 4
            $fileDirectory = realpath(dirname($path));
103
104
            return !(
105 4
                (false !== $fileDirectory && is_writeable($fileDirectory)) // Path is within a writable directory
106 4
                && (false === $fileRealPath || (!is_dir($fileRealPath) && is_writeable($fileRealPath))) // Path is a writable file or non-existent
107
            );
108 11
        };
109
    }
110
111 11
    private function isNoWritableDirectory(): callable
112
    {
113
        return function ($path): bool {
114 3
            $path = realpath($path);
115
116 3
            return !(false !== $path && is_dir($path) && is_writeable($path));
117 11
        };
118
    }
119
}
120