PluginProbe
GiveWP – Donation Plugin and Fundraising Platform / 4.18.0
GiveWP – Donation Plugin and Fundraising Platform v4.18.0
4.18.0 4.17.0 4.16.9 4.16.8.1 4.16.8 4.16.7.2 4.16.7.1 4.16.7 4.16.6.1 4.16.6 4.16.5.1 4.16.5 4.16.4 4.16.3 4.16.2 4.16.1 4.16.0 4.15.5 4.15.4 4.15.3 4.15.2 4.15.1 4.15.0 2.3.0 2.3.1 All 257 releases
give / src / DonationForms / DataTransferObjects / DonateFormRouteData.php

DonateFormRouteData.php in GiveWP – Donation Plugin and Fundraising Platform 4.18.0, at src/DonationForms/DataTransferObjects/DonateFormRouteData.php

196 lines 5.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace Give\DonationForms\DataTransferObjects;
4
5 use Give\DonationForms\Exceptions\DonationFormFieldErrorsException;
6 use Give\DonationForms\Exceptions\DonationFormForbidden;
7 use Give\DonationForms\Models\DonationForm;
8 use Give\Framework\FieldsAPI\Actions\CreateValidatorFromForm;
9 use Give\Framework\FieldsAPI\Exceptions\NameCollisionException;
10 use Give\Framework\Permissions\Facades\UserPermissions;
11 use Give\Framework\Support\Contracts\Arrayable;
12 use WP_Error;
13
14 /**
15 * @since 3.0.0
16 */
17 class DonateFormRouteData implements Arrayable
18 {
19 /**
20 * @var string
21 */
22 public $gatewayId;
23 /**
24 * @var array
25 */
26 private $requestData;
27 /**
28 * @var int
29 */
30 public $formId;
31 /**
32 * @var string
33 */
34 public $originUrl;
35 /**
36 * @var string|null
37 */
38 public $embedId;
39 /**
40 * @var bool
41 */
42 public $isEmbed;
43
44 /**
45 * Convert data from request into DTO
46 *
47 * @since 4.17.0 Validate the client-provided origin URL before it is used in redirects.
48 * @since 3.0.0
49 */
50 public static function fromRequest(array $requestData): self
51 {
52 $self = new self();
53 $self->formId = (int)$requestData['formId'];
54 $self->gatewayId = $requestData['gatewayId'];
55 $self->originUrl = self::validateOriginUrl($requestData['originUrl'] ?? '');
56 $self->isEmbed = filter_var($requestData['isEmbed'], FILTER_VALIDATE_BOOLEAN);
57 $self->embedId = $self->isEmbed ? $requestData['embedId'] : null;
58 $self->requestData = $requestData;
59
60 return $self;
61 }
62
63 /**
64 * This method loops over the form schema to
65 * compares the request against the individual fields,
66 * their types and validation rules.
67 *
68 * @since 3.22.0 added givewp_donation_form_fields_validated action
69 * @since 3.14.0 Added form status validation
70 * @since 3.0.0
71 *
72 * @throws DonationFormFieldErrorsException|NameCollisionException|DonationFormForbidden
73 */
74 public function validated(): DonateControllerData
75 {
76 $request = $this->getRequestData();
77 $validData = new DonateControllerData();
78
79 /** @var DonationForm $form */
80 $form = DonationForm::find($this->formId);
81
82 if (!$form || !$this->isValidForm($form)) {
83 throw new DonationFormForbidden();
84 }
85
86 $validator = (new CreateValidatorFromForm())($form->schema(), $request);
87
88 if ($validator->fails()) {
89 $this->throwDonationFormFieldErrorsException($validator->errors());
90 }
91
92 $validatedValues = $validator->validated();
93
94 /**
95 * @since 4.16.0 added $isFinalSubmission (true here: the final donation submission)
96 * @since 3.22.0
97 *
98 * @param array $data validated values in key value pairs
99 * @param bool $isFinalSubmission whether this is the final donation submission
100 */
101 do_action('givewp_donation_form_fields_validated', $validatedValues, true);
102
103 foreach ($validatedValues as $fieldId => $value) {
104 $validData->{$fieldId} = $value;
105 }
106
107 $validData->formTitle = $form->title;
108 $validData->wpUserId = get_current_user_id();
109 $validData->originUrl = $this->originUrl;
110 $validData->embedId = $this->embedId;
111 $validData->isEmbed = $this->isEmbed;
112
113 return $validData;
114 }
115
116 /**
117 * @since 3.0.0
118 */
119 public function getRequestData(): array
120 {
121 return $this->requestData;
122 }
123
124 /**
125 * The origin URL is client-provided and later used as a redirect target,
126 * so anything that is not a valid http(s) URL falls back to the site URL.
127 * Intentionally not wp_http_validate_url(), which rejects localhost hosts
128 * that are valid embed origins during development.
129 *
130 * @since 4.17.0
131 *
132 * @param mixed $originUrl
133 */
134 private static function validateOriginUrl($originUrl): string
135 {
136 if (!is_string($originUrl) || $originUrl === '') {
137 return '';
138 }
139
140 $scheme = wp_parse_url($originUrl, PHP_URL_SCHEME);
141
142 if (in_array($scheme, ['http', 'https'], true) && filter_var($originUrl, FILTER_VALIDATE_URL)) {
143 return $originUrl;
144 }
145
146 return home_url();
147 }
148
149 /**
150 * This loops over an array of errors in the specific FieldAPI format,
151 * and converts them into a WP_Error object that is attached to the
152 * exception and delivered back to the client via JSON.
153 *
154 * @since 3.0.0
155 *
156 * @param array<string, string> $errors
157 *
158 * @throws DonationFormFieldErrorsException
159 */
160 private function throwDonationFormFieldErrorsException(array $errors)
161 {
162 $wpError = new WP_Error();
163
164 foreach ($errors as $id => $error) {
165 $wpError->add($id, $error);
166 }
167
168 throw new DonationFormFieldErrorsException($wpError);
169 }
170
171 /**
172 * @since 3.0.0
173 */
174 public function toArray(): array
175 {
176 return get_object_vars($this);
177 }
178
179 /**
180 * @since 4.14.0.0 update permission capability to use facade
181 * @since 3.14.0
182 */
183 private function isValidForm(DonationForm $form): bool
184 {
185 if ($form->status->isTrash()) {
186 return false;
187 }
188
189 if (!$form->status->isPublished() && !UserPermissions::donationForms()->canEdit()) {
190 return false;
191 }
192
193 return true;
194 }
195 }
196