TBaseValidator::setEnableClientScript()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
eloc 1
c 0
b 0
f 0
nc 1
nop 1
dl 0
loc 3
ccs 0
cts 1
cp 0
crap 2
rs 10
1
<?php
2
3
/**
4
 * TBaseValidator class file
5
 *
6
 * @author Qiang Xue <[email protected]>
7
 * @link https://github.com/pradosoft/prado
8
 * @license https://github.com/pradosoft/prado/blob/master/LICENSE
9
 */
10
11
namespace Prado\Web\UI\WebControls;
12
13
use Prado\Exceptions\TConfigurationException;
14
use Prado\Exceptions\TNotSupportedException;
15
use Prado\TPropertyValue;
16
use Prado\Exceptions\TInvalidDataTypeException;
17
use Prado\Web\Javascripts\TJavaScript;
18
use Prado\Web\UI\IValidator;
19
20
/**
21
 * TBaseValidator class
22
 *
23
 * TBaseValidator serves as the base class for validator controls.
24
 *
25
 * Validation is performed when a postback control, such as a TButton, a TLinkButton
26
 * or a TTextBox (under AutoPostBack mode) is submitting the page and
27
 * its <b>CausesValidation</b> property is true.
28
 * You can also manually perform validation by calling {@see \Prado\Web\UI\TPage::validate()}.
29
 * The input control to be validated is specified by {@see setControlToValidate ControlToValidate}.
30
 *
31
 * Validator controls always validate the associated input control on the serve side.
32
 * In addition, if {@see getEnableClientScript EnableClientScript} is true,
33
 * validation will also be performed on the client-side using javascript.
34
 * Client-side validation will validate user input before it is sent to the server.
35
 * The form data will not be submitted if any error is detected. This avoids
36
 * the round-trip of information necessary for server-side validation.
37
 *
38
 * You can use multiple validator controls to validate a single input control,
39
 * each responsible for validating against a different criteria.
40
 * For example, on a user registration form, you may want to make sure the user
41
 * enters a value in the username text box, and the input must consist of only word
42
 * characters. You can use a {@see \Prado\Web\UI\WebControls\TRequiredFieldValidator} to ensure the input
43
 * of username and a {@see \Prado\Web\UI\WebControls\TRegularExpressionValidator} to ensure the proper input.
44
 *
45
 * If an input control fails validation, the text specified by the {@see setErrorMessage ErrorMessage}
46
 * property is displayed in the validation control. However, if the {@see setText Text}
47
 * property is set, it will be displayed instead. If both {@see setErrorMessage ErrorMessage}
48
 * and {@see setText Text} are empty, the body content of the validator will
49
 * be displayed. Error display is controlled by {@see setDisplay Display} property.
50
 *
51
 * You can also customized the client-side behaviour by adding javascript
52
 * code to the subproperties of the {@see getClientSide ClientSide}
53
 * property. See quickstart documentation for further details.
54
 *
55
 * You can also place a {@see \Prado\Web\UI\WebControls\TValidationSummary} control on a page to display error messages
56
 * from the validators together. In this case, only the {@see setErrorMessage ErrorMessage}
57
 * property of the validators will be displayed in the {@see \Prado\Web\UI\WebControls\TValidationSummary} control.
58
 *
59
 * Validators can be partitioned into validation groups by setting their
60
 * {@see setValidationGroup ValidationGroup} property. If the control causing the
61
 * validation also sets its ValidationGroup property, only those validators having
62
 * the same ValidationGroup value will do input validation.
63
 *
64
 * Note, the {@see \Prado\Web\UI\TPage::getIsValid IsValid} property of the current {@see \Prado\Web\UI\TPage}
65
 * instance will be automatically updated by the validation process which occurs
66
 * after {@see \Prado\Web\UI\TPage::onLoad onLoad} of {@see \Prado\Web\UI\TPage} and before the postback events.
67
 * Therefore, if you use the {@see \Prado\Web\UI\TPage::getIsValid()} property in
68
 * the {@see \Prado\Web\UI\TPage::onLoad()} method, you must first explicitly call
69
 * the {@see \Prado\Web\UI\TPage::validate()} method.
70
 *
71
 * <b>Notes to Inheritors</b>  When you inherit from TBaseValidator, you must
72
 * override the method {@see evaluateIsValid}.
73
 *
74
 * @author Qiang Xue <[email protected]>
75
 * @since 3.0
76
 */
