PluginProbe
GiveWP – Donation Plugin and Fundraising Platform / 4.16.9
GiveWP – Donation Plugin and Fundraising Platform v4.16.9
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 2.3.2 2.30.0 All 255 releases
← All changes | src/PaymentGateways/PayPalCommerce/ScriptLoader.php +195 -73 2.30.04.16.9 View file →
@@ -1,10 +1,12 @@
1 1 <?php
2 2
3 3 namespace Give\PaymentGateways\PayPalCommerce;
4 4
5 +use Give\Helpers\EnqueueScript;
6 +use Give\Helpers\Form\Template\Utils\Frontend as FrontendFormTemplateUtils;
7 +use Give\PaymentGateways\Gateways\PayPalCommerce\PayPalCommerceGateway;
5 8 use Give\PaymentGateways\PayPalCommerce\Models\MerchantDetail;
6 -use Give\PaymentGateways\PayPalCommerce\Repositories\MerchantDetails;
7 9 use Give_Admin_Settings;
8 10
9 11 /**
10 12 * Class ScriptLoader
@@ -9,34 +11,86 @@
9 11 /**
10 12 * Class ScriptLoader
11 13 * @package Give\PaymentGateways\PayPalCommerce
12 14 *
15 + * @since 3.0.0 Implement on-demand PayPal connection. Admin can select Advance or standard card processing.
13 16 * @since 2.9.0
14 17 */
15 18 class ScriptLoader
16 19 {
17 20 /**
21 + * List of connection account type.
22 + *
23 + * @since 3.0.0
24 + * @var string[]
25 + */
26 + public static $accountTypes = [
27 + 'PPCP',
28 + 'EXPRESS_CHECKOUT'
29 + ];
30 +
31 + /**
32 + * List of countries that support custom payment accounts
33 + *
34 + * @since 3.0.0
35 + * @var string[]
36 + */
37 + private $countriesAvailableForAdvanceConnection = [
38 + 'AU',
39 + 'AT',
40 + 'BE',
41 + 'BG',
42 + 'CY',
43 + 'CZ',
44 + 'DK',
45 + 'EE',
46 + 'FI',
47 + 'FR',
48 + 'GR',
49 + 'HU',
50 + 'IT',
51 + 'LV',
52 + 'LI',
53 + 'LT',
54 + 'LU',
55 + 'MT',
56 + 'NL',
57 + 'NO',
58 + 'PL',
59 + 'PT',
60 + 'RO',
61 + 'SK',
62 + 'SI',
63 + 'ES',
64 + 'SE',
65 + 'GB',
66 + 'US',
67 + ];
68 +
69 + /**
18 70 * @since 2.9.0
19 71 *
20 - * @var MerchantDetails
72 + * @var PayPalCommerceGateway
21 73 */
22 - private $merchantRepository;
74 + private $payPalCommerceGateway;
23 75
24 76 /**
25 77 * ScriptLoader constructor.
26 78 *
79 + * @since 3.0.0 Remove $merchantRepository parameter and add $payPalCommerceGateway parameter.
27 80 * @since 2.9.0
28 81 *
29 - * @param MerchantDetails $merchantRepository
82 + * @param PayPalCommerceGateway $payPalCommerceGateway
30 83 */
31 - public function __construct(MerchantDetails $merchantRepository)
84 + public function __construct(PayPalCommerceGateway $payPalCommerceGateway)
32 85 {
33 - $this->merchantRepository = $merchantRepository;
86 + $this->payPalCommerceGateway = $payPalCommerceGateway;
34 87 }
35 88
36 89 /**
37 90 * Load admin scripts
38 91 *
92 + * @since 3.13.0 Add new "keepWebhooksAfterDisconnect" string
39 93 * @since 2.9.0
40 94 */
41 95 public function loadAdminScripts()
42 96 {
@@ -53,9 +107,9 @@
53 107 );
54 108
55 109 wp_enqueue_style(
56 110 'give-admin-paypal-commerce-css',
57 - GIVE_PLUGIN_URL . 'assets/dist/css/admin-paypal-commerce.css',
111 + GIVE_PLUGIN_URL . 'build/assets/dist/css/admin-paypal-commerce.css',
58 112 [],
59 113 GIVE_VERSION
60 114 );
61 115
@@ -62,8 +116,10 @@
62 116 wp_localize_script(
63 117 'give-paypal-partner-js',
64 118 'givePayPalCommerce',
65 119 [
120 + 'countriesAvailableForAdvanceConnection' => $this->countriesAvailableForAdvanceConnection,
121 + 'accountTypes' => self::$accountTypes,
66 122 'translations' => [
67 123 'confirmPaypalAccountDisconnection' => esc_html__('Disconnect PayPal Account', 'give'),
68 124 'disconnectPayPalAccount' => esc_html__(
69 125 'Are you sure you want to disconnect your PayPal account?',
@@ -68,15 +124,19 @@
68 124 'disconnectPayPalAccount' => esc_html__(
69 125 'Are you sure you want to disconnect your PayPal account?',
70 126 'give'
71 127 ),
128 + 'keepWebhooksAfterDisconnect' => esc_html__("Continue to receive events, including subscription renewals, from the disconnected account? If you have existing recurring donations with this account, you'll want to leave this checked. This is not reversible.",
129 + 'give'),
130 + 'keepWebhooksAfterDisconnectLearnMore' => esc_html__('Learn why this is critically important.',
131 + 'give') . ' &raquo;',
72 132 'connectSuccessTitle' => esc_html__('You’re connected to PayPal! Here’s what’s next...', 'give'),
73 133 'pciWarning' => sprintf(
74 134 __(
75 135 'PayPal allows you to accept credit or debit cards directly on your website. Because of
76 - this, your site needs to maintain <a href="%1$s" target="_blank">PCI-DDS compliance</a>.
77 - GiveWP never stores sensitive information like card details to your server and works
78 - seamlessly with SSL certificates. Compliance is comprised of, but not limited to:',
136 + this, your site needs to maintain <a href="%1$s" target="_blank">PCI-DDS compliance</a>.
137 + GiveWP never stores sensitive information like card details to your server and works
138 + seamlessly with SSL certificates. Compliance is comprised of, but not limited to:',
79 139 'give'
80 140 ),
81 141 'https://givewp.com/documentation/resources/pci-compliance/'
82 142 ),
@@ -132,83 +192,93 @@
132 192
133 193 /**
134 194 * Load public assets.
135 195 *
196 + * @since 3.2.0 Get form id from post content if form id is not available.
197 + * @since 3.2.0 Use EnqueueScript to register and enqueue script.
198 + * @since 2.32.0 Handle exception if client token is not generated.
136 199 * @since 2.9.0
137 200 */
138 201 public function loadPublicAssets()
139 202 {
140 - if (!Utils::gatewayIsActive() || !Utils::isAccountReadyToAcceptPayment()) {
203 + $formId = FrontendFormTemplateUtils::getFormId();
204 +
205 + if (! $formId) {
206 + $formId = $this->getFormIdFromPostContent();
207 + }
208 +
209 + if (
210 + ! $formId
211 + || \Give\Helpers\Form\Utils::isV3Form($formId)
212 + || ! Utils::gatewayIsActive()
213 + || ! Utils::isAccountReadyToAcceptPayment()
214 + ) {
141 215 return;
142 216 }
143 217
218 + try {
219 + $formSettings = $this->payPalCommerceGateway->formSettings($formId);
220 + $paypalSDKOptions = $formSettings['sdkOptions'];
221 +
222 + // Remove v3 donation form related param.
223 + unset($paypalSDKOptions['data-namespace']);
224 + } catch (\Exception $e) {
225 + give_set_error(
226 + 'give-paypal-commerce-client-token-error',
227 + sprintf(
228 + esc_html__(
229 + 'Unable to load PayPal Commerce client token. Please try again later. Error: %1$s',
230 + 'give'
231 + ),
232 + $e->getMessage()
233 + )
234 + );
235 +
236 + return;
237 + }
238 +
144 239 /* @var MerchantDetail $merchant */
145 240 $merchant = give(MerchantDetail::class);
241 +
146 242 $scriptId = 'give-paypal-commerce-js';
147 -
148 - /**
149 - * List of PayPal query parameters: https://developer.paypal.com/docs/checkout/reference/customize-sdk/#query-parameters
150 - * @since 2.27.1 Removed locale query parameter.
151 - */
152 - $payPalSdkQueryParameters = [
153 - 'client-id' => $merchant->clientId,
154 - 'merchant-id' => $merchant->merchantIdInPayPal,
155 - 'components' => 'hosted-fields,buttons',
156 - 'disable-funding' => 'credit',
157 - 'vault' => true,
158 - 'data-partner-attribution-id' => give('PAYPAL_COMMERCE_ATTRIBUTION_ID'),
159 - 'data-client-token' => $this->merchantRepository->getClientToken(),
243 + $data = [
244 + 'paypalCardInfoErrorPrefixes' => [
245 + 'expirationDateField' => esc_html__('Card Expiration Date:', 'give'),
246 + 'cardNumberField' => esc_html__('Card Number:', 'give'),
247 + 'cardCvcField' => esc_html__('Card CVC:', 'give'),
248 + ],
249 + 'cardFieldPlaceholders' => [
250 + 'cardNumber' => esc_html__('Card Number', 'give'),
251 + 'cardCvc' => esc_html__('CVC', 'give'),
252 + 'expirationDate' => esc_html__('MM/YY', 'give'),
253 + ],
254 + 'threeDsCardAuthenticationFailedNotice' => esc_html__(
255 + 'There was a problem authenticating your payment method. Please try again. If the problem persists, please try another payment method.',
256 + 'give'
257 + ),
258 + 'errorCodeLabel' => esc_html__('Error Code', 'give'),
259 + 'genericDonorErrorMessage' => __(
260 + 'There was an error processing your donation. Please contact the administrator.',
261 + 'give'
262 + ),
263 + // List of style properties support by PayPal for advanced card fields: https://developer.paypal.com/docs/business/checkout/reference/style-guide/#style-the-card-payments-fields
264 + 'hostedCardFieldStyles' => apply_filters('give_paypal_commerce_hosted_field_style', []),
265 + 'supportsCustomPayments' => $merchant->supportsCustomPayments ? 1 : '',
266 + 'separatorLabel' => esc_html__('Or pay with card', 'give'),
267 + 'payPalSdkQueryParameters' => $paypalSDKOptions,
268 + 'textForOverlayScreen' => sprintf(
269 + '<h3>%1$s</h3><p>%2$s</p><p>%3$s</p>',
270 + esc_html__('Donation Processing...', 'give'),
271 + esc_html__('Checking donation status with PayPal.', 'give'),
272 + esc_html__('This will only take a second!', 'give')
273 + )
160 274 ];
161 275
162 - if (give_is_setting_enabled(give_get_option('paypal_commerce_accept_venmo', 'disabled'))) {
163 - $payPalSdkQueryParameters['enable-funding'] = 'venmo';
164 - }
165 -
166 - wp_enqueue_script(
167 - $scriptId,
168 - GIVE_PLUGIN_URL . 'assets/dist/js/paypal-commerce.js',
169 - [],
170 - GIVE_VERSION,
171 - true
172 - );
173 -
174 - wp_localize_script(
175 - $scriptId,
176 - 'givePayPalCommerce',
177 - [
178 - 'paypalCardInfoErrorPrefixes' => [
179 - 'expirationDateField' => esc_html__('Card Expiration Date:', 'give'),
180 - 'cardNumberField' => esc_html__('Card Number:', 'give'),
181 - 'cardCvcField' => esc_html__('Card CVC:', 'give'),
182 - ],
183 - 'cardFieldPlaceholders' => [
184 - 'cardNumber' => esc_html__('Card Number', 'give'),
185 - 'cardCvc' => esc_html__('CVC', 'give'),
186 - 'expirationDate' => esc_html__('MM/YY', 'give'),
187 - ],
188 - 'threeDsCardAuthenticationFailedNotice' => esc_html__(
189 - 'There was a problem authenticating your payment method. Please try again. If the problem persists, please try another payment method.',
190 - 'give'
191 - ),
192 - 'errorCodeLabel' => esc_html__('Error Code', 'give'),
193 - 'genericDonorErrorMessage' => __(
194 - 'There was an error processing your donation. Please contact the administrator.',
195 - 'give'
196 - ),
197 - // List of style properties support by PayPal for advanced card fields: https://developer.paypal.com/docs/business/checkout/reference/style-guide/#style-the-card-payments-fields
198 - 'hostedCardFieldStyles' => apply_filters('give_paypal_commerce_hosted_field_style', []),
199 - 'supportsCustomPayments' => $merchant->supportsCustomPayments ? 1 : '',
200 - 'accountCountry' => $merchant->accountCountry,
201 - 'separatorLabel' => esc_html__('Or pay with card', 'give'),
202 - 'payPalSdkQueryParameters' => $payPalSdkQueryParameters,
203 - 'textForOverlayScreen' => sprintf(
204 - '<h3>%1$s</h3><p>%2$s</p><p>%3$s</p>',
205 - esc_html__('Donation Processing...', 'give'),
206 - esc_html__('Checking donation status with PayPal.', 'give'),
207 - esc_html__('This will only take a second!', 'give')
208 - ),
209 - ]
210 - );
276 + EnqueueScript::make($scriptId, 'build/assets/dist/js/paypal-commerce.js')
277 + ->registerTranslations()
278 + ->loadInFooter()
279 + ->registerLocalizeData('givePayPalCommerce', $data)
280 + ->enqueue();
211 281 }
212 282
213 283 /**
214 284 * Get PayPal partner js url.
@@ -220,6 +290,58 @@
220 290 */
221 291 private function getPartnerJsUrl()
222 292 {
223 293 return 'https://www.paypal.com/webapps/merchantboarding/js/lib/lightbox/partner.js';
294 + }
295 +
296 + /**
297 + * This function should return form id from page, post content.
298 + *
299 + * @since 3.4.0 Check if $attributes is a valid array before trying to use it as it were
300 + * @since 3.2.0
301 + */
302 + private function getFormIdFromPostContent(): ?int
303 + {
304 + global $post;
305 + $formId = null;
306 +
307 + if (!$post) {
308 + return null;
309 + }
310 +
311 +
312 + // Donation form can be in page, post content as shortcode.
313 + $has_shortcode = $post && has_shortcode($post->post_content, 'give_form');
314 + if ($has_shortcode) {
315 + $pattern = get_shortcode_regex(['give_form']);
316 +
317 + if (
318 + preg_match('/' . $pattern . '/s', $post->post_content, $matches)
319 + && array_key_exists(2, $matches)
320 + && 'give_form' === $matches[2]
321 + ) {
322 + $attributes = shortcode_parse_atts($matches[3]);
323 +
324 + if (is_array($attributes) && array_key_exists('id', $attributes)) {
325 + $formId = $attributes['id'];
326 + }
327 + }
328 + }
329 +
330 + // Donation form can be in page, post content as Donation Form block.
331 + if (!$formId) {
332 + $blocks = parse_blocks($post->post_content);
333 +
334 + foreach ($blocks as $block) {
335 + if (
336 + $block['blockName'] === 'give/donation-form'
337 + && array_key_exists('id', $block['attrs'])
338 + ) {
339 + $formId = $block['attrs']['id'];
340 + break;
341 + }
342 + }
343 + }
344 +
345 + return absint($formId);
224 346 }
225 347 }