Completed
Push — master ( b57c0a...d441ef )
by Adam
02:49 queued 14s
created

Control::disableAjax()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 2
Bugs 0 Features 1
Metric Value
c 2
b 0
f 1
dl 0
loc 4
ccs 0
cts 2
cp 0
rs 10
cc 1
eloc 2
nc 1
nop 0
crap 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
		// Check confirmer
155 1 View Code Duplication
		if ((!$confirmer = $this->getComponent('confirmer-' . $name)) || !$confirmer instanceof Confirmer || $confirmer->isConfigured()) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
156
			throw new Exceptions\InvalidArgumentException("Confirmation control '$name' could not be created.");
157
		}
158
159
		// Set confirmer handler
160 1
		$confirmer->setHandler($handler);
161
		// Set confirmer heading
162 1
		$confirmer->setHeading($heading);
163
		// Set confirmer question
164 1
		$confirmer->setQuestion($question);
165 1
	}
166
167
	/**
168
	 * @param string $name
169
	 *
170
	 * @return Confirmer
171
	 *
172
	 * @throws Exceptions\InvalidArgumentException
173
	 */
174
	public function getConfirmer(string $name) : Confirmer
175
	{
176 View Code Duplication
		if ((!$confirmer = $this->getComponent('confirmer-' . $name)) || !$confirmer instanceof Confirmer || !$confirmer->isConfigured()) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
177
			throw new Exceptions\InvalidArgumentException("Confirmation control '$name' does not exists.");
178
		}
179
180
		return $confirmer;
181
	}
182
183
	/**
184
	 * @return void
185
	 */
186
	public function resetConfirmer()
187
	{
188 1
		$this->confirmer = NULL;
189
190
		// Invalidate dialog snippets
191 1
		$this->redrawControl();
192 1
	}
193
194
	/**
195
	 * @return Application\UI\Multiplier
196
	 *
197
	 * @throws Exceptions\InvalidArgumentException
198
	 */
199
	protected function createComponentConfirmer() : Application\UI\Multiplier
200
	{
201 1
		return new Application\UI\Multiplier((function () {
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 = [])
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("Confirmer '$name' do not exist.");
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()
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()
277
	{
278
		$this->useAjax = TRUE;
279
	}
280
281
	/**
282
	 * @return void
283
	 */
284
	public function disableAjax()
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()
297
	{
298
		// Create template
299 1
		$template = parent::render();
300
301
		// Check if control has template
302 1
		if ($template instanceof Nette\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