Completed
Branch TemplateInspector (5726eb)
by Josh
09:25
created

HintGenerator   A

Complexity

Total Complexity 19

Size/Duplication

Total Lines 179
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 0

Test Coverage

Coverage 0%

Importance

Changes 0
Metric Value
wmc 19
lcom 1
cbo 0
dl 0
loc 179
ccs 0
cts 59
cp 0
rs 10
c 0
b 0
f 0

9 Methods

Rating   Name   Duplication   Size   Complexity  
A getHints() 0 19 2
A setConfig() 0 4 1
A setPlugins() 0 4 1
A setXSL() 0 4 1
A setPluginsHints() 0 7 2
A setRenderingHints() 0 6 1
B setRulesHints() 0 31 6
A setTagAttributesHints() 0 13 3
A setTagsHints() 0 11 2
1
<?php
2
3
/**
4
* @package   s9e\TextFormatter
5
* @copyright Copyright (c) 2010-2017 The s9e Authors
6
* @license   http://www.opensource.org/licenses/mit-license.php The MIT License
7
*/
8
namespace s9e\TextFormatter\Configurator\JavaScript;
9
10
use ReflectionClass;
11
use s9e\TextFormatter\Configurator\Collections\PluginCollection;
12
13
class HintGenerator
14
{
15
	/**
16
	* @var array Config on which hints are based
17
	*/
18
	protected $config;
19
20
	/**
21
	* @var array Generated hints
22
	*/
23
	protected $hints;
24
25
	/**
26
	* @var PluginCollection Configured plugins
27
	*/
28
	protected $plugins;
29
30
	/**
31
	* @var string XSL stylesheet on which hints are based
32
	*/
33
	protected $xsl;
34
35
	/**
36
	* Generate a HINT object that contains informations about the configuration
37
	*
38
	* @return string JavaScript Code
39
	*/
40
	public function getHints()
41
	{
42
		$this->hints = [];
43
		$this->setPluginsHints();
44
		$this->setRenderingHints();
45
		$this->setRulesHints();
46
		$this->setTagsHints();
47
48
		// Build the source. Note that Closure Compiler seems to require that each of HINT's
49
		// properties be declared as a const
50
		$js = "/** @const */ var HINT={};\n";
51
		ksort($this->hints);
52
		foreach ($this->hints as $hintName => $hintValue)
53
		{
54
			$js .= '/** @const */ HINT.' . $hintName . '=' . json_encode($hintValue) . ";\n";
55
		}
56
57
		return $js;
58
	}
59
60
	/**
61
	* Set the config on which hints are based
62
	*
63
	* @param  array $config
64
	* @return void
65
	*/
66
	public function setConfig(array $config)
67
	{
68
		$this->config = $config;
69
	}
70
71
	/**
72
	* Set the collection of plugins
73
	*
74
	* @param  PluginCollection $plugins
75
	* @return void
76
	*/
77
	public function setPlugins(PluginCollection $plugins)
78
	{
79
		$this->plugins = $plugins;
80
	}
81
82
	/**
83
	* Set the XSL on which hints are based
84
	*
85
	* @param  string $xsl
86
	* @return void
87
	*/
88
	public function setXSL($xsl)
89
	{
90
		$this->xsl = $xsl;
91
	}
92
93
	/**
94
	* Set custom hints from plugins
95
	*
96
	* @return void
97
	*/
98
	protected function setPluginsHints()
99
	{
100
		foreach ($this->plugins as $plugins)
101
		{
102
			$this->hints += $plugins->getJSHints();
103
		}
104
	}
105
106
	/**
107
	* Set hints related to rendering
108
	*
109
	* @return void
110
	*/
111
	protected function setRenderingHints()
112
	{
113
		// Test for post-processing in templates. Theorically allows for false positives and
114
		// false negatives, but not in any realistic setting
115
		$this->hints['postProcessing'] = (int) (strpos($this->xsl, 'data-s9e-livepreview-postprocess') !== false);
116
	}
117
118
	/**
119
	* Set hints related to rules
120
	*
121
	* @return void
122
	*/
123
	protected function setRulesHints()
124
	{
125
		$this->hints['closeAncestor']   = 0;
126
		$this->hints['closeParent']     = 0;
127
		$this->hints['createChild']     = 0;
128
		$this->hints['fosterParent']    = 0;
129
		$this->hints['requireAncestor'] = 0;
130
131
		$flags = 0;
132
		foreach ($this->config['tags'] as $tagConfig)
133
		{
134
			// Test which rules are in use
135
			foreach (array_intersect_key($tagConfig['rules'], $this->hints) as $k => $v)
136
			{
137
				$this->hints[$k] = 1;
138
			}
139
			$flags |= $tagConfig['rules']['flags'];
140
		}
141
		$flags |= $this->config['rootContext']['flags'];
142
143
		// Iterate over Parser::RULE_* constants and test which flags are set
144
		$parser = new ReflectionClass('s9e\\TextFormatter\\Parser');
145
		foreach ($parser->getConstants() as $constName => $constValue)
146
		{
147
			if (substr($constName, 0, 5) === 'RULE_')
148
			{
149
				// This will set HINT.RULE_AUTO_CLOSE and others
150
				$this->hints[$constName] = ($flags & $constValue) ? 1 : 0;
151
			}
152
		}
153
	}
154
155
	/**
156
	* Set hints based on given tag's attributes config
157
	*
158
	* @param  array $tagConfig
159
	* @return void
160
	*/
161
	protected function setTagAttributesHints(array $tagConfig)
162
	{
163
		if (empty($tagConfig['attributes']))
164
		{
165
			return;
166
		}
167
168
		foreach ($tagConfig['attributes'] as $attrConfig)
169
		{
170
			$this->hints['attributeGenerator']    |= isset($attrConfig['generator']);
171
			$this->hints['attributeDefaultValue'] |= isset($attrConfig['defaultValue']);
172
		}
173
	}
174
175
	/**
176
	* Set hints related to tags config
177
	*
178
	* @return void
179
	*/
180
	protected function setTagsHints()
181
	{
182
		$this->hints['attributeGenerator']    = 0;
183
		$this->hints['attributeDefaultValue'] = 0;
184
		$this->hints['namespaces']            = 0;
185
		foreach ($this->config['tags'] as $tagName => $tagConfig)
186
		{
187
			$this->hints['namespaces'] |= (strpos($tagName, ':') !== false);
188
			$this->setTagAttributesHints($tagConfig);
189
		}
190
	}
191
}