Completed
Push — master ( c14408...ca9cbd )
by Vitaly
02:50
created

Resource::scan()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 21
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 1
eloc 10
c 2
b 0
f 0
nc 1
nop 3
dl 0
loc 21
rs 9.3142
1
<?php
2
/**
3
 * Created by Vitaly Iegorov <[email protected]>.
4
 * on 15.05.16 at 10:52
5
 */
6
namespace samsonphp\resource;
7
8
use samsonphp\resource\exception\ResourceNotFound;
9
10
/**
11
 * Static resource entity class.
12
 *
13
 * @package samsonphp\resource
14
 */
15
class Resource
16
{
17
    /** Collection of excluding scanning folder patterns */
18
    const EXCLUDING_FOLDERS = [
19
        '*/cache/*',
20
        '*/tests/*',
21
        '*/vendor/*/vendor/*'
22
    ];
23
24
    /** @var string Full path to project web root directory */
25
    public static $webRoot;
26
27
    /** @var string Full path to project root directory */
28
    public static $projectRoot;
29
30
    /**
31
     * Recursively scan collection of paths to find assets with passed
32
     * extensions. Method is based on linux find command so this method
33
     * can face difficulties on other OS.
34
     *
35
     * TODO: Add windows support
36
     * TODO: Check if CMD commands can be executed
37
     *
38
     * @param array $paths      Paths for files scanning
39
     * @param array $extensions File extension filter
40
     * @param array $excludeFolders Path patterns for exluding
41
     *
42
     * @return array Found files
43
     */
44
    public static function scan(array $paths, array $extensions, array $excludeFolders = self::EXCLUDING_FOLDERS)
45
    {
46
        // Generate LINUX command to gather resources as this is 20 times faster
47
        $files = [];
48
49
        // Generate exclusion conditions
50
        $exclude = implode(' ', array_map(function ($value) {
51
            return '-not -path ' . $value.' ';
52
        }, $excludeFolders));
53
54
        // Generate other types
55
        $filters = implode('-o ', array_map(function ($value) use ($exclude) {
56
            return '-name "*.' . $value . '" '.$exclude;
57
        }, $extensions));
58
59
        // Scan path excluding folder patterns
60
        exec('find ' . implode(' ', $paths) . ' -type f '.$filters, $files);
61
62
        // TODO: Why some paths have double slashes? Investigate speed of realpath, maybe // changing if quicker
63
        return array_map('realpath', $files);
64
    }
65
66
    /**
67
     * Build relative path to static resource relatively to web root path.
68
     *
69
     * @param string $relativePath Relative path to static resource
70
     * @param string $parentPath   Path to parent entity
71
     *
72
     * @return string Validated relative path to static resource relatively to web root path
73
     * @throws ResourceNotFound
74
     */
75
    public static function getWebRelativePath($relativePath, $parentPath = '')
76
    {
77
        return static::getRelativePath($relativePath, $parentPath, static::$webRoot);
78
    }
79
80
    /**
81
     * Build correct relative path to static resource using relative path and parent path.
82
     *
83
     * @param string $relativePath Relative path to static resource
84
     * @param string $parentPath   Path to parent entity
85
     * @param string $rootPath     Root path for relative path building
86
     *
87
     * @return string Validated relative path to static resource
88
     * @throws ResourceNotFound
89
     */
90
    public static function getRelativePath($relativePath, $parentPath = '', $rootPath = '')
91
    {
92
        // If parent path if not passed - use project root path
93
        $parentPath = $parentPath === '' ? static::$projectRoot : $parentPath;
94
95
        // Build full path to resource from given relative path
96
        $fullPath = rtrim($parentPath, DIRECTORY_SEPARATOR)
97
            .DIRECTORY_SEPARATOR
98
            .ltrim($relativePath, DIRECTORY_SEPARATOR);
99
100
        // Make real path with out possible "../"
101
        $realPath = realpath($fullPath);
102
103
        // Output link to static resource handler with relative path to project root
104
        if ($realPath) {
105
            // Build relative path to static resource
106
            return str_replace($rootPath, '', $realPath);
107
        }
108
109
        throw new ResourceNotFound($fullPath);
110
    }
111
112
    /**
113
     * Build relative path to static resource relatively to project root path.
114
     *
115
     * @param string $relativePath Relative path to static resource
116
     * @param string $parentPath   Path to parent entity
117
     *
118
     * @return string Validated relative path to static resource relatively to project root path
119
     * @throws ResourceNotFound
120
     */
121
    public static function getProjectRelativePath($relativePath, $parentPath = '')
122
    {
123
        return static::getRelativePath($relativePath, $parentPath, static::$projectRoot);
124
    }
125
}
126