Completed
Push — master ( 14cc6a...ccb281 )
by Adam
02:36
created

Control   A

Complexity

Total Complexity 34

Size/Duplication

Total Lines 311
Duplicated Lines 0 %

Coupling/Cohesion

Components 3
Dependencies 9

Test Coverage

Coverage 70.13%

Importance

Changes 20
Bugs 2 Features 5
Metric Value
wmc 34
c 20
b 2
f 5
lcom 3
cbo 9
dl 0
loc 311
ccs 54
cts 77
cp 0.7013
rs 9.2

16 Methods

Rating   Name   Duplication   Size   Complexity  
A setTemplateFile() 0 4 1
A getTemplateFile() 0 5 2
A formatSignalMethod() 0 8 2
A injectFactories() 0 5 1
A __construct() 0 16 3
A setLayoutFile() 0 4 1
A addConfirmer() 0 21 3
A getConfirmer() 0 11 2
A resetConfirmer() 0 7 1
A createComponentConfirmer() 0 20 3
A showConfirm() 0 13 4
A handleShowConfirmer() 0 19 3
A enableAjax() 0 4 1
A disableAjax() 0 4 1
B render() 0 24 4
A getConfirmerControl() 0 10 2
1
<?php
2
/**
3
 * Control.php
4
 *
5
 * @copyright      More in license.md
6
 * @license        http://www.ipublikuj.eu
7
 * @author         Adam Kadlec http://www.ipublikuj.eu
8
 * @package        iPublikuj:ConfirmationDialog!
9
 * @subpackage     Components
10
 * @since          1.0.0
11
 *
12
 * @date           12.03.14
13
 */
14
15
declare(strict_types = 1);
16
17
namespace IPub\ConfirmationDialog\Components;
18
19
use Nette;
20
use Nette\Application;
21
use Nette\Localization;
22
use Nette\Utils;
23
24
use IPub;
25
use IPub\ConfirmationDialog\Exceptions;
26
27
/**
28
 * Confirmation dialog control
29
 *
30
 * @package        iPublikuj:ConfirmationDialog!
31
 * @subpackage     Components
32
 */
