Completed
Push — master ( 2b133d...acf90e )
by Michal
05:36
created

ManifestService::formatOutput()   B

Complexity

Conditions 10
Paths 2

Size

Total Lines 34

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 20
CRAP Score 11.7434

Importance

Changes 0
Metric Value
dl 0
loc 34
ccs 20
cts 27
cp 0.7407
rs 7.6666
c 0
b 0
f 0
cc 10
nc 2
nop 3
crap 11.7434

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
declare(strict_types=1);
3
4
namespace Webrouse\AssetMacro;
5
6
7
use Nette\Http\IRequest;
8
use Nette\Utils\Strings;
9
use Webrouse\AssetMacro\Exceptions\InvalidVariableException;
10
use Webrouse\AssetMacro\Exceptions\ManifestNotFoundException;
11
12
class ManifestService
13
{
14
	/** @var Config */
15
	private $config;
16
17
	/** @var string */
18
	private $baseUrl;
19
20
	/** @var string */
21
	private $basePath;
22
23
	/** @var Manifest[] */
24
	private $manifestCache = [];
25
26
27 1
	public function __construct(Config $config, IRequest $httpRequest)
28
	{
29 1
		$this->config = $config;
30 1
		$url = $httpRequest->getUrl();
31 1
		$this->baseUrl = $url->getBaseUrl() . $this->config->getPublicPath();
32 1
		$this->basePath = $url->getBasePath() . $this->config->getPublicPath();
33 1
	}
34
35
36
	public function getConfig(): Config
37
	{
38 1
		return $this->config;
39
	}
40
41
42 1
	public function getManifest(string $assetPath = null, bool $needed = true): ?Manifest
43
	{
44
		// Manifest is specified by array in config
45 1
		if (($data = $this->config->getManifestAsArray()) !== null) {
46 1
			$key = '__array__';
47 1
			if (empty($this->manifestCache[$key])) {
48 1
				$this->manifestCache[$key] = new Manifest($this->config, null, $data);
49
			}
50 1
			return $this->manifestCache[$key];
51
		}
52
53
		// Load manifest from JSON file
54 1
		$path = $this->config->getManifestPath() ?? $this->autodetectManifest($assetPath, $needed);
55 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...
56 1
			return null;
57
		}
58
59 1
		if (!file_exists($path)) {
60 1
			Utils::throwError(
61 1
				new ManifestNotFoundException(sprintf("Manifest file not found: '%s'.", $path)),
62 1
				$this->config->getMissingManifestPolicy(),
63 1
				$needed
64
			);
65 1
			return null;
66
		}
67
68 1
		if (empty($this->manifestCache[$path])) {
69 1
			$this->manifestCache[$path] = new Manifest($this->config, $path);
70
		}
71
72 1
		return $this->manifestCache[$path];
73
	}
74
75
76 1
	public function getAsset(string $path, bool $needed = true): ?Asset
77
	{
78 1
		$manifest = $this->getManifest($path, $needed);
79 1
		return $manifest ? $manifest->getAsset($path, $needed) : $this->getAssetManifestNotFound($path);
80
	}
81
82
83 1
	public function formatOutput(Asset $asset, string $format = '%url%', bool $absolute = false): string
84
	{
85 1
		$base = $absolute ? $this->baseUrl : $this->basePath;
86
87 1
		return Strings::replace($format,
88 1
			'/%([^%]+)%/',
89 1
			function ($matches) use ($asset, $format, $base) {
90 1
				switch ($matches[1]) {
91
					case 'content':
92 1
						$content = file_get_contents($asset->getAbsolutePath());
93 1
						return $content ? trim($content) : '';
94
					case 'raw':
95 1
						return $asset->getRevision()->getRawValue();
96
					case 'base':
97 1
						return $base;
98
					case 'basePath':
99 1
						return $this->basePath;
100
					case 'baseUrl':
101 1
						return $this->baseUrl;
102
					case 'path':
103 1
						return $asset->getRelativePath();
104
					case 'url':
105 1
						return sprintf('%s%s', $base, $asset->getRelativeUrl());
106
					default:
107 1
						$msg = sprintf(
108
							"Asset macro: Invalid variable '%s' in format '%s'. " .
109 1
							'Use one of allowed variables: %%raw%%, %%basePath%%, %%path%%, %%url%%.',
110 1
							$matches[1],
111 1
							$format
112
						);
113 1
						throw new InvalidVariableException($msg);
114
				}
115 1
			});
116
	}
117
118
119 1
	protected function getAssetManifestNotFound(string $path): Asset
120
	{
121 1
		$revision = new Revision($this->config, $path, null);
122 1
		return new Asset($revision);
123
	}
124
125
126 1
	private function autodetectManifest(string $assetPath = null, bool $needed = true): ?string
127
	{
128
		// Finding a manifest begins in the asset directory
129 1
		$dir = $assetPath ?
130 1
			$this->config->getAssetsPath() . DIRECTORY_SEPARATOR . Utils::normalizePath(dirname($assetPath)) :
131 1
			$this->config->getAssetsPath();
132
133
		// Autodetect manifest
134 1
		while (Strings::startsWith($dir, $this->config->getAssetsPath())) {
135 1
			foreach ($this->config->getManifestAutodetectPaths() as $path) {
136 1
				$path = $dir . DIRECTORY_SEPARATOR . $path;
137 1
				if (file_exists($path)) {
138 1
					return $path;
139
				}
140
			}
141
142 1
			$dir = dirname($dir); // go up ../
143
		}
144
145 1
		Utils::throwError(
146 1
			new ManifestNotFoundException(sprintf('Manifest not found in: %s.', implode(', ', $this->config->getManifestAutodetectPaths()))),
147 1
			$this->config->getMissingManifestPolicy(),
148 1
			$needed
149
		);
150
151 1
		return null;
152
	}
153
}
154