Completed
Push — master ( 9450db...32d720 )
by Vojtěch
03:23
created

EnvironmentExtension::beforeCompile()   C

Complexity

Conditions 7
Paths 8

Size

Total Lines 22
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 56

Importance

Changes 0
Metric Value
dl 0
loc 22
rs 6.9811
c 0
b 0
f 0
ccs 0
cts 15
cp 0
cc 7
eloc 12
nc 8
nop 0
crap 56
1
<?php
2
3
namespace SixtyEightPublishers\Application\DI;
4
5
use Nette\DI\CompilerExtension;
6
use Nette\PhpGenerator\ClassType;
7
use SixtyEightPublishers\Application\ConfigurationException;
8
use SixtyEightPublishers\Application\Environment;
9
use SixtyEightPublishers\Application\ProfileContainer;
10
use SixtyEightPublishers\Application\IEnvironmentDetector;
11
use SixtyEightPublishers\Application\Detector\NetteRequestDetector;
12
use SixtyEightPublishers\Application\Diagnostics\Panel;
13
use SixtyEightPublishers\Application\IProfileStorage;
14
use SixtyEightPublishers\Application\Storage\SessionProfileStorage;
15
16
class EnvironmentExtension extends CompilerExtension
17
{
18
	/**
19
	 * @var array
20
	 */
21
	private $defaults = [
22
		'debugger' => FALSE,
23
		'localeDomain' => FALSE,
24
		'mode' => 'tolerant',
25
		'profile' => [],
26
	];
27
28
	/**
29
	 * {@inheritdoc}
30
	 */
31
	public function loadConfiguration()
32
	{
33
		$builder = $this->getContainerBuilder();
34
		$config = $this->getConfig($this->defaults);
35
36
		$builder->addDefinition($this->prefix('environment'))
37
			->setClass(Environment::class);
38
39
		$builder->addDefinition($this->prefix('detector'))
40
			->setClass(NetteRequestDetector::class);
41
42
		$builder->addDefinition($this->prefix('profileStorage'))
43
			->setClass(SessionProfileStorage::class);
44
45
		$profileContainer = $builder->addDefinition($this->prefix('profileContainer'))
46
			->setClass(ProfileContainer::class);
47
48
		if (empty($config['profile'])) {
49
			throw new ConfigurationException("You must define some profile combination in your configuration.");
50
		}
51
52
		$requiredProfileParams = ['country', 'language', 'currency'];
53
		foreach ($config['profile'] as $profileName => $profile) {
54
			if (!empty(array_diff($requiredProfileParams, array_keys($profile)))) {
55
				throw new ConfigurationException("Problem with \"{$profileName}\" profile configuration. There are missing some of the required parameters (country, language, currency).");
56
			}
57
58
			$profileContainer->addSetup('addProfile', [
59
				$profileName,
60
				(array) $profile['country'],
61
				(array) $profile['language'],
62
				(array) $profile['currency'],
63
				array_key_exists('domain', $profile) ? (array) $profile['domain'] : [],
64
				!(array_key_exists('disable', $profile) && $profile['disable'] === TRUE),
65
			]);
66
		}
67
68
		if ($this->useDebugger()) {
69
			$builder->addDefinition($this->prefix('panel'))
70
				->setClass(Panel::class)
71
				->setInject(FALSE)
72
				->setAutowired(FALSE);
73
		}
74
	}
75
76
	/**
77
	 * {@inheritdoc}
78
	 */
79
	public function beforeCompile()
80
	{
81
		$builder = $this->getContainerBuilder();
82
		$detectors = $builder->findByType(IEnvironmentDetector::class);
83
		$storage = $builder->findByType(IProfileStorage::class);
84
85
		if (count($detectors) > 1) {
86
			foreach ($detectors as $name => $definition) {
87
				if ($definition->getClass() === NetteRequestDetector::class) {
88
					$builder->removeDefinition($name);
89
				}
90
			}
91
		}
92
93
		if (count($storage) > 1) {
94
			foreach ($storage as $name => $definition) {
95
				if ($definition->getClass() === SessionProfileStorage::class) {
96
					$builder->removeDefinition($name);
97
				}
98
			}
99
		}
100
	}
101
102
	/**
103
	 * {@inheritdoc}
104
	 */
105
	public function afterCompile(ClassType $class)
106
	{
107
		$initialize = $class->methods['initialize'];
108
109
		if ($this->useDebugger()) {
110
			$bar = $this->getContainerBuilder()->getByType('Tracy\Bar');
111
			$initialize->addBody('$this->getService(?)->addPanel($this->getService(?));', [
112
				$bar,
113
				$this->prefix('panel'),
114
			]);
115
		}
116
	}
117
118
	/**
119
	 * @return bool
120
	 */
121
	private function useDebugger()
122
	{
123
		$config = $this->getConfig($this->defaults);
124
		$bar = $this->getContainerBuilder()->getByType('Tracy\Bar');
125
126
		return ($config['debugger'] && $bar && interface_exists('Tracy\IBarPanel'));
0 ignored issues
show
Bug Best Practice introduced by
The expression $bar of type string|null is loosely compared to true; 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...
127
	}
128
}
129