77
abstract class TBaseValidator extends TLabel implements IValidator
78
{
79
	/**
80
	 * @var bool whether the validation succeeds
81
	 */
82
	private $_isValid = true;
83
	/**
84
	 * @var bool whether the validator has been registered with the page
85
	 */
86
	private $_registered = false;
87
	/**
88
	 * @var TValidatorClientSide validator client-script options.
89
	 */
90
	private $_clientSide;
91
	/**
92
	 * Controls for which the client-side validation3.js file needs to handle
93
	 * them specially.
94
	 * @var array list of control class names
95
	 */
96
	private static $_clientClass = [
97
		// normal controls needing special handling to extract their values
98
		\Prado\Web\UI\WebControls\TCheckBox::class => 'TCheckBox',
99
		\Prado\Web\UI\WebControls\TDatePicker::class => 'TDatePicker',
100
		\Prado\Web\UI\WebControls\THtmlArea::class => 'THtmlArea',
101
		\Prado\Web\UI\WebControls\THtmlArea5::class => 'THtmlArea5',
102
		\Prado\Web\UI\WebControls\TReCaptcha2::class => 'TReCaptcha2',
103
		// list controls
104
		\Prado\Web\UI\WebControls\TCheckBoxList::class => 'TCheckBoxList',
105
		\Prado\Web\UI\WebControls\TListBox::class => 'TListBox',
106
		\Prado\Web\UI\WebControls\TRadioButton::class => 'TRadioButton',
107
	];
108
109
	/**
110
	 * Constructor.
111
	 * This method sets the foreground color to red.
112
	 */
113
	public function __construct()
114 1
	{
115
		parent::__construct();
116 1
		$this->setForeColor('red');
117 1
	}
118 1
119
	/**
120
	 * Registers the validator with page.
121
	 * @param mixed $param event parameter
122
	 */
123
	public function onInit($param)
124
	{
125
		parent::onInit($param);
126
		$this->getPage()->getValidators()->add($this);
127
		$this->_registered = true;
128
	}
129
130
	/**
131
	 * Unregisters the validator from page.
132
	 * @param mixed $param event parameter
133
	 */
134
	public function onUnload($param)
135
	{
136
		if ($this->_registered && ($page = $this->getPage()) !== null) {
137
			$page->getValidators()->remove($this);
138
		}
139
		$this->_registered = false;
140
		parent::onUnload($param);
141
	}
142
143
	/**
144
	 * Adds attributes to renderer. Calls parent implementation and renders the
145
	 * client control scripts.
146
	 * @param \Prado\Web\UI\THtmlWriter $writer the renderer
147
	 */
148
	protected function addAttributesToRender($writer)
149
	{
150
		$display = $this->getDisplay();
151
		$visible = $this->getEnabled(true) && !$this->getIsValid();
152
		if ($display === TValidatorDisplayStyle::None || (!$visible && $display === TValidatorDisplayStyle::Dynamic)) {
0 ignored issues
show
introduced by
The condition $display === Prado\Web\U...orDisplayStyle::Dynamic is always false.
Loading history...
153
			$writer->addStyleAttribute('display', 'none');
154
		} elseif (!$visible) {
155
			$writer->addStyleAttribute('visibility', 'hidden');
156
		}
157
		$writer->addAttribute('id', $this->getClientID());
158
		parent::addAttributesToRender($writer);
159
		$this->renderClientControlScript($writer);
160
	}
161
162
	/**
163
	 * Returns an array of javascript validator options.
164
	 * @return array javascript validator options.
165
	 */
166
	protected function getClientScriptOptions()
167
	{
168
		$control = $this->getValidationTarget();
169
		$options['ID'] = $this->getClientID();
0 ignored issues
show
Comprehensibility Best Practice introduced by
$options was never initialized. Although not strictly required by PHP, it is generally a good practice to add $options = array(); before regardless.
Loading history...
170
		$options['FormID'] = $this->getPage()->getForm()->getClientID();
171
		$options['Display'] = $this->getDisplay();
172
		$options['ErrorMessage'] = $this->getErrorMessage();
173
		if ($this->getFocusOnError()) {
174
			$options['FocusOnError'] = $this->getFocusOnError();
175
			$options['FocusElementID'] = $this->getFocusElementID();
176
		}
177
		$options['ValidationGroup'] = $this->getValidationGroup();
178
		if ($control) {
0 ignored issues
show
introduced by
$control is of type Prado\Web\UI\TControl, thus it always evaluated to true.
Loading history...
179
			$options['ControlToValidate'] = $control->getClientID();
180
		}
181
		$options['ControlCssClass'] = $this->getControlCssClass();
182
183
		$options['ControlType'] = $this->getClientControlClass($control);
184
		$options['Enabled'] = $this->getEnabled(true);
185
186
		//get date format from date picker target control
187
		if ($control instanceof TDatePicker) {
188
			$options['DateFormat'] = $control->getDateFormat();
189
		}
190
191
		$options = array_merge($options, $this->getClientSide()->getOptions()->toArray());
192
193
		return $options;
194
	}
195
196
	/**
197
	 * Gets the Control type for client-side validation. If new cases exists in
198
	 * TBaseValidator::$_clientClass, be sure to update the corresponding
199
	 * "Javascript/validation3.js" file as well.
200
	 * @param \Prado\Web\UI\TControl $control control to validate.
201
	 * @return string control type for client-side validation.
202
	 */
203
	private function getClientControlClass($control)
204
	{
205
		foreach (self::$_clientClass as $fullName => $shortName) {
206
			if ($control instanceof $fullName) {
207
				return $shortName;
208
			}
209
		}
210
		$reflectionClass = new \ReflectionClass($control);
211
		return $reflectionClass->getShortName();
212
	}
213
214
	/**
215
	 * Gets the TValidatorClientSide that allows modification of the client-
216
	 * side validator events.
217
	 *
218
	 * The client-side validator supports the following events.
219
	 * # <tt>OnValidate</tt> -- raised before client-side validation is
220
	 * executed.
221
	 * # <tt>OnValidationSuccess</tt> -- raised after client-side validation is completed
222
	 * and is successfull, overrides default validator error messages updates.
223
	 * # <tt>OnValidationError</tt> -- raised after client-side validation is completed
224
	 * and failed, overrides default validator error message updates.
225
	 *
226
	 * You can attach custom javascript code to each of these events
227
	 *
228
	 * @return TValidatorClientSide javascript validator event options.
229
	 */
230
	public function getClientSide()
231
	{
232
		if ($this->_clientSide === null) {
233
			$this->_clientSide = $this->createClientSide();
234
		}
235
		return $this->_clientSide;
236
	}
237
238
	/**
239
	 * @return TValidatorClientSide javascript validator event options.
240
	 */
241
	protected function createClientSide()
242
	{
243
		return new TValidatorClientSide();
244
	}
245
246
	/**
247
	 * Renders the javascript code to the end script.
248
	 * If you override this method, be sure to call the parent implementation
249
	 * so that the event handlers can be invoked.
250
	 * @param \Prado\Web\UI\THtmlWriter $writer the renderer
251
	 */
252
	public function renderClientControlScript($writer)
0 ignored issues
show
Unused Code introduced by
The parameter $writer is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

252
	public function renderClientControlScript(/** @scrutinizer ignore-unused */ $writer)

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

Loading history...
253
	{
254
		$scripts = $this->getPage()->getClientScript();
255
		if ($this->getEnableClientScript()) {
256
			$scripts->registerPradoScript('validator');
257
		}
258
		$formID = $this->getPage()->getForm()->getClientID();
259
		$scriptKey = "TBaseValidator:$formID";
260
		if ($this->getEnableClientScript() && !$scripts->isEndScriptRegistered($scriptKey)) {
261
			$manager['FormID'] = $formID;
0 ignored issues
show
Comprehensibility Best Practice introduced by
$manager was never initialized. Although not strictly required by PHP, it is generally a good practice to add $manager = array(); before regardless.
Loading history...
262
			$options = TJavaScript::encode($manager);
263
			$scripts->registerEndScript($scriptKey, "new Prado.ValidationManager({$options});");
264
		}
265
		if ($this->getEnableClientScript()) {
266
			$this->registerClientScriptValidator();
267
		}
268
	}
269
270
	/**
271
	 * Override parent implementation to update the control CSS Class before
272
	 * the validated control is rendered
273
	 * @param mixed $param
274
	 */
275
	public function onPreRender($param)
276
	{
277
		parent::onPreRender($param);
278
		$this->updateControlCssClass();
279
	}
280
281
	/**
282
	 * Update the ControlToValidate component's css class depending
283
	 * if the ControlCssClass property is set, and whether this is valid.
284
	 */
285
	protected function updateControlCssClass()
286
	{
287
		if (($cssClass = $this->getControlCssClass()) !== '') {
288
			$control = $this->getValidationTarget();
289
			if ($control instanceof TWebControl) {
290
				$class = preg_replace('/ ' . preg_quote($cssClass) . '/', '', $control->getCssClass());
291
				if (!$this->getIsValid()) {
292
					$class .= ' ' . $cssClass;
293
					$control->setCssClass($class);
294
				} elseif ($control instanceof \Prado\Web\UI\IValidatable && $control->getIsValid()) {
0 ignored issues
show
Bug introduced by
The method getIsValid() does not exist on Prado\Web\UI\WebControls\TWebControl. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

294
				} elseif ($control instanceof \Prado\Web\UI\IValidatable && $control->/** @scrutinizer ignore-call */ getIsValid()) {
Loading history...
295
					$control->setCssClass($class);
296
				}
297
			}
298
		}
299
	}
300
301
	/**
302
	 * Registers the individual validator client-side javascript code.
303
	 */
304
	protected function registerClientScriptValidator()
305
	{
306
		$key = 'prado:' . $this->getClientID();
307
		if (!$this->getPage()->getClientScript()->isEndScriptRegistered($key)) {
308
			$options = TJavaScript::encode($this->getClientScriptOptions());
309
			$script = 'new ' . $this->getClientClassName() . '(' . $options . ');';
310
			$this->getPage()->getClientScript()->registerEndScript($key, $script);
311
		}
312
	}
313
314
	/**
315
	 * Gets the name of the javascript class responsible for performing validation for this control.
316
	 * This method overrides the parent implementation.
317
	 * @return string the javascript class name
318
	 */
319
	abstract protected function getClientClassName();
320
321
	/**
322
	 * This method overrides the parent implementation to forbid setting ForControl.
323
	 * @param string $value the associated control ID
324
	 * @throws TNotSupportedException whenever this method is called
325
	 */
326
	public function setForControl($value)
327
	{
328
		throw new TNotSupportedException('basevalidator_forcontrol_unsupported', $this::class);
329
	}
330
331
	/**
332
	 * This method overrides parent's implementation by setting {@see setIsValid IsValid} to true if disabled.
333
	 * @param bool $value whether the validator is enabled.
334
	 */
335
	public function setEnabled($value)
336
	{
337
		$value = TPropertyValue::ensureBoolean($value);
338
		parent::setEnabled($value);
339
		if (!$value) {
340
			$this->_isValid = true;
341
		}
342
	}
343
344
	/**
345
	 * @return TValidatorDisplayStyle the style of displaying the error message. Defaults to TValidatorDisplayStyle::Fixed.
346
	 */
347
	public function getDisplay()
348
	{
349
		return $this->getViewState('Display', TValidatorDisplayStyle::Fixed);
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->getViewSta...torDisplayStyle::Fixed) also could return the type string which is incompatible with the documented return type Prado\Web\UI\WebControls\TValidatorDisplayStyle.
Loading history...
350
	}
