Completed
Push — master ( d441ef...56480f )
by Adam
03:05
created

Confirmer::confirmClicked()   C

Complexity

Conditions 7
Paths 20

Size

Total Lines 39
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 9
CRAP Score 11.1032

Importance

Changes 12
Bugs 1 Features 1
Metric Value
c 12
b 1
f 1
dl 0
loc 39
ccs 9
cts 16
cp 0.5625
rs 6.7272
cc 7
eloc 18
nc 20
nop 1
crap 11.1032
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
		// Check if request is done via ajax...
137
		if ($this->getPresenter() instanceof Application\UI\Presenter && !$this->getPresenter()->isAjax()) {
138
			// ...if not redirect to actual page
139
			$this->getPresenter()->redirect('this');
140
		}
141
	}
142
143
	/**
144
	 * Confirm NO clicked
145
	 * 
146
	 * @return void
147
	 *
148
	 * @param Forms\Controls\SubmitButton $button
149
	 */
150
	public function cancelClicked(Forms\Controls\SubmitButton $button)
151
	{
152
		// Get submitted values from form
153 1
		$values = $button->getForm(TRUE)->getValues();
154
155
		// Get token from post
156 1
		$token = $values->secureToken;
157
158 1
		if ($this->getConfirmerValues($token)) {
159 1
			$this->storage->clear($token);
160
		}
161
162 1
		$this->getDialog()->resetConfirmer();
163
164
		// Check if request is done via ajax...
165 1
		if ($this->getPresenter() instanceof Application\UI\Presenter && !$this->getPresenter()->isAjax()) {
166
			// ...if not redirect to actual page
167 1
			$this->getPresenter()->redirect('this');
168
		}
169
	}
170
171
	/**
172
	 * Check if confirmer is fully configured
173
	 *
174
	 * @return bool
175
	 */
176
	public function isConfigured() : bool
177
	{
178 1
		if ((is_string($this->heading) || is_callable($this->heading)) &&
179 1
			(is_string($this->question) || is_callable($this->question)) &&
180 1
			is_callable($this->handler)
181
		) {
182 1
			return TRUE;
183
		}
184
185 1
		return FALSE;
186
	}
187
188
	/**
189
	 * Render confirmer
190
	 * 
191
	 * @return void
192
	 *
193
	 * @throws Exceptions\InvalidStateException
194
	 */
195
	public function render()
196
	{
197
		// Create template
198 1
		$template = parent::render();
199
200
		// Check if control has template
201 1
		if ($template instanceof Nette\Bridges\ApplicationLatte\Template) {
202
			// Assign vars to template
203 1
			$template->add('name', $this->name);
204 1
			$template->add('class', $this->cssClass);
205 1
			$template->add('icon', $this->getIcon());
206 1
			$template->add('question', $this->getQuestion());
207 1
			$template->add('heading', $this->getHeading());
208 1
			$template->add('useAjax', $this->useAjax);
209
210
			// If template was not defined before...
211 1
			if ($template->getFile() === NULL) {
212
				// ...try to get base component template file
213 1
				$templateFile = !empty($this->templateFile) ? $this->templateFile : $this->getDialog()->getTemplateFile();
214 1
				$template->setFile($templateFile);
215
			}
216
217
			// Render component template
218 1
			$template->render();
219
220
		} else {
221
			throw new Exceptions\InvalidStateException('Confirmer control is without template.');
222
		}
223 1
	}
224
225
	/**
226
	 * Change default confirmer template path
227
	 *
228
	 * @param string $layoutFile
229
	 * 
230
	 * @return void
231
	 */
232
	public function setTemplateFile(string $layoutFile)
233
	{
234
		$this->setTemplateFilePath($layoutFile, self::TEMPLATE_CONFIRMER);
235
	}
236
237
	/**
238
	 * Generate unique token key
239
	 *
240
	 * @return string
241
	 */
242
	protected function generateToken() : string
243
	{
244 1
		return base_convert(md5(uniqid('confirm' . $this->getName(), TRUE)), 16, 36);
245
	}
246
247
	/**
248
	 * Get parent dialog control
249
	 *
250
	 * @return Control
251
	 *
252
	 * @throws Exceptions\InvalidStateException
253
	 */
254
	protected function getDialog() : Control
255
	{
256
		// Check if confirm dialog was loaded before...
257 1
		if (!$this->dialog) {
258
			// ...if not try to lookup for it
259 1
			$multiplier = $this->getParent();
260
261
			// Check if confirmer is in multiplier
262 1
			if ($multiplier instanceof Application\UI\Multiplier) {
263 1
				$this->dialog = $multiplier->getParent();
264
265
				// Check if parent is right
266 1
				if (!$this->dialog instanceof Control) {
267 1
					throw new Exceptions\InvalidStateException('Confirmer is not attached to parent control!');
268
				}
269
270
			} else {
271
				throw new Exceptions\InvalidStateException('Confirmer is not attached to multiplier!');
272
			}
273
		}
274
275 1
		return $this->dialog;
276
	}
277
}
278