ManifestService   A
last analyzed

Complexity

Total Complexity 18

Size/Duplication

Total Lines 114
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 7

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
wmc 18
lcom 1
cbo 7
dl 0
loc 114
ccs 48
cts 48
cp 1
rs 10
c 0
b 0
f 0

8 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 5 1
A getConfig() 0 4 1
A getFormatter() 0 4 1
B getManifest() 0 32 6
A getAsset() 0 5 2
A format() 0 5 1
A getAssetManifestNotFound() 0 5 1
A autodetectManifest() 0 27 5
1
<?php
2
declare(strict_types=1);
3
4
namespace Webrouse\AssetMacro;
5
6
7
use Nette\Utils\Strings;
8
use Webrouse\AssetMacro\Exceptions\ManifestNotFoundException;
9
10
class ManifestService
11
{
12
	/** @var Config */
13
	private $config;
14
15
	/** @var IFormatter */
16
	private $formatter;
17
18
	/** @var Manifest[] */
19
	private $manifestCache = [];
20
21
22 1
	public function __construct(Config $config, IFormatter $formatter)
23
	{
24 1
		$this->config = $config;
25 1
		$this->formatter = $formatter;
26 1
	}
27
28
29
	public function getConfig(): Config
30
	{
31 1
		return $this->config;
32
	}
33
34
35
	public function getFormatter(): IFormatter
36
	{
37 1
		return $this->formatter;
38
	}
39
40
41 1
	public function getManifest(string $assetPath = null, bool $needed = true): ?Manifest
42
	{
43
		// Manifest is specified by array in config
44 1
		if (($data = $this->config->getManifestAsArray()) !== null) {
45 1
			$key = '__array__';
46 1
			if (empty($this->manifestCache[$key])) {
47 1
				$this->manifestCache[$key] = new Manifest($this->config, null, $data);
48
			}
49 1
			return $this->manifestCache[$key];
50
		}
51
52
		// Load manifest from JSON file
53 1
		$path = $this->config->getManifestPath() ?? $this->autodetectManifest($assetPath, $needed);
54 1
		if (!$path) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $path of type string|null is loosely compared to false; this is ambiguous if the string can be empty. You might want to explicitly use === null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
55 1
			return null;
56
		}
57
58 1
		if (!file_exists($path)) {
59 1
			Utils::throwError(
60 1
				new ManifestNotFoundException(sprintf("Manifest file not found: '%s'.", $path)),
61 1
				$this->config->getMissingManifestPolicy(),
62 1
				$needed
63
			);
64 1
			return null;
65
		}
66
67 1
		if (empty($this->manifestCache[$path])) {
68 1
			$this->manifestCache[$path] = new Manifest($this->config, $path);
69
		}
70
71 1
		return $this->manifestCache[$path];
72
	}
73
74
75 1
	public function getAsset(string $path, bool $needed = true): Asset
76
	{
77 1
		$manifest = $this->getManifest($path, $needed);
78 1
		return $manifest ? $manifest->getAsset($path, $needed) : $this->getAssetManifestNotFound($path);
79
	}
80
81
82 1
	public function format(string $path, bool $needed = true, string $format = '%url%', bool $absolute = false): string
83
	{
84 1
		$asset = $this->getAsset($path, $needed);
85 1
		return $this->formatter->format($asset, $format, $absolute);
86
	}
87
88
89 1
	protected function getAssetManifestNotFound(string $path): Asset
90
	{
91 1
		$revision = new Revision($this->config, $path, null);
92 1
		return new Asset($revision);
93
	}
94
95
96 1
	private function autodetectManifest(string $assetPath = null, bool $needed = true): ?string
97
	{
98
		// Finding a manifest begins in the asset directory
99 1
		$dir = $assetPath ?
100 1
			$this->config->getAssetsPath() . DIRECTORY_SEPARATOR . Utils::normalizePath(dirname($assetPath)) :
101 1
			$this->config->getAssetsPath();
102
103
		// Autodetect manifest
104 1
		while (Strings::startsWith($dir, $this->config->getAssetsPath())) {
105 1
			foreach ($this->config->getManifestAutodetectPaths() as $path) {
106 1
				$path = $dir . DIRECTORY_SEPARATOR . $path;
107 1
				if (file_exists($path)) {
108 1
					return $path;
109
				}
110
			}
111
112 1
			$dir = dirname($dir); // go up ../
113
		}
114
115 1
		Utils::throwError(
116 1
			new ManifestNotFoundException(sprintf('Manifest not found in: %s.', implode(', ', $this->config->getManifestAutodetectPaths()))),
117 1
			$this->config->getMissingManifestPolicy(),
118 1
			$needed
119
		);
120
121 1
		return null;
122
	}
123
}
124