Completed
Push — master ( 9fd866...fb673b )
by Nikita
02:48
created

Router::getResources()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 9
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 0
Metric Value
cc 2
eloc 4
c 0
b 0
f 0
nc 2
nop 2
dl 0
loc 9
ccs 0
cts 0
cp 0
crap 6
rs 9.6666
1
<?php
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 1
     * @see ModuleConnector::init()
54
     *
55
     * @param array $params Initialization parameters
56 1
     *
57
     * @return bool True if resource successfully initialized
58
     */
59 1
    public function init(array $params = array())
60
    {
61 1
        // Subscribe to core template rendering event
62 1
        Event::subscribe('core.rendered', [$this, 'renderTemplate']);
63 1
64 1
        Event::subscribe(Compressor::E_CREATE_RESOURCE_LIST, [$this, 'getResources']);
65
66
        // Set default dependency as local file manager
67 1
        $this->fileManager = $this->fileManager ?: new LocalFileManager();
68
69
        $this->resourceManager = new ResourceManager($this->fileManager);
70 1
        $this->resourceManager::$cacheRoot = $this->cache_path;
71
        $this->resourceManager::$webRoot = getcwd();
72 1
        $this->resourceManager::$projectRoot = dirname($this->resourceManager::$webRoot) . '/';
73
74
        // Get loaded modules
75 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...
76
77
        // Event for modification of resource list
78 1
        Event::fire(self::E_MODULES, [&$moduleList]);
79
80
        $appResourcePaths = $this->getAssets($moduleList);
81 1
82
        // Get assets
83
        $this->resources = $this->resourceManager->manage($appResourcePaths);
84 1
85
        // Fire completion event
86
        Event::fire(self::E_FINISHED, [&$this->resources]);
87
88
        // Get asset URLs
89
        $this->resourceUrls = array_map([$this, 'getAssetCachedUrl'], $this->resources);
90
91
        // Continue parent initialization
92
        return parent::init($params);
93
    }
94 2
95
    /**
96 2
     * Get asset files from modules.
97
     *
98
     * @param array $moduleList Collection of modules
99 2
     *
100 2
     * @return string[] Resources paths
101
     */
102
    public function getAssets($moduleList)
103
    {
104
        $projectRoot = dirname(getcwd()) . '/';
105 1
106 1
        // Add resource paths
107 1
        $paths = [];
108 2
        foreach ($moduleList as $module) {
109
            /**
110
             * We need to exclude project root because vendor folder will be scanned
111 2
             * and all assets from there would be added.
112
             */
113 2
            if ($module->path() !== $projectRoot) {
114
                $paths[] = $module->path();
115
            }
116
        }
117
118
        // Add web-root as last path
119
        $paths[] = getcwd();
120
121
        return $paths;
122
    }
123
124 1
    /**
125
     * Template rendering handler by injecting static assets url
126 1
     * in appropriate.
127 1
     *
128
     * @param $view
129 1
     *
130 1
     * @return mixed
131 1
     */
132 1
    public function renderTemplate(&$view, $resourceUrls = [])
133 1
    {
134 1
        $resourceUrls = empty($resourceUrls)?$this->resourceUrls:$resourceUrls;
135 1
136
        foreach ($resourceUrls as $type => $urls) {
137 1
            if (array_key_exists($type, $this->templateMarkers)) {
138
                // Replace template marker by type with collection of links to resources of this type
139 1
                $view = str_ireplace(
140 1
                    $this->templateMarkers[$type],
141 1
                    implode("\n", array_map(function ($value) use ($type) {
142
                        if ($type === 'css') {
143 1
                            return '<link type="text/css" rel="stylesheet" property="stylesheet" href="' . $value . '">';
144
                        } elseif ($type === 'js') {
145
                            return '<script type="text/javascript" src="' . $value . '"></script>';
146
                        }
147
                    }, $urls)) . "\n" . $this->templateMarkers[$type],
148
                    $view
149
                );
150
            }
151
        }
152
153 1
        return $view;
154
    }
155 1
156
    public function getResources(&$resources = [], $moduleList = null)
157
    {
158
        $moduleList = isset($moduleList)?$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...
159
160
        $appResourcePaths = $this->getAssets($moduleList);
161
162
        // Get assets
163
        $resources = $this->resourceManager->manage($appResourcePaths);
164
    }
165
166
    /**
167
     * Get cached asset URL.
168
     *
169
     * @param string $cachedAsset Full path to cached asset
170
     *
171
     * @return mixed Cached asset URL
172
     */
173
    private function getAssetCachedUrl($cachedAsset)
174
    {
175
        return str_replace(ResourceManager::$webRoot, '', $cachedAsset);
176
    }
177
}
178