Completed
Push — master ( a87ba4...b6d929 )
by Adam
01:01
created

Control   B

Complexity

Total Complexity 36

Size/Duplication

Total Lines 298
Duplicated Lines 0 %

Coupling/Cohesion

Components 2
Dependencies 9

Test Coverage

Coverage 72.15%

Importance

Changes 20
Bugs 2 Features 5
Metric Value
wmc 36
c 20
b 2
f 5
lcom 2
cbo 9
dl 0
loc 298
ccs 57
cts 79
cp 0.7215
rs 8.8

15 Methods

Rating   Name   Duplication   Size   Complexity  
A getConfirmer() 0 8 4
A injectFactories() 0 5 1
A __construct() 0 16 3
A setLayoutFile() 0 6 1
A setTemplateFile() 0 6 1
A getTemplateFile() 0 5 2
A formatSignalMethod() 0 8 2
B addConfirmer() 0 22 5
A resetConfirmer() 0 9 1
A createComponentConfirmer() 0 23 3
A showConfirm() 0 13 4
A handleShowConfirmer() 0 20 3
A enableAjax() 0 6 1
A disableAjax() 0 6 1
B render() 0 24 4
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		5.0
11
 *
12
 * @date		12.03.14
13
 */
14
15
namespace IPub\ConfirmationDialog\Components;
16
17
use Nette;
18
use Nette\Application;
19
use Nette\Localization;
20
use Nette\Utils;
21
22
use IPub;
23
use IPub\ConfirmationDialog\Exceptions;
24
25
/**
26
 * Confirmation dialog control
27
 *
28
 * @package		iPublikuj:ConfirmationDialog!
29
 * @subpackage	Components
30
 */