351
352
	/**
353
	 * @param TValidatorDisplayStyle $value the style of displaying the error message
354
	 */
355
	public function setDisplay($value)
356
	{
357
		$this->setViewState('Display', TPropertyValue::ensureEnum($value, TValidatorDisplayStyle::class), TValidatorDisplayStyle::Fixed);
358
	}
359
360
	/**
361
	 * @return bool whether client-side validation is enabled.
362
	 */
363
	public function getEnableClientScript()
364
	{
365
		return $this->getViewState('EnableClientScript', true);
366
	}
367
368
	/**
369
	 * @param bool $value whether client-side validation is enabled.
370
	 */
371
	public function setEnableClientScript($value)
372
	{
373
		$this->setViewState('EnableClientScript', TPropertyValue::ensureBoolean($value), true);
374
	}
375
376
	/**
377
	 * @return string the text for the error message.
378
	 */
379
	public function getErrorMessage()
380
	{
381
		return $this->getViewState('ErrorMessage', '');
382
	}
383
384
	/**
385
	 * Sets the text for the error message.
386
	 * @param string $value the error message
387
	 */
388
	public function setErrorMessage($value)
389
	{
390
		$this->setViewState('ErrorMessage', $value, '');
391
	}
392
393
	/**
394
	 * @return string the ID path of the input control to validate
395
	 */