33 1
final class Control extends BaseControl
34
{
35
	/**
36
	 * Define class name
37
	 */
38
	const CLASS_NAME = __CLASS__;
39
40
	/**
41
	 * @var IConfirmer
42
	 */
43
	private $confirmerFactory;
44
45
	/**
46
	 * @var Confirmer
47
	 */
48
	private $confirmer;
49
50
	/**
51
	 * @var bool
52
	 */
53
	private $useAjax = TRUE;
54
55
	/**
56
	 * @param IConfirmer $confirmerFactory
57
	 */
58
	public function injectFactories(IConfirmer $confirmerFactory)
59
	{
60
		// Get confirmer component factory
61 1
		$this->confirmerFactory = $confirmerFactory;
62 1
	}
63
64
	/**
65
	 * @param string|NULL $layoutFile
66
	 * @param string|NULL $templateFile
67
	 */
68
	public function __construct(
69
		string $layoutFile = NULL,
70
		string $templateFile = NULL
71
	) {
72 1
		list(, , $parent, $name) = func_get_args() + [NULL, NULL, NULL, NULL];
73
74 1
		parent::__construct($parent, $name);
75
76 1
		if ($layoutFile !== NULL) {
77
			$this->setLayoutFile($layoutFile);
78
		}
79
80 1
		if ($templateFile !== NULL) {
81
			$this->setTemplateFile($templateFile);
82
		}
83 1
	}
84
85
	/**
86
	 * Change default dialog layout path
87
	 *
88
	 * @param string $layoutFile
89
	 *
90
	 * @return void
91
	 */
92
	public function setLayoutFile(string $layoutFile)
93
	{
94
		$this->setTemplateFilePath($layoutFile, self::TEMPLATE_LAYOUT);
95
	}
96
97
	/**
98
	 * Change default confirmer template path
99
	 *
100
	 * @param string $layoutFile
101
	 *
102
	 * @return void
103
	 */
104
	public function setTemplateFile(string $layoutFile)
105
	{
106 1
		$this->setTemplateFilePath($layoutFile, self::TEMPLATE_CONFIRMER);
107 1
	}
108
109
	/**
110
	 * @return string
111
	 */
112
	public function getTemplateFile() : string
113
	{
114
		// ...try to get default component layout file
115 1
		return $this->templateFile !== NULL ? $this->templateFile : __DIR__ . DIRECTORY_SEPARATOR . 'template' . DIRECTORY_SEPARATOR . 'default.latte';
116
	}
117
118
	/**
119
	 * Overrides signal method formatter
120
	 * This provide "dynamically named signals"
121
	 *
122
	 * @param string $signal
123
	 *
124
	 * @return string
125
	 */
126
	public static function formatSignalMethod($signal) : string
127
	{
128 1
		if (Utils\Strings::startsWith($signal, 'confirm')) {
129 1
			return 'handleShowConfirmer';
130
		}
131
132
		return parent::formatSignalMethod($signal);
133
	}
134
135
	/**
136
	 * Add confirmation handler to "dynamicaly named signals"
137
	 *
138
	 * @param string $name                           Confirmation/signal name
139
	 * @param callback|Nette\Utils\Callback $handler Callback called when confirmation succeed
140
	 * @param callback|string $question              Callback ($confirmer, $params) or string containing question text
141
	 * @param callback|string $heading               Callback ($confirmer, $params) or string containing heading text
142
	 *
143
	 * @return void
144
	 *
145
	 * @throws Exceptions\InvalidArgumentException
146
	 */
147
	public function addConfirmer(string $name, $handler, $question, $heading)
148
	{
149
		// Confirmer name could be only A-z
150 1
		if (!preg_match('/[A-Za-z_]+/', $name)) {
151
			throw new Exceptions\InvalidArgumentException('Confirmation control name contain invalid characters.');
152
		}
153
154 1
		$confirmer = $this->getConfirmerControl($name);
155
156
		// Check confirmer
157 1
		if ($confirmer->isConfigured()) {
158
			throw new Exceptions\InvalidArgumentException(sprintf('Confirmation control "%s" could not be created.', $name));
159
		}
160
161
		// Set confirmer handler
162 1
		$confirmer->setHandler($handler);
163
		// Set confirmer heading
164 1
		$confirmer->setHeading($heading);
165
		// Set confirmer question
166 1
		$confirmer->setQuestion($question);
167 1
	}
168
169
	/**
170
	 * @param string $name
171
	 *
172
	 * @return Confirmer
173
	 *
174
	 * @throws Exceptions\InvalidArgumentException
175
	 */
176
	public function getConfirmer(string $name) : Confirmer
177
	{
178
		$confirmer = $this->getConfirmerControl($name);
179
180
		// Check confirmer
181
		if (!$confirmer->isConfigured()) {
182
			throw new Exceptions\InvalidArgumentException(sprintf('Confirmation control "%s" does not exists.', $name));
183
		}
184
185
		return $confirmer;
186
	}
187
188
	/**
189
	 * @return void
190
	 */
191
	public function resetConfirmer()
192
	{
193 1
		$this->confirmer = NULL;
194
195
		// Invalidate dialog snippets
196 1
		$this->redrawControl();
197 1
	}
198
199
	/**
200
	 * @return Application\UI\Multiplier
201
	 *
202
	 * @throws Exceptions\InvalidArgumentException
203
	 */
204
	protected function createComponentConfirmer() : Application\UI\Multiplier
205
	{
206 1
		return new Application\UI\Multiplier((function () {
207
			// Check if confirmer factory is available
208 1
			if (!$this->confirmerFactory) {
209
				throw new Exceptions\InvalidStateException('Confirmation control factory does not exist.');
210
			}
211
212 1
			$confirmer = $this->confirmerFactory->create($this->templateFile);
213
214 1
			if ($this->useAjax) {
215 1
				$confirmer->enableAjax();
216
217
			} else {
218
				$confirmer->disableAjax();
219
			}
220
221 1
			return $confirmer;
222 1
		}));
223
	}
224
225
	/**
226
	 * Show dialog for confirmation
227
	 *
228
	 * @param string $name
229
	 * @param array $params
230
	 *
231
	 * @return void
232
	 *
233
	 * @throws Exceptions\InvalidArgumentException
234
	 * @throws Exceptions\InvalidStateException
235
	 */
236
	public function showConfirm(string $name, array $params = [])
237
	{
238 1
		if (!is_string($name)) {
239
			throw new Exceptions\InvalidArgumentException('$name must be string.');
240
		}
241
242 1
		if ((!$this->confirmer = $this['confirmer-' . $name]) || !$this->confirmer->isConfigured()) {
243
			throw new Exceptions\InvalidStateException(sprintf('Confirmer "%s" do not exist.', $name));
244
		}
245
246
		// Prepare confirmer for displaying
247 1
		$this->confirmer->showConfirm($params);
248 1
	}
249
250
	/**
251
	 * Dynamically named signal receiver
252
	 *
253
	 * @return void
254
	 *
255
	 * @throws Exceptions\InvalidArgumentException
256
	 * @throws Exceptions\InvalidStateException
257
	 */
258
	public function handleShowConfirmer()
259
	{
260 1
		if (!$this->getPresenter() instanceof Application\UI\Presenter) {
261
			throw new Exceptions\InvalidArgumentException('Confirmer is not attached to presenter.');
262
		}
263
264 1
		list(, $signal) = $this->getPresenter()->getSignal();
265
266 1
		$name = Utils\Strings::substring($signal, 7);
267 1
		$name{0} = strtolower($name{0});
268
269 1
		if (!$this['confirmer-' . $name]->isConfigured()) {
270
			throw new Exceptions\InvalidArgumentException('Invalid confirmation control.');
271
		}
272
273 1
		$params = $this->getParameters();
274
275 1
		$this->showConfirm($name, $params);
276 1
	}
277
278
	/**
279
	 * @return void
280
	 */
281
	public function enableAjax()
282
	{
283
		$this->useAjax = TRUE;
284
	}
285
286
	/**
287
	 * @return void
288
	 */
289
	public function disableAjax()
290
	{
291
		$this->useAjax = FALSE;
292
	}
293
294
	/**
295
	 * Render control
296
	 *
297
	 * @return void
298
	 *
299
	 * @throws Exceptions\InvalidStateException
300
	 */
301
	public function render()
302
	{
303
		// Create template
304 1
		$template = parent::render();
305
306
		// Check if control has template
307 1
		if ($template instanceof Nette\Bridges\ApplicationLatte\Template) {
308
			// Assign vars to template
309 1
			$template->confirmer = $this->confirmer;
310
311
			// If template was not defined before...
312 1
			if ($template->getFile() === NULL) {
313
				// ...try to get base component template file
314 1
				$layoutFile = $this->layoutFile !== NULL ? $this->layoutFile : __DIR__ . DIRECTORY_SEPARATOR . 'template' . DIRECTORY_SEPARATOR . 'layout.latte';
315 1
				$template->setFile($layoutFile);
316
			}
317
318
			// Render component template
319 1
			$template->render();
320
321
		} else {
322
			throw new Exceptions\InvalidStateException('Dialog control is without template.');
323
		}
324 1
	}
325
326
	/**
327
	 * @param string $name
328
	 *
329
	 * @return Confirmer
330
	 *
331
	 * @throws Exceptions\InvalidArgumentException
332
	 */
333
	private function getConfirmerControl(string $name) : Confirmer
334
	{
335 1
		$confirmer = $this->getComponent('confirmer-' . $name);
336
337 1
		if (!$confirmer instanceof Confirmer) {
338
			throw new Exceptions\InvalidArgumentException(sprintf('Confirmation control "%s" does not exists.', $name));
339
		}
340
341 1
		return $confirmer;
342
	}
343
}
344