Passed
Pull Request — master (#43)
by Jitendra
01:52
created

_require()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 1
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php
2
3
/*
4
 * This file is part of the PHINT package.
5
 *
6
 * (c) Jitendra Adhikari <[email protected]>
7
 *     <https://github.com/adhocore>
8
 *
9
 * Licensed under MIT license.
10
 */
11
12
namespace Ahc\Phint\Util;
13
14
use Ahc\Json\Comment;
15
use Symfony\Component\Finder\Finder;
16
17
class Path
18
{
19
    /** @var string */
20
    protected $phintPath;
21
22
    /**
23
     * Platform agnostic absolute path detection.
24
     *
25
     * @param string $path
26
     *
27
     * @return bool
28
     */
29
    public function isAbsolute(string $path): bool
30
    {
31
        if (\DIRECTORY_SEPARATOR === '\\') {
32
            return strpos($path, ':') === 1;
33
        }
34
35
        return isset($path[0]) && $path[0] === '/';
36
    }
37
38
    public function getRelativePath($fullPath, $basePath): string
39
    {
40
        if (strpos($fullPath, $basePath) === 0) {
41
            return substr($fullPath, strlen($basePath));
42
        }
43
44
        // Hmm!
45
        return $fullPath;
46
    }
47
48
    public function ensureDir(string $dir): bool
49
    {
50
        if (!\is_dir($dir)) {
51
            return \mkdir($dir, 0777, true);
52
        }
53
54
        return true;
55
    }
56
57
    public function getExtension(string $filePath): string
58
    {
59
        return \pathinfo($filePath, \PATHINFO_EXTENSION);
60
    }
61
62
    public function readAsJson(string $filePath, bool $asArray = true)
63
    {
64
        return (new Comment)->decode(\file_get_contents($filePath), $asArray);
65
    }
66
67
    public function writeFile(string $file, $content, int $mode = null): bool
68
    {
69
        $this->ensureDir(\dirname($file));
70
71
        if (!\is_string($content)) {
72
            $content = \json_encode($content, \JSON_PRETTY_PRINT | \JSON_UNESCAPED_SLASHES);
73
        }
74
75
        return \file_put_contents($file, $content, $mode) > 0;
76
    }
77
78
    public function getPhintPath(string $subpath = ''): string
79
    {
80
        $this->initPhintPath();
81
82
        if ($subpath && $this->phintPath) {
83
            return $this->phintPath . '/' . \ltrim($subpath, '/');
84
        }
85
86
        return $this->phintPath;
87
    }
88
89
    public function createBinaries(array $bins, string $basePath)
90
    {
91
        foreach ($bins as $bin) {
92
            $bin = $this->join($basePath, $bin);
93
94
            if ($this->writeFile($bin, "#!/usr/bin/env php\n<?php\n")) {
95
                @\chmod($bin, 0755);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition for chmod(). This can introduce security issues, and is generally not recommended. ( Ignorable by Annotation )

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

95
                /** @scrutinizer ignore-unhandled */ @\chmod($bin, 0755);

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
96
            }
97
        }
98
    }
99
100
    public function join(...$paths): string
101
    {
102
        if (\is_array($paths[0] ?? '')) {
103
            $paths = $paths[0];
104
        }
105
106
        $join = '';
0 ignored issues
show
Unused Code introduced by
The assignment to $join is dead and can be removed.
Loading history...
107
        foreach ($paths as $i => &$path) {
108
            $path = $i === 0 ? \rtrim($path, '\\/') : \trim($path, '\\/');
109
        }
110
111
        return \implode('/', $paths);
112
    }
113
114
    public function findFiles(array $inPaths, string $ext, bool $dotfiles = false): array
115
    {
116
        $finder = new Finder;
117
        $ext    = '.' . \ltrim($ext, '.');
118
        $len    = \strlen($ext);
119
120
        $finder->files()->ignoreDotFiles($dotfiles)->filter(function ($file) use ($ext, $len) {
121
            return \substr($file, -$len) === $ext;
122
        });
123
124
        foreach ($inPaths as $path) {
125
            $finder->in($path);
126
        }
127
128
        $files = [];
129
        foreach ($finder as $file) {
130
            $files[] = (string) $file;
131
        }
132
133
        return $files;
134
    }
135
136
    public function loadClasses(array $inPaths, string $ext): array
0 ignored issues
show
Unused Code introduced by
The parameter $ext is not used and could be removed. ( Ignorable by Annotation )

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

136
    public function loadClasses(array $inPaths, /** @scrutinizer ignore-unused */ string $ext): array

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
137
    {
138
        $classes = \array_merge(\get_declared_interfaces(), \get_declared_classes(), \get_declared_traits());
139
140
        foreach ($this->findFiles($inPaths) as $file) {
0 ignored issues
show
Bug introduced by
The call to Ahc\Phint\Util\Path::findFiles() has too few arguments starting with ext. ( Ignorable by Annotation )

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

140
        foreach ($this->/** @scrutinizer ignore-call */ findFiles($inPaths) as $file) {

This check compares calls to functions or methods with their respective definitions. If the call has less arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
141
            _require($file);
142
        }
143
144
        $newClasses = \array_merge(\get_declared_interfaces(), \get_declared_classes(), \get_declared_traits());
145
146
        return \array_diff($newClasses, $classes);
147
    }
148
149
    protected function initPhintPath()
150
    {
151
        if (null !== $this->phintPath) {
152
            return;
153
        }
154
155
        $this->phintPath = '';
156
157
        if (false !== $home = ($_SERVER['HOME'] ?? \getenv('HOME'))) {
158
            $path = \rtrim($home, '/') . '/.phint';
159
160
            if ($this->ensureDir($path)) {
161
                $this->phintPath = $path;
162
            }
163
        }
164
    }
165
}
166
167
/**
168
 * Isolated file require.
169
 *
170
 * @param string $file
171
 *
172
 * @return void
173
 */
174
function _require(string $file)
175
{
176
    require_once $file;
177
}
178