396
	public function getControlToValidate()
397
	{
398 1
		return $this->getViewState('ControlToValidate', '');
399
	}
400 1
401
	/**
402
	 * Sets the ID path of the input control to validate.
403
	 * The ID path is the dot-connected IDs of the controls reaching from
404
	 * the validator's naming container to the target control.
405
	 * @param string $value the ID path
406
	 */
407
	public function setControlToValidate($value)
408
	{
409
		$this->setViewState('ControlToValidate', $value, '');
410
	}
411
412
	/**
413
	 * @return bool whether to set focus at the validating place if the validation fails. Defaults to false.
414
	 */
415
	public function getFocusOnError()
416
	{
417
		return $this->getViewState('FocusOnError', false);
418
	}
419
420
	/**
421
	 * @param bool $value whether to set focus at the validating place if the validation fails
422
	 */
423
	public function setFocusOnError($value)
424
	{
425
		$this->setViewState('FocusOnError', TPropertyValue::ensureBoolean($value), false);
426
	}
427
428
	/**
429
	 * Gets the ID of the HTML element that will receive focus if validation fails and {@see getFocusOnError FocusOnError} is true.
430
	 * Defaults to the client ID of the {@see getControlToValidate ControlToValidate}.
431
	 * @return string the ID of the HTML element to receive focus
432
	 */
