Нет описания

ApiDataSanitizer.php 5.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. <?php
  2. namespace MailPoet\CustomFields;
  3. if (!defined('ABSPATH')) exit;
  4. use InvalidArgumentException;
  5. use MailPoet\Models\CustomField;
  6. class ApiDataSanitizer {
  7. const ERROR_MANDATORY_ARGUMENT_MISSING = 1001;
  8. const ERROR_MANDATORY_ARGUMENT_WRONG_TYPE = 1002;
  9. const ERROR_PARAMS_WRONG_TYPE = 1003;
  10. const ERROR_INVALID_TYPE = 1004;
  11. const ERROR_INVALID_VALIDATE = 1005;
  12. const ERROR_CHECKBOX_WRONG_VALUES_COUNT = 1006;
  13. const ERROR_INVALID_DATE_FORMAT = 1007;
  14. const ERROR_INVALID_DATE_TYPE = 1008;
  15. const ERROR_NO_VALUES = 1009;
  16. const ERROR_NO_VALUE = 1010;
  17. public function sanitize(array $data = []) {
  18. $this->checkMandatoryStringParameter($data, 'name');
  19. $this->checkMandatoryStringParameter($data, 'type');
  20. $this->checkParamsType($data);
  21. return [
  22. 'name' => $data['name'],
  23. 'type' => strtolower($data['type']),
  24. 'params' => $this->sanitizeParams($data),
  25. ];
  26. }
  27. private function checkMandatoryStringParameter(array $data, $parameterName) {
  28. if (empty($data[$parameterName])) {
  29. throw new InvalidArgumentException(sprintf(__('Mandatory argument "%s" is missing', 'mailpoet'), $parameterName), self::ERROR_MANDATORY_ARGUMENT_MISSING);
  30. }
  31. if (!is_string($data[$parameterName])) {
  32. throw new InvalidArgumentException(sprintf(__('Mandatory argument "%s" has to be string', 'mailpoet'), $parameterName), self::ERROR_MANDATORY_ARGUMENT_WRONG_TYPE);
  33. }
  34. }
  35. private function checkParamsType($data) {
  36. if (isset($data['params']) && !is_array($data['params'])) {
  37. throw new InvalidArgumentException(sprintf(__('Params has to be array', 'mailpoet')), self::ERROR_PARAMS_WRONG_TYPE);
  38. }
  39. }
  40. private function sanitizeParams($data) {
  41. $data['params'] = isset($data['params']) ? $data['params'] : [];
  42. $result = [];
  43. $result['required'] = $this->getRequired($data['params']);
  44. $result['label'] = $this->getLabel($data);
  45. return $result + $this->getExtraParams($data);
  46. }
  47. private function getLabel($data) {
  48. if (empty($data['params']['label'])) {
  49. return $data['name'];
  50. } else {
  51. return $data['params']['label'];
  52. }
  53. }
  54. private function getRequired($params) {
  55. if (isset($params['required']) && $params['required']) {
  56. return '1';
  57. }
  58. return '';
  59. }
  60. private function getExtraParams($data) {
  61. $type = strtolower($data['type']);
  62. if (in_array($type, [CustomField::TYPE_TEXT, CustomField::TYPE_TEXTAREA], true)) {
  63. return $this->getExtraParamsForText($data['params']);
  64. }
  65. if (in_array($type, [CustomField::TYPE_RADIO, CustomField::TYPE_SELECT], true)) {
  66. return $this->getExtraParamsForSelect($data['params']);
  67. }
  68. if ($type === CustomField::TYPE_CHECKBOX) {
  69. return $this->getExtraParamsForCheckbox($data['params']);
  70. }
  71. if ($type === CustomField::TYPE_DATE) {
  72. return $this->getExtraParamsForDate($data['params']);
  73. }
  74. throw new InvalidArgumentException(sprintf(__('Invalid type "%s"', 'mailpoet'), $type), self::ERROR_INVALID_TYPE);
  75. }
  76. private function getExtraParamsForText($params) {
  77. if (isset($params['validate'])) {
  78. $validate = trim(strtolower($params['validate']));
  79. if (in_array($validate, ['number', 'alphanum', 'phone'], true)) {
  80. return ['validate' => $validate];
  81. }
  82. throw new InvalidArgumentException(__('Validate parameter is not valid', 'mailpoet'), self::ERROR_INVALID_VALIDATE);
  83. }
  84. return [];
  85. }
  86. private function getExtraParamsForCheckbox($params) {
  87. if (empty($params['values']) || count($params['values']) > 1) {
  88. throw new InvalidArgumentException(__('You need to pass exactly one value for checkbox', 'mailpoet'), self::ERROR_CHECKBOX_WRONG_VALUES_COUNT);
  89. }
  90. $value = reset($params['values']);
  91. return ['values' => [$this->sanitizeValue($value)]];
  92. }
  93. private function getExtraParamsForDate($params) {
  94. $dateType = (isset($params['date_type'])
  95. ? $params['date_type']
  96. : 'year_month_day'
  97. );
  98. $inputDateFormat = (isset($params['date_format'])
  99. ? $params['date_format']
  100. : ''
  101. );
  102. switch ($dateType) {
  103. case 'year_month_day':
  104. if (!in_array($inputDateFormat, ['MM/DD/YYYY', 'DD/MM/YYYY', 'YYYY/MM/DD'], true)) {
  105. throw new InvalidArgumentException(__('Invalid date_format for year_month_day', 'mailpoet'), self::ERROR_INVALID_DATE_FORMAT);
  106. }
  107. $dateFormat = $inputDateFormat;
  108. break;
  109. case 'year_month':
  110. if (!in_array($inputDateFormat, ['YYYY/MM', 'MM/YY'], true)) {
  111. throw new InvalidArgumentException(__('Invalid date_format for year_month', 'mailpoet'), self::ERROR_INVALID_DATE_FORMAT);
  112. }
  113. $dateFormat = $inputDateFormat;
  114. break;
  115. case 'month':
  116. $dateFormat = 'MM';
  117. break;
  118. case 'year':
  119. $dateFormat = 'YYYY';
  120. break;
  121. case 'day':
  122. $dateFormat = 'DD';
  123. break;
  124. default:
  125. throw new InvalidArgumentException(__('Invalid value for date_type', 'mailpoet'), self::ERROR_INVALID_DATE_TYPE);
  126. }
  127. return [
  128. 'date_type' => $dateType,
  129. 'date_format' => $dateFormat,
  130. ];
  131. }
  132. private function getExtraParamsForSelect($params) {
  133. if (empty($params['values'])) {
  134. throw new InvalidArgumentException(__('You need to pass some values for this type', 'mailpoet'), self::ERROR_NO_VALUES);
  135. }
  136. $values = [];
  137. foreach ($params['values'] as $value) {
  138. $values[] = $this->sanitizeValue($value);
  139. }
  140. return ['values' => $values];
  141. }
  142. private function sanitizeValue($value) {
  143. if (empty($value['value'])) {
  144. throw new InvalidArgumentException(__('Value cannot be empty', 'mailpoet'), self::ERROR_NO_VALUE);
  145. }
  146. $result = ['value' => $value['value']];
  147. if (isset($value['is_checked']) && $value['is_checked']) {
  148. $result['is_checked'] = '1';
  149. } else {
  150. $result['is_checked'] = '';
  151. }
  152. return $result;
  153. }
  154. }