PathHelper   A
last analyzed

Complexity

Total Complexity 21

Size/Duplication

Total Lines 127
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 0

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
wmc 21
lcom 1
cbo 0
dl 0
loc 127
ccs 66
cts 66
cp 1
rs 10
c 0
b 0
f 0

2 Methods

Rating   Name   Duplication   Size   Complexity  
B __construct() 0 27 4
C normalize() 0 67 17
1
<?php
2
3
/*
4
 * This file is part of the kaloa/filesystem package.
5
 *
6
 * For full copyright and license information, please view the LICENSE file
7
 * that was distributed with this source code.
8
 */
9
10
namespace Kaloa\Filesystem;
11
12
use InvalidArgumentException;
13
14
/**
15
 *
16
 */
17
final class PathHelper
18
{
19
    /**
20
     *
21
     */
22
    const SYSTEM_AUTODETECT = 0x0;
23
24
    /**
25
     *
26
     */
27
    const SYSTEM_UNIX = 0x1;
28
29
    /**
30
     *
31
     */
32
    const SYSTEM_WINDOWS = 0x2;
33
34
    /**
35
     * @var bool
36
     */
37
    private $isWindowsSystem;
38
39
    /**
40
     * @param int $system
41
     */
42 6
    public function __construct($system = self::SYSTEM_AUTODETECT)
43
    {
44 6
        if (!in_array(
45 6
            $system,
46
            array(
47 6
                self::SYSTEM_AUTODETECT,
48 6
                self::SYSTEM_UNIX,
49
                self::SYSTEM_WINDOWS
50 6
            ),
51
            true
52 6
        )) {
53 1
            throw new InvalidArgumentException(sprintf(
54 1
                '$system must be on of the %s::SYSTEM_* constants',
55 1
                get_class($this)
56 1
            ));
57
        }
58
59 5
        $tmp = false;
60
61 5
        if (self::SYSTEM_AUTODETECT === $system) {
62 3
            $tmp = ('win' === strtolower(substr(PHP_OS, 0, 3)));
63 5
        } elseif (self::SYSTEM_WINDOWS === $system) {
64 2
            $tmp = true;
65 2
        }
66
67 5
        $this->isWindowsSystem = $tmp;
68 5
    }
69
70
    /**
71
     *
72
     * @param string $path
73
     * @return string
74
     * @throws InvalidArgumentException
75
     */
76 5
    public function normalize($path)
77
    {
78 5
        if (!is_string($path)) {
79 1
            throw new InvalidArgumentException('$path must be of type string');
80
        }
81
82 4
        $path = trim($path);
83
84 4
        $path = str_replace('\\', '/', $path);
85
86 4
        $isAbsolutePath = false;
87 4
        $windowsDriveLetter = '';
88
89 4
        if ($this->isWindowsSystem) {
90 2
            $matches = array();
91 2
            if (1 === preg_match('~\A([A-Za-z]):(\z|/.*)~', $path, $matches)) {
92 1
                $isAbsolutePath = true;
93 1
                $windowsDriveLetter = strtolower($matches[1]);
94 1
                $path = $matches[2];
95 2
            } elseif (substr($path, 0, 1) === '/') {
96 1
                $isAbsolutePath = true;
97 1
                $windowsDriveLetter = 'c';
98 1
            }
99 2
        } else {
100 2
            $isAbsolutePath = (substr($path, 0, 1) === '/');
101
        }
102
103 4
        $components = explode('/', $path);
104
105 4
        $newComponents = array();
106
107 4
        foreach ($components as $component) {
108
            switch ($component) {
109 4
                case '':
110 4
                case '.':
111
                    // Discard
112 4
                    break;
113 4
                case '..':
114 4
                    $c = count($newComponents);
115
                    if (
116 4
                        ($c === 0 && !$isAbsolutePath)
117 4
                        || ($c > 0 && $newComponents[$c - 1] === '..')
118 4
                    ) {
119
                        // Relative paths may start with ".." components
120 2
                        $newComponents[] = $component;
121 2
                    } else {
122 4
                        array_pop($newComponents);
123
                    }
124 4
                    break;
125 4
                default:
126 4
                    $newComponents[] = $component;
127 4
                    break;
128 4
            }
129 4
        }
130
131 4
        $newPath = ($isAbsolutePath ? '/' : '') . implode('/', $newComponents);
132
133 4
        if ($isAbsolutePath && $this->isWindowsSystem) {
134 1
            $newPath = $windowsDriveLetter . ':' . $newPath;
135 1
        }
136
137 4
        if ($newPath === '') {
138 4
            $newPath = '.';
139 4
        }
140
141 4
        return $newPath;
142
    }
143
}
144