433
	public function getFocusElementID()
434
	{
435
		if (($id = $this->getViewState('FocusElementID', '')) === '') {
436
			$target = $this->getValidationTarget();
437
			/* Workaround: TCheckBoxList and TRadioButtonList nests the actual
438
			 * inputs inside a table; we ensure the first input gets focused
439
			 */
440
			if ($target instanceof TCheckBoxList && $target->getItemCount() > 0) {
441
				$id = $target->getClientID() . '_c0';
442
			} else {
443
				$id = $target->getClientID();
444
			}
445
		}
446
		return $id;
447
	}
448
449
	/**
450
	 * Sets the ID of the HTML element that will receive focus if validation fails and {@see getFocusOnError FocusOnError} is true.
451
	 * @param string $value the ID of the HTML element to receive focus
452
	 */
453
	public function setFocusElementID($value)
454
	{
455
		$this->setViewState('FocusElementID', $value, '');
456
	}
457
458
	/**
459
	 * @return string the group which this validator belongs to
460
	 */
461
	public function getValidationGroup()
462
	{
463
		return $this->getViewState('ValidationGroup', '');
464
	}
465
466
	/**
467
	 * @param string $value the group which this validator belongs to
468
	 */
469
	public function setValidationGroup($value)
470
	{
471
		$this->setViewState('ValidationGroup', $value, '');
472
	}
473
474
	/**
475
	 * @return bool whether the validation succeeds
476
	 */
477
	public function getIsValid()
478
	{
479
		return $this->_isValid;
480
	}
481
482
	/**
483
	 * Sets the value indicating whether the validation succeeds
484
	 * @param bool $value whether the validation succeeds
485
	 */
486
	public function setIsValid($value)
487
	{
488
		$this->_isValid = TPropertyValue::ensureBoolean($value);
489
	}
490
491
	/**
492
	 * @throws TConfigurationException if {@see getControlToValidate
493
	 * ControlToValidate} is empty or does not point to a valid control
494
	 * @return \Prado\Web\UI\TControl control to be validated. Null if no control is found.
495
	 */
496
	public function getValidationTarget()
497
	{
498 1
		if (($id = $this->getControlToValidate()) !== '' && ($control = $this->findControl($id)) !== null) {
499
			return $control;
500 1
		} else {
501
			throw new TConfigurationException('basevalidator_controltovalidate_invalid', $this::class);
502
		}
503 1
	}
