Completed
Push — master ( d2ee45...5d494d )
by Adam
04:50 queued 02:51
created

Control::getConfirmer()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 11
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 0
Metric Value
dl 0
loc 11
ccs 0
cts 4
cp 0
rs 9.4285
c 0
b 0
f 0
cc 2
eloc 5
nc 2
nop 1
crap 6
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
 * @author         Adam Kadlec <[email protected]>
34
 */
35 1
final class Control extends BaseControl
36
{
37
	/**
38
	 * @var IConfirmer
39
	 */
40
	private $confirmerFactory;
41
42
	/**
43
	 * @var Confirmer
44
	 */
45
	private $confirmer;
46
47
	/**
48
	 * @var bool
49
	 */
50
	private $useAjax = TRUE;
51
52
	/**
53
	 * @param IConfirmer $confirmerFactory
54
	 */
55
	public function injectFactories(IConfirmer $confirmerFactory)
56
	{
57
		// Get confirmer component factory
58 1
		$this->confirmerFactory = $confirmerFactory;
59 1
	}
60
61
	/**
62
	 * @param string|NULL $layoutFile
63
	 * @param string|NULL $templateFile
64
	 */
65
	public function __construct(
66
		string $layoutFile = NULL,
67
		string $templateFile = NULL
68
	) {
69 1
		list(, , $parent, $name) = func_get_args() + [NULL, NULL, NULL, NULL];
70
71 1
		parent::__construct($parent, $name);
72
73 1
		if ($layoutFile !== NULL) {
74
			$this->setLayoutFile($layoutFile);
75
		}
76
77 1
		if ($templateFile !== NULL) {
78
			$this->setTemplateFile($templateFile);
79
		}
80 1
	}
81
82
	/**
83
	 * Change default dialog layout path
84
	 *
85
	 * @param string $layoutFile
86
	 *
87
	 * @return void
88
	 */
89
	public function setLayoutFile(string $layoutFile)
90
	{
91
		$this->setTemplateFilePath($layoutFile, self::TEMPLATE_LAYOUT);
92
	}
93
94
	/**
95
	 * Change default confirmer template path
96
	 *
97
	 * @param string $layoutFile
98
	 *
99
	 * @return void
100
	 */
101
	public function setTemplateFile(string $layoutFile)
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|Nette\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)
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()
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
	 * @throws Exceptions\InvalidArgumentException
200
	 */
201
	protected function createComponentConfirmer() : Application\UI\Multiplier
202
	{
203 1
		return new Application\UI\Multiplier((function () {
204
			// Check if confirmer factory is available
205 1
			if (!$this->confirmerFactory) {
206
				throw new Exceptions\InvalidStateException('Confirmation control factory does not exist.');
207
			}
208
209 1
			$confirmer = $this->confirmerFactory->create($this->templateFile);
210
211 1
			if ($this->useAjax) {
212 1
				$confirmer->enableAjax();
213
214
			} else {
215
				$confirmer->disableAjax();
216
			}
217
218 1
			return $confirmer;
219 1
		}));
220
	}
221
222
	/**
223
	 * Show dialog for confirmation
224
	 *
225
	 * @param string $name
226
	 * @param array $params
227
	 *
228
	 * @return void
229
	 *
230
	 * @throws Exceptions\InvalidArgumentException
231
	 * @throws Exceptions\InvalidStateException
232
	 */
233
	public function showConfirm(string $name, array $params = [])
234
	{
235 1
		if (!is_string($name)) {
236
			throw new Exceptions\InvalidArgumentException('$name must be string.');
237
		}
238
239 1
		if ((!$this->confirmer = $this['confirmer-' . $name]) || !$this->confirmer->isConfigured()) {
240
			throw new Exceptions\InvalidStateException(sprintf('Confirmer "%s" do not exist.', $name));
241
		}
242
243
		// Prepare confirmer for displaying
244 1
		$this->confirmer->showConfirm($params);
245 1
	}
246
247
	/**
248
	 * Dynamically named signal receiver
249
	 *
250
	 * @return void
251
	 *
252
	 * @throws Exceptions\InvalidArgumentException
253
	 * @throws Exceptions\InvalidStateException
254
	 */
255
	public function handleShowConfirmer()
256
	{
257 1
		if (!$this->getPresenter() instanceof Application\UI\Presenter) {
258
			throw new Exceptions\InvalidArgumentException('Confirmer is not attached to presenter.');
259
		}
260
261 1
		list(, $signal) = $this->getPresenter()->getSignal();
262
263 1
		$name = Utils\Strings::substring($signal, 7);
264 1
		$name{0} = strtolower($name{0});
265
266 1
		if (!$this['confirmer-' . $name]->isConfigured()) {
267
			throw new Exceptions\InvalidArgumentException('Invalid confirmation control.');
268
		}
269
270 1
		$params = $this->getParameters();
271
272 1
		$this->showConfirm($name, $params);
273 1
	}
274
275
	/**
276
	 * @return void
277
	 */
278
	public function enableAjax()
279
	{
280
		$this->useAjax = TRUE;
281
	}
282
283
	/**
284
	 * @return void
285
	 */
286
	public function disableAjax()
287
	{
288
		$this->useAjax = FALSE;
289
	}
290
291
	/**
292
	 * Render control
293
	 *
294
	 * @return void
295
	 *
296
	 * @throws Exceptions\InvalidStateException
297
	 */
298
	public function render()
299
	{
300
		// Create template
301 1
		$template = parent::render();
302
303
		// Check if control has template
304 1
		if ($template instanceof Nette\Bridges\ApplicationLatte\Template) {
305
			// Assign vars to template
306 1
			$template->confirmer = $this->confirmer;
307
308
			// If template was not defined before...
309 1
			if ($template->getFile() === NULL) {
310
				// ...try to get base component template file
311 1
				$layoutFile = $this->layoutFile !== NULL ? $this->layoutFile : __DIR__ . DIRECTORY_SEPARATOR . 'template' . DIRECTORY_SEPARATOR . 'layout.latte';
312 1
				$template->setFile($layoutFile);
313
			}
314
315
			// Render component template
316 1
			$template->render();
317
318
		} else {
319
			throw new Exceptions\InvalidStateException('Dialog control is without template.');
320
		}
321 1
	}
322
323
	/**
324
	 * @param string $name
325
	 *
326
	 * @return Confirmer
327
	 *
328
	 * @throws Exceptions\InvalidArgumentException
329
	 */
330
	private function getConfirmerControl(string $name) : Confirmer
331
	{
332 1
		$confirmer = $this->getComponent('confirmer-' . $name);
333
334 1
		if (!$confirmer instanceof Confirmer) {
335
			throw new Exceptions\InvalidArgumentException(sprintf('Confirmation control "%s" does not exists.', $name));
336
		}
337
338 1
		return $confirmer;
339
	}
340
}
341