Control::setTemplateFile()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

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