504
505
	/**
506
	 * Retrieves the property value of the control being validated.
507
	 * @param \Prado\Web\UI\TControl $control control being validated
508
	 * @throws TInvalidDataTypeException if the control to be validated does not implement {@see \Prado\Web\UI\IValidatable}.
509
	 * @return string property value to be validated
510
	 */
511
	protected function getValidationValue($control)
512
	{
513
		if ($control instanceof \Prado\Web\UI\IValidatable) {
514
			return $control->getValidationPropertyValue();
0 ignored issues
show
Bug introduced by
The method getValidationPropertyValue() does not exist on Prado\Web\UI\TControl. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

514
			return $control->/** @scrutinizer ignore-call */ getValidationPropertyValue();
Loading history...
515
		} else {
516
			throw new TInvalidDataTypeException('basevalidator_validatable_required', $this::class);
517
		}
518
	}
519
520
	/**
521
	 * Validates the specified control.
522
	 * Do not override this method. Override {@see evaluateIsValid} instead.
523
	 * @return bool whether the validation succeeds
524
	 */
525
	public function validate()
526
	{
527
		$this->onValidate();
528
		if ($this->getVisible(true) && $this->getEnabled(true)) {
529
			$target = $this->getValidationTarget();
530
			// if the target is not a disabled web control
531
			if ($target === null ||
532
				($target !== null &&
533
				!($target instanceof TWebControl && !$target->getEnabled(true)))) {
534
				if ($this->evaluateIsValid()) {
535
					$this->setIsValid(true);
536
					$this->onValidationSuccess();
537
				} else {
538
					if ($target && $target instanceof \Prado\Web\UI\IValidatable) {
539
						$target->setIsValid(false);
0 ignored issues
show
Bug introduced by
The method setIsValid() does not exist on Prado\Web\UI\TControl. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

539
						$target->/** @scrutinizer ignore-call */ 
540
               setIsValid(false);
Loading history...
540
					}
541
					$this->setIsValid(false);
542
					$this->onValidationError();
543
				}
544
			} else {
545
				$this->evaluateIsValid();
546
				$this->setIsValid(true);
547
				$this->onValidationSuccess();
548
			}
549
		} else {
550
			$this->setIsValid(true);
551
		}
552
		return $this->getIsValid();
553
	}
554
555
	/**
556
	 * @return string the css class that is applied to the control being validated in case the validation fails
557
	 */
558
	public function getControlCssClass()
559
	{
560
		return $this->getViewState('ControlCssClass', '');
561
	}
562
563
	/**
564
	 * @param string $value the css class that is applied to the control being validated in case the validation fails
565
	 */
566
	public function setControlCssClass($value)
567
	{
568
		$this->setViewState('ControlCssClass', $value, '');
569
	}
570
571
	/**
572
	 * This is the major method for validation.
573
	 * Derived classes should implement this method to provide customized validation.
574
	 * @return bool whether the validation succeeds
575
	 */
576
	abstract protected function evaluateIsValid();
577
578
	/**
579
	 * This event is raised when the validator succeeds in validation.
580
	 */
581
	public function onValidationSuccess()
582
	{
583
		$this->raiseEvent('OnValidationSuccess', $this, null);
584
	}
585
586
	/**
587
	 * This event is raised when the validator fails in validation.
588
	 */
589
	public function onValidationError()
590
	{
591
		$this->raiseEvent('OnValidationError', $this, null);
592
	}
593
594
	/**
595
	 * This event is raised right before the validator starts to perform validation.
596
	 * You may use this event to change the behavior of validation.
597
	 * For example, you may disable the validator if certain condition is satisfied.
598
	 * Note, the event will NOT be raised if the validator is invisible.
599
	 */
600
	public function onValidate()
601
	{
602
		$this->raiseEvent('OnValidate', $this, null);
603
	}
604
605
	/**
606
	 * Renders the validator control.
607
	 * @param \Prado\Web\UI\THtmlWriter $writer writer for the rendering purpose
608
	 */
609
	public function renderContents($writer)
610
	{
611
		if (($text = $this->getText()) !== '') {
612
			$writer->write($text);
613
		} elseif (($text = $this->getErrorMessage()) !== '') {
614
			$writer->write($text);
615
		} else {
616
			parent::renderContents($writer);
617
		}
618
	}
619
}
620