Router::getAssets()   A
last analyzed

Complexity

Conditions 3
Paths 3

Size

Total Lines 21
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 3

Importance

Changes 0
Metric Value
cc 3
eloc 8
nc 3
nop 1
dl 0
loc 21
rs 9.3142
c 0
b 0
f 0
ccs 8
cts 8
cp 1
crap 3
1
<?php declare(strict_types=1);
2
namespace samsonphp\resource;
3
4
use samson\core\ExternalModule;
5
use samsonframework\filemanager\FileManagerInterface;
6
use samsonframework\localfilemanager\LocalFileManager;
7
use samsonphp\compressor\Compressor;
8
use samsonphp\event\Event;
9
10
/**
11
 * Resource router for serving static resource from unreachable web-root paths.
12
 *
13
 * TODO: Validate old files that do not exists anymore to remove them
14
 *
15
 * @author Vitaly Iegorov <[email protected]>
16
 */
17
class Router extends ExternalModule
18
{
19
    /** @deprecated Use E_MODULES */
20
    const EVENT_START_GENERATE_RESOURCES = 'resourcer.modulelist';
21
    /** Event for modifying modules */
22
    const E_MODULES = 'resourcer.modulelist';
23
    /** Event for resources preloading */
24
    const E_RESOURCE_PRELOAD = ResourceManager::E_ANALYZE;
25
    /** Event for resources compiling */
26
    const E_RESOURCE_COMPILE = ResourceManager::E_COMPILE;
27
    /** Event when recourse management is finished */
28
    const E_FINISHED = 'resourcer.finished';
29
30
    const I_MAIN_PROJECT_TEMPLATE = 'main.template';
31
32
    /** @var FileManagerInterface File system manager */
33
    public $fileManager;
34
35
    /** @deprecated Identifier */
36
    protected $id = STATIC_RESOURCE_HANDLER;
37
38
    /** @var array Template markers for inserting assets */
39
    protected $templateMarkers = ['css' => '</head>', 'js' => '</body>'];
40
41
    /** @var array Collection of static resources */
42
    protected $resources = [];
43
44
    /** @var array Collection of static resource URLs */
45
    protected $resourceUrls = [];
46
47
    /** @var  ResourceManager */
48
    protected $resourceManager;
49
50
    /**
51
     * Module initialization stage.
52
     *
53
     * @see ModuleConnector::init()
54
     *
55
     * @param array $params Initialization parameters
56
     *
57
     * @return bool True if resource successfully initialized
58
     */
59 1
    public function init(array $params = array())
60
    {
61
        // Subscribe to core template rendering event
62 1
        Event::subscribe('core.rendered', [$this, 'renderTemplate']);
63
64 1
        if (class_exists(Compressor::class, false)) {
65
            Event::subscribe(Compressor::E_CREATE_RESOURCE_LIST, [$this, 'getResources']);
66
        }
67
68
        // Set default dependency as local file manager
69 1
        $this->fileManager = $this->fileManager ?: new LocalFileManager();
70
71 1
        $this->resourceManager = new ResourceManager($this->fileManager);
72 1
        ResourceManager::$cacheRoot = $this->cache_path;
73 1
        ResourceManager::$webRoot = getcwd();
74 1
        ResourceManager::$projectRoot = dirname(ResourceManager::$webRoot) . '/';
75
76
        // Get loaded modules
77 1
        $moduleList = $this->system->module_stack;
0 ignored issues
show
Bug introduced by
Accessing module_stack on the interface samsonframework\core\SystemInterface suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
78
79
        // Event for modification of resource list
80 1
        Event::fire(self::E_MODULES, [&$moduleList]);
81
82 1
        $appResourcePaths = $this->getAssets($moduleList);
83
84
        // Get assets
85 1
        $this->resources = $this->resourceManager->manage($appResourcePaths);
86
87
        // Fire completion event
88 1
        Event::fire(self::E_FINISHED, [&$this->resources]);
89
90
        // Get asset URLs
91 1
        $this->resourceUrls = array_map([$this, 'getAssetCachedUrl'], $this->resources);
92
93
        // Continue parent initialization
94 1
        return parent::init($params);
95
    }
96
97
    /**
98
     * Get asset files from modules.
99
     *
100
     * @param array $moduleList Collection of modules
101
     *
102
     * @return string[] Resources paths
103
     */
104 2
    public function getAssets($moduleList)
105
    {
106 2
        $projectRoot = dirname(getcwd()) . '/';
107
108
        // Add resource paths
109 2
        $paths = [];
110 2
        foreach ($moduleList as $module) {
111
            /**
112
             * We need to exclude project root because vendor folder will be scanned
113
             * and all assets from there would be added.
114
             */
115 1
            if ($module->path() !== $projectRoot) {
116 1
                $paths[] = $module->path();
117
            }
118
        }
119
120
        // Add web-root as last path
121 2
        $paths[] = getcwd();
122
123 2
        return $paths;
124
    }
125
126
    /**
127
     * Template rendering handler by injecting static assets url
128
     * in appropriate.
129
     *
130
     * @param $view
131
     *
132
     * @return mixed
133
     */
134 1
    public function renderTemplate(&$view, $resourceUrls = [])
135
    {
136 1
        $resourceUrls = empty($resourceUrls)?$this->resourceUrls:$resourceUrls;
137
138 1
        foreach ($resourceUrls as $type => $urls) {
139 1
            if (array_key_exists($type, $this->templateMarkers)) {
140
                // Replace template marker by type with collection of links to resources of this type
141 1
                $view = str_ireplace(
142 1
                    $this->templateMarkers[$type],
143 1
                    implode("\n", array_map(function ($value) use ($type) {
144 1
                        if ($type === 'css') {
145 1
                            return '<link type="text/css" rel="stylesheet" property="stylesheet" href="' . $value . '">';
146 1
                        } elseif ($type === 'js') {
147 1
                            return '<script type="text/javascript" src="' . $value . '"></script>';
148
                        }
149 1
                    }, $urls)) . "\n" . $this->templateMarkers[$type],
150
                    $view
151
                );
152
            }
153
        }
154
155 1
        return $view;
156
    }
157
158
    /**
159
     *
160
     * @param array $resources
161
     * @param null  $moduleList
162
     */
163
    public function getResources(&$resources = [], $moduleList = null)
164
    {
165
        // Get assets
166
        $resources = $this->resourceManager->manage(
167
            $this->getAssets($moduleList === null
168
                ? $moduleList
169
                : $this->system->module_stack
0 ignored issues
show
Bug introduced by
Accessing module_stack on the interface samsonframework\core\SystemInterface suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
170
            )
171
        );
172
    }
173
174
    /**
175
     * Get cached asset URL.
176
     *
177
     * @param string $cachedAsset Full path to cached asset
178
     *
179
     * @return mixed Cached asset URL
180
     */
181 1
    private function getAssetCachedUrl($cachedAsset)
182
    {
183 1
        return str_replace(ResourceManager::$webRoot, '', $cachedAsset);
184
    }
185
}
186