31
class Control extends BaseControl
32 1
{
33
	const CLASSNAME = __CLASS__;
34
35
	/**
36
	 * @var IConfirmer
37
	 */
38
	protected $confirmerFactory;
39
40
	/**
41
	 * @var Confirmer
42
	 */
43
	protected $confirmer;
44
45
	/**
46
	 * @var bool
47
	 */
48
	protected $useAjax = TRUE;
49
50
	/**
51
	 * @param IConfirmer $confirmerFactory
52
	 */
53
	public function injectFactories(IConfirmer $confirmerFactory)
54
	{
55
		// Get confirmer component factory
56 1
		$this->confirmerFactory = $confirmerFactory;
57 1
	}
58
59
	/**
60
	 * @param NULL|string $layoutFile
61
	 * @param NULL|string $templateFile
62
	 * @param Nette\ComponentModel\IContainer $parent
63
	 * @param null $name
64
	 */
65
	public function __construct(
66
		$layoutFile = NULL,
67
		$templateFile = NULL,
68
		Nette\ComponentModel\IContainer $parent = NULL, $name = NULL
0 ignored issues
show
Unused Code introduced by
The parameter $parent is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $name is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
69
	) {
70
		// TODO: remove, only for tests
71 1
		parent::__construct(NULL, NULL);
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 $this
88
	 */
89
	public function setLayoutFile($layoutFile)
90
	{
91 1
		$this->setTemplateFilePath($layoutFile, self::TEMPLATE_LAYOUT);
92
93
		return $this;
94
	}
95
96
	/**
97
	 * Change default confirmer template path
98
	 *
99
	 * @param string $layoutFile
100
	 *
101
	 * @return $this
102
	 */
103
	public function setTemplateFile($layoutFile)
104
	{
105 1
		$this->setTemplateFilePath($layoutFile, self::TEMPLATE_CONFIRMER);
106
107 1
		return $this;
108
	}
109
110
	/**
111
	 * @return string
112
	 */
113
	public function getTemplateFile()
114
	{
115
		// ...try to get default component layout file
116 1
		return !empty($this->templateFile) ? $this->templateFile : __DIR__ . DIRECTORY_SEPARATOR .'template'. DIRECTORY_SEPARATOR .'default.latte';
117
	}
118
119
	/**
120
	 * Overrides signal method formatter
121
	 * This provide "dynamically named signals"
122
	 *
123
	 * @param string $signal
124
	 *
125
	 * @return string
126
	 */
127
	public static function formatSignalMethod($signal)
128
	{
129 1
		if (Utils\Strings::startsWith($signal, 'confirm')) {
130 1
			return 'handleShowConfirmer';
131
		}
132
133
		return parent::formatSignalMethod($signal);
134
	}
135
136
	/**
137
	 * Add confirmation handler to "dynamicaly named signals"
138
	 *
139 1
	 * @param string $name Confirmation/signal name
140
	 * @param callback|Nette\Callback $handler Callback called when confirmation succeed
141
	 * @param callback|string $question Callback ($confirmer, $params) or string containing question text
142
	 * @param callback|string $heading Callback ($confirmer, $params) or string containing heading text
143
	 *
144
	 * @return $this
145
	 *
146 1
	 * @throws Exceptions\InvalidArgumentException
147
	 */
148
	public function addConfirmer($name, $handler, $question, $heading)
149
	{
150
		// Confirmer name could be only A-z
151 1
		if (!preg_match('/[A-Za-z_]+/', $name)) {
152
			throw new Exceptions\InvalidArgumentException("Confirmation control name contain invalid characters.");
153
154
		// Check confirmer
155 1
		} else if ((!$confirmer = $this->getComponent('confirmer-'. $name)) || !$confirmer instanceof Confirmer || $confirmer->isConfigured()) {
156
			throw new Exceptions\InvalidArgumentException("Confirmation control '$name' could not be created.");
157
158
		} else {
159
			$confirmer
160
				// Set confirmer handler
161 1
				->setHandler($handler)
162
				// Set confirmer heading
163 1
				->setHeading($heading)
164
				// Set confirmer question
165 1
				->setQuestion($question);
166
		}
167
168 1
		return $this;
169
	}
170
171
	/**
172
	 * @param string $name
173
	 *
174
	 * @return Confirmer
175
	 *
176
	 * @throws Exceptions\InvalidArgumentException
177
	 */
178
	public function getConfirmer($name)
179
	{
180
		if ((!$confirmer = $this->getComponent('confirmer-'. $name)) || !$confirmer instanceof Confirmer || !$confirmer->isConfigured()) {
181
			throw new Exceptions\InvalidArgumentException("Confirmation control '$name' does not exists.");
182
		}
183
184
		return $confirmer;
185
	}
186
187
	/**
188
	 * @return $this
189
	 */
190
	public function resetConfirmer()
191
	{
192 1
		$this->confirmer = NULL;
193
194
		// Invalidate dialog snippets
195 1
		$this->redrawControl();
196
197 1
		return $this;
198
	}
199
200
	/**
201
	 * @return Application\UI\Multiplier
202
	 *
203
	 * @throws Exceptions\InvalidArgumentException
204
	 */
205
	protected function createComponentConfirmer()
206
	{
207 1
		$that = $this;
208
209 1
		return new Application\UI\Multiplier((function() use ($that) {
210
			// Check if confirmer factory is available
211 1
			if ($that->confirmerFactory) {
212 1
				$confirmer = $that->confirmerFactory->create($that->templateFile);
213
214 1
			} else {
215
				throw new Exceptions\InvalidStateException("Confirmation control factory does not exist.");
216
			}
217
218 1
			if ($that->useAjax) {
219 1
				$confirmer->enableAjax();
220
221 1
			} else {
222
				$confirmer->disableAjax();
223
			}
224
225 1
			return $confirmer;
226 1
		}));
227
	}
228
229
	/**
230
	 * Show dialog for confirmation
231
	 *
232
	 * @param string $name
233
	 * @param array $params
234
	 *
235
	 * @throws Exceptions\InvalidArgumentException
236
	 * @throws Exceptions\InvalidStateException
237
	 */
238
	public function showConfirm($name, array $params = [])
239
	{
240 1
		if (!is_string($name)) {
241
			throw new Exceptions\InvalidArgumentException('$name must be string.');
242
		}
243
244 1
		if ((!$this->confirmer = $this['confirmer-'. $name]) || !$this->confirmer->isConfigured()) {
245
			throw new Exceptions\InvalidStateException("Confirmer '$name' do not exist.");
246
		}
247
248
		// Prepare confirmer for displaying
249 1
		$this->confirmer->showConfirm($params);
250 1
	}
251
252
	/**
253
	 * Dynamically named signal receiver
254
	 *
255
	 * @throws Exceptions\InvalidArgumentException
256
	 * @throws Exceptions\InvalidStateException
257
	 */
258
	public function handleShowConfirmer()
259
	{
260 1
		if ($this->getPresenter() instanceof Application\UI\Presenter) {
261 1
			list(, $signal) = $this->getPresenter()->getSignal();
262
263 1
		} else {
264
			throw new Exceptions\InvalidArgumentException('Confirmer is not attached to presenter.');
265
		}
266
267 1
		$name = Utils\Strings::substring($signal, 7);
268 1
		$name{0} = strtolower($name{0});
269
270 1
		if (!$this['confirmer-'. $name]->isConfigured()) {
271
			throw new Exceptions\InvalidArgumentException('Invalid confirmation control.');
272
		}
273
274 1
		$params = $this->getParameters();
275
276 1
		$this->showConfirm($name, $params);
277 1
	}
278
279
	/**
280
	 * @return $this
281
	 */
282
	public function enableAjax()
283
	{
284
		$this->useAjax = TRUE;
285
286
		return $this;
287
	}
288
289
	/**
290
	 * @return $this
291
	 */
292
	public function disableAjax()
293
	{
294
		$this->useAjax = FALSE;
295
296
		return $this;
297
	}
298
299
	/**
300
	 * Render control
301
	 *
302
	 * @throws Exceptions\InvalidStateException
303
	 */
304
	public function render()
305
	{
306
		// Create template
307 1
		$template = parent::render();
308
309
		// Check if control has template
310 1
		if ($template instanceof Nette\Bridges\ApplicationLatte\Template) {
311
			// Assign vars to template
312 1
			$template->confirmer = $this->confirmer;
313
314
			// If template was not defined before...
315 1
			if ($template->getFile() === NULL) {
316
				// ...try to get base component template file
317 1
				$layoutFile = !empty($this->layoutFile) ? $this->layoutFile : __DIR__ . DIRECTORY_SEPARATOR . 'template' . DIRECTORY_SEPARATOR . 'layout.latte';
318 1
				$template->setFile($layoutFile);
319 1
			}
320
321
			// Render component template
322 1
			$template->render();
323
324 1
		} else {
325
			throw new Exceptions\InvalidStateException('Dialog control is without template.');
326
		}
327 1
	}
328
}
329