Completed
Push — master ( 56480f...14cc6a )
by Adam
02:38
created

Confirmer::confirmClicked()   B

Complexity

Conditions 5
Paths 13

Size

Total Lines 35
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 9
CRAP Score 6.6

Importance

Changes 12
Bugs 1 Features 1
Metric Value
c 12
b 1
f 1
dl 0
loc 35
ccs 9
cts 15
cp 0.6
rs 8.439
cc 5
eloc 17
nc 13
nop 1
crap 6.6
1
<?php
2
/**
3
 * Confirmer.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           31.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\Forms;
22
use Nette\Localization;
23
24
use IPub;
25
use IPub\ConfirmationDialog;
26
use IPub\ConfirmationDialog\Exceptions;
27
28
/**
29
 * Confirmation dialog confirmer control
30
 *
31
 * @package        iPublikuj:ConfirmationDialog!
32
 * @subpackage     Components
33
 *
34
 * @property-read string $name
35
 * @property-read string $cssClass
36
 * @property-read string $useAjax
37
 */
38 1
final class Confirmer extends ConfirmerAttributes
39
{
40
	/**
41
	 * Define class name
42
	 */
43
	const CLASS_NAME = __CLASS__;
44
45
	/**
46
	 * @var Control|Nette\ComponentModel\IContainer
47
	 */
48
	private $dialog;
49
50
	/**
51
	 * @param NULL|string $templateFile
52
	 */
53
	public function __construct(string $templateFile = NULL)
54
	{
55 1
		list(, $parent, $name) = func_get_args() + [NULL, NULL, NULL];
56
57 1
		parent::__construct($parent, $name);
58
59 1
		if ($templateFile !== NULL) {
60
			$this->setTemplateFile($templateFile);
61
		}
62 1
	}
63
64
	/**
65
	 * Show current confirmer
66
	 *
67
	 * @param array $params
68
	 * 
69
	 * @return void
70
	 */
71
	public function showConfirm(array $params = [])
72
	{
73
		// Generate protection token
74 1
		$token = $this->generateToken();
75
76
		// Set generated token to form
77 1
		$this['form']['secureToken']->value = $token;
78
79
		// Store token to storage
80 1
		$this->storage->set($token, [
81 1
			'confirmer' => $this->getName(),
82 1
			'params'    => $params,
83
		]);
84
85 1
		if ($this->getQuestion() !== FALSE) {
86
			// Invalidate confirmer snippets
87 1
			$this->redrawControl();
88
			// Invalidate dialog snippets
89 1
			$this->getDialog()->redrawControl();
90
		}
91 1
	}
92
93
	/**
94
	 * Confirm YES clicked
95
	 *
96
	 * @param Forms\Controls\SubmitButton $button
97
	 * 
98
	 * @return void
99
	 *
100
	 * @throws Exceptions\HandlerNotCallableException
101
	 * @throws Exceptions\InvalidStateException
102
	 */
103
	public function confirmClicked(Forms\Controls\SubmitButton $button)
104
	{
105
		// Get submitted values from form
106 1
		$values = $button->getForm(TRUE)->getValues();
107
108
		// Get token from post
109 1
		$token = $values->secureToken;
110
111
		try {
112
			// Get values stored in confirmer storage
113 1
			$values = $this->getConfirmerValues($token);
114
			// Remove storage data for current confirmer
115 1
			$this->storage->clear($token);
116
117 1
			$this->getDialog()->resetConfirmer();
118
119 1
			$control = $this->getDialog()->getParent();
120
121 1
			if ($control === NULL) {
122
				throw new Exceptions\InvalidStateException('Confirmer is not attached to parent control.');
123
			}
124
125 1
			$this->callHandler($control, $values['params']);
126
127 1
		} catch (Exceptions\InvalidStateException $ex) {
128
			if (self::$strings['expired'] != '' && $this->getPresenter() instanceof Application\UI\Presenter) {
129
				$this->getPresenter()->flashMessage(self::$strings['expired']);
130
131
			} else {
132
				throw $ex;
133
			}
134
		}
135
136
		$this->refreshPage();
137
	}
138
139
	/**
140
	 * Confirm NO clicked
141
	 * 
142
	 * @return void
143
	 *
144
	 * @param Forms\Controls\SubmitButton $button
145
	 */
146
	public function cancelClicked(Forms\Controls\SubmitButton $button)
147
	{
148
		// Get submitted values from form
149 1
		$values = $button->getForm(TRUE)->getValues();
150
151
		// Get token from post
152 1
		$token = $values->secureToken;
153
154 1
		if ($this->getConfirmerValues($token)) {
155 1
			$this->storage->clear($token);
156
		}
157
158 1
		$this->getDialog()->resetConfirmer();
159
160 1
		$this->refreshPage();
161
	}
162
163
	/**
164
	 * Check if confirmer is fully configured
165
	 *
166
	 * @return bool
167
	 */
168
	public function isConfigured() : bool
169
	{
170 1
		if ((is_string($this->heading) || is_callable($this->heading)) &&
171 1
			(is_string($this->question) || is_callable($this->question)) &&
172 1
			is_callable($this->handler)
173
		) {
174 1
			return TRUE;
175
		}
176
177 1
		return FALSE;
178
	}
179
180
	/**
181
	 * Render confirmer
182
	 * 
183
	 * @return void
184
	 *
185
	 * @throws Exceptions\InvalidStateException
186
	 */
187
	public function render()
188
	{
189
		// Create template
190 1
		$template = parent::render();
191
192
		// Check if control has template
193 1
		if ($template instanceof Nette\Bridges\ApplicationLatte\Template) {
194
			// Assign vars to template
195 1
			$template->add('name', $this->name);
196 1
			$template->add('class', $this->cssClass);
197 1
			$template->add('icon', $this->getIcon());
198 1
			$template->add('question', $this->getQuestion());
199 1
			$template->add('heading', $this->getHeading());
200 1
			$template->add('useAjax', $this->useAjax);
201
202
			// If template was not defined before...
203 1
			if ($template->getFile() === NULL) {
204
				// ...try to get base component template file
205 1
				$templateFile = !empty($this->templateFile) ? $this->templateFile : $this->getDialog()->getTemplateFile();
206 1
				$template->setFile($templateFile);
207
			}
208
209
			// Render component template
210 1
			$template->render();
211
212
		} else {
213
			throw new Exceptions\InvalidStateException('Confirmer control is without template.');
214
		}
215 1
	}
216
217
	/**
218
	 * Change default confirmer template path
219
	 *
220
	 * @param string $layoutFile
221
	 * 
222
	 * @return void
223
	 */
224
	public function setTemplateFile(string $layoutFile)
225
	{
226
		$this->setTemplateFilePath($layoutFile, self::TEMPLATE_CONFIRMER);
227
	}
228
229
	/**
230
	 * Generate unique token key
231
	 *
232
	 * @return string
233
	 */
234
	protected function generateToken() : string
235
	{
236 1
		return base_convert(md5(uniqid('confirm' . $this->getName(), TRUE)), 16, 36);
237
	}
238
239
	/**
240
	 * Get parent dialog control
241
	 *
242
	 * @return Control
243
	 *
244
	 * @throws Exceptions\InvalidStateException
245
	 */
246
	protected function getDialog() : Control
247
	{
248
		// Check if confirm dialog was loaded before...
249 1
		if (!$this->dialog) {
250
			// ...if not try to lookup for it
251 1
			$multiplier = $this->getParent();
252
253
			// Check if confirmer is in multiplier
254 1
			if ($multiplier instanceof Application\UI\Multiplier) {
255 1
				$this->dialog = $multiplier->getParent();
256
257
				// Check if parent is right
258 1
				if (!$this->dialog instanceof Control) {
259 1
					throw new Exceptions\InvalidStateException('Confirmer is not attached to parent control!');
260
				}
261
262
			} else {
263
				throw new Exceptions\InvalidStateException('Confirmer is not attached to multiplier!');
264
			}
265
		}
266
267 1
		return $this->dialog;
268
	}
269
270
	/**
271
	 * @return void
272
	 */
273
	private function refreshPage()
274
	{
275
		// Check if request is done via ajax...
276 1
		if ($this->getPresenter() instanceof Application\UI\Presenter && !$this->getPresenter()->isAjax()) {
277
			// ...if not redirect to actual page
278 1
			$this->getPresenter()->redirect('this');
279
		}
280
	}
281
}
282