Passed
Push — main ( 4ba462...bcb2e0 )
by Mohammad
03:01
created

PathResolver   A

Complexity

Total Complexity 15

Size/Duplication

Total Lines 96
Duplicated Lines 0 %

Importance

Changes 2
Bugs 0 Features 1
Metric Value
eloc 39
dl 0
loc 96
rs 10
c 2
b 0
f 1
wmc 15

9 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 5 1
A directionFromBase() 0 3 1
A outputPath() 0 5 2
A pathSection() 0 3 2
A typeNamespace() 0 8 1
A getStubPath() 0 9 2
A getPathRelativeToProject() 0 7 2
A resolvePath() 0 12 3
A typePath() 0 3 1
1
<?php
2
3
namespace Shamaseen\Repository;
4
5
use Illuminate\Support\Facades\Config;
6
use Illuminate\Support\Str;
7
8
class PathResolver
9
{
10
    protected string $modelName;
11
    protected string $userPath;
12
    protected string $basePath;
13
14
    public function __construct($modelName, $userPath, $basePath)
15
    {
16
        $this->modelName = $modelName;
17
        $this->userPath = $userPath;
18
        $this->basePath = $basePath;
19
    }
20
21
    public static array $configTypePathMap = [
22
        'Controller' => 'controllers_path',
23
        'Model' => 'models_path',
24
        'Repository' => 'repositories_path',
25
        'Request' => 'requests_path',
26
        'Resource' => 'json_resources_path',
27
        'Collection' => 'json_resources_path',
28
        'Policy' => 'policies_path',
29
        'Test' => 'tests_path'
30
    ];
31
32
    public function outputPath(string $type): string
33
    {
34
        return 'Model' === $type
35
            ? $this->directionFromBase($type).'/'.$this->modelName.'.php'
36
            : $this->directionFromBase($type).'/'.$this->modelName.$type.'.php';
37
    }
38
39
    public function directionFromBase($type): string
40
    {
41
        return $this->typePath($type).$this->pathSection($this->userPath);
42
    }
43
44
    public function pathSection(?string $section): string
45
    {
46
        return $section ? '/'.$section : '';
47
    }
48
49
    public function typePath(string $type): string
50
    {
51
        return Config::get('repository.'.self::$configTypePathMap[$type]);
52
    }
53
54
    public function getPathRelativeToProject(string $path): string
55
    {
56
        if (Str::startsWith($path, base_path())) {
57
            return Str::after($path, base_path());
58
        }
59
60
        return $path;
61
    }
62
63
    /**
64
     * Resolve each ../.
65
     */
66
    public function resolvePath(string $path): string
67
    {
68
        $paths = explode('/', $path);
69
70
        $pathsLength = count($paths);
71
        for ($i = 1; $i < $pathsLength; ++$i) {
72
            if ('..' === $paths[$i]) {
73
                unset($paths[$i - 1],$paths[$i]);
74
            }
75
        }
76
77
        return implode('/', $paths);
78
    }
79
80
    public function typeNamespace(string $type): string
81
    {
82
        $resolvedPath = $this->resolvePath($this->basePath.'/'.$this->typePath($type).$this->pathSection($this->userPath));
83
84
        $upperCaseEachSection = Str::of($resolvedPath)->explode('/')
85
            ->reduce(fn ($total, $part) => $total.'/'.ucfirst($part));
86
87
        return Str::of($this->getPathRelativeToProject($upperCaseEachSection))->ltrim('/')->replace('/', '\\');
88
    }
89
90
    /**
91
     * Get stub path base on type.
92
     *
93
     * @param string $type determine which stub should choose to get content
94
     */
95
    public function getStubPath(string $type): string
96
    {
97
        $configStub = realpath(Config::get('repository.stubs_path')."/$type.stub");
98
99
        if (!$configStub) {
100
            return __DIR__."/stubs/$type.stub";
101
        }
102
103
        return Config::get('repository.stubs_path')."/$type.stub";
104
    }
105
}
106