BaseTag::__construct()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 18
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 9
c 1
b 0
f 0
nc 2
nop 4
dl 0
loc 18
rs 9.9666
1
<?php
2
3
namespace alekciy\ffd;
4
5
use Exception;
6
use InvalidArgumentException;
7
use Valitron\Validator;
8
9
abstract class BaseTag
10
{
11
	/** @var integer Тип документа, DocumentInterface::TYPE_* */
12
	public $documentType;
13
14
	/** @var string Формат документа, DocumentInterface::FORMAT_* */
15
	public $documentForm;
16
17
	/** @var string Версия ФФД документа, DocumentInterface::VERSION_* */
18
	public $documentVersion;
19
20
	/** @var mixed Значение тега */
21
	public $value;
22
23
	/**
24
	 * Текстовой идентификатор тега.
25
	 *
26
	 * @return string
27
	 * @throws Exception
28
	 */
29
	public static function getCode(): string
30
	{
31
		if (preg_match('~Tag(?<code>[0-9]{4})~u', static::class, $matches) === 1) {
32
			return $matches['code'];
33
		}
34
		throw new Exception('Название класса потомка должно соответствовать шаблону Tag[0-9]{4}');
35
	}
36
37
	/**
38
	 * Параметры инициализации, массив:
39
	 *   ключ - идентификатор тега;
40
	 *   значение - значение тега.
41
	 *
42
	 * @param array $init
43
	 * @return void
44
	 */
45
	abstract protected function init(array &$init);
46
47
	/**
48
	 * Правила валидации в виде массива в котором должен быть минимум один ключ 'value' для проверки свойства
49
	 * $this->value - значение тега и он должен быть обязательным.
50
	 * В потомках можно учитывать контекст типа документа ($this->documentType), формата ($this->documentForm) и версии
51
	 * ФФД ($this->documentVersion) для возврата разных правил валидации.
52
	 *
53
	 * @see https://github.com/vlucas/valitron#built-in-validation-rules
54
	 * @return array
55
	 */
56
	abstract protected function getRuleList(): array;
57
58
	/**
59
	 * @param int $documentType Тип документа.
60
	 * @param string $documentForm Формат документа.
61
	 * @param string $documentVersion Версия ФФД.
62
	 * @param array $init Параметры инициализации.
63
	 * @throws Exception
64
	 */
65
	public function __construct(
66
		int $documentType,
67
		string $documentForm,
68
		string $documentVersion,
69
		array &$init
70
	) {
71
		$this->documentType = $documentType;
72
		$this->documentForm = $documentForm;
73
		$this->documentVersion = $documentVersion;
74
		$this->validate($this->getBaseRuleList());
75
76
		$this->init($init);
77
78
		$tagRuleList = $this->getRuleList();
79
		if (!isset($tagRuleList['value'])) {
80
			throw new Exception('Метод ' . get_class($this) . '::getRuleList() должен возращать ключ value');
81
		}
82
		$this->validate($this->getRuleList());
83
	}
84
85
	/**
86
	 * Выполнить проверку корректности запроса.
87
	 *
88
	 * @see https://github.com/vlucas/valitron#built-in-validation-rules
89
	 * @param array $ruleList Правила валидации.
90
	 * @param string $lang Язык на котором выводятся сообщения с ошибками валидации.
91
	 * @return void
92
	 * @throws Exception
93
	 */
94
	protected function validate(array $ruleList, $lang = 'ru')
95
	{
96
		$methodName = get_class($this) == __CLASS__
97
			? 'getBaseRuleList()'
98
			: 'getRuleList()';
99
100
		Validator::lang($lang);
101
		$validator = new Validator(get_object_vars($this));
102
		try {
103
			$validator->mapFieldsRules($ruleList);
104
		} catch (InvalidArgumentException $e) {
105
			throw new Exception(get_class($this) . " ошибка в методе {$methodName}: " . $e->getMessage());
106
		}
107
		if (!$validator->validate()) {
108
			$messageList = [];
109
			foreach ($validator->errors() as  $propertyName => $errorList) {
110
				$messageList[] = get_class($this) . "::{$methodName}[{$propertyName}] " . implode(', ', $errorList);
111
			}
112
			throw new Exception(implode('. ', $messageList));
113
		}
114
	}
115
116
	/**
117
	 * Правила валидации в виде массива:
118
	 *   ключ - имя правила,
119
	 *   значение - массив с именами свойств для которых правило будет проверяться.
120
	 *
121
	 * @see https://github.com/vlucas/valitron#built-in-validation-rules
122
	 * @return array
123
	 */
124
	private function getBaseRuleList()
125
	{
126
		return [
127
			'documentType' => ['required', ['in', [
128
				DocumentInterface::TYPE_REGISTRATION,
129
				DocumentInterface::TYPE_OPEN,
130
				DocumentInterface::TYPE_CHECK,
131
				DocumentInterface::TYPE_STRICT,
132
				DocumentInterface::TYPE_CLOSE,
133
				DocumentInterface::TYPE_FN_CLOSE,
134
				DocumentInterface::TYPE_CONFIRMATION,
135
				DocumentInterface::TYPE_REGISTRATION_CHANGE,
136
				DocumentInterface::TYPE_STATE,
137
				DocumentInterface::TYPE_CHECK_CORRECT,
138
				DocumentInterface::TYPE_STRICT_CORRECT,
139
			]]],
140
			'documentForm' => ['required', ['in', [
141
				DocumentInterface::FORMAT_PRINT,
142
				DocumentInterface::FORMAT_ELECTRONIC,
143
			]]],
144
			'documentVersion' => ['required', ['in', [
145
				DocumentInterface::VERSION_1_05,
146
				DocumentInterface::VERSION_1_10,
147
			]]],
148
		];
149
	}
150
}