WooCommerce PayPal Payments - Version 1.6.2

Version Description

  • Fix - Order of WooCommerce checkout actions causing incompatibility with AvaTax address validation #335
  • Fix - Can't checkout to certain countries with optional postcode #330
  • Fix - Prevent subscription from being purchased when saving payment fails #308
  • Fix - Guest users must checkout twice for subscriptions, no smart buttons loaded #342
  • Fix - Failed PayPal API request causing strange error #347
  • Fix - PayPal payments page empty after switching packages #350
  • Fix - Could Not Validate Nonce Error #239
  • Fix - Refund via PayPal dashboard does not set the WooCommerce order to "Refunded" #241
  • Fix - Uncaught TypeError: round() #344
  • Fix - Broken multi-level (nested) associative array values after getting submitted from checkout page #307
  • Fix - Transaction id missing in some cases #328
  • Fix - Payment not possible in pay for order form because of terms checkbox missing #294
  • Fix - "Save your Credit Card" shouldn't be optional when paying for a subscription #368
  • Fix - When paying for a subscription and vaulting fails, cart is cleared #367
  • Fix - Fatal error when activating PayPal Checkout plugin #363
Download this release

Release Info

Developer woothemes
Plugin Icon 128x128 WooCommerce PayPal Payments
Version 1.6.2
Comparing to
See all releases

Code changes from version 1.6.1 to 1.6.2

Files changed (334) hide show
  1. changelog.txt +17 -0
  2. modules/ppcp-admin-notices/composer.json +17 -0
  3. modules/ppcp-admin-notices/services.php +3 -3
  4. modules/ppcp-admin-notices/src/{class-adminnotices.php → AdminNotices.php} +5 -9
  5. modules/ppcp-admin-notices/src/Entity/{class-message.php → Message.php} +0 -0
  6. modules/ppcp-admin-notices/src/Renderer/{class-renderer.php → Renderer.php} +0 -0
  7. modules/ppcp-admin-notices/src/Renderer/{class-rendererinterface.php → RendererInterface.php} +0 -0
  8. modules/ppcp-admin-notices/src/Repository/{class-repository.php → Repository.php} +0 -0
  9. modules/ppcp-admin-notices/src/Repository/{class-repositoryinterface.php → RepositoryInterface.php} +0 -0
  10. modules/ppcp-api-client/composer.json +17 -0
  11. modules/ppcp-api-client/services.php +39 -36
  12. modules/ppcp-api-client/src/{class-apimodule.php → ApiModule.php} +3 -7
  13. modules/ppcp-api-client/src/Authentication/{class-bearer.php → Bearer.php} +0 -0
  14. modules/ppcp-api-client/src/Authentication/{class-connectbearer.php → ConnectBearer.php} +0 -0
  15. modules/ppcp-api-client/src/Authentication/{class-paypalbearer.php → PayPalBearer.php} +0 -0
  16. modules/ppcp-api-client/src/Endpoint/{class-identitytoken.php → IdentityToken.php} +0 -0
  17. modules/ppcp-api-client/src/Endpoint/{class-loginseller.php → LoginSeller.php} +0 -0
  18. modules/ppcp-api-client/src/Endpoint/{class-orderendpoint.php → OrderEndpoint.php} +32 -1
  19. modules/ppcp-api-client/src/Endpoint/{class-partnerreferrals.php → PartnerReferrals.php} +0 -0
  20. modules/ppcp-api-client/src/Endpoint/{class-partnersendpoint.php → PartnersEndpoint.php} +0 -0
  21. modules/ppcp-api-client/src/Endpoint/{class-paymenttokenendpoint.php → PaymentTokenEndpoint.php} +0 -0
  22. modules/ppcp-api-client/src/Endpoint/{class-paymentsendpoint.php → PaymentsEndpoint.php} +1 -1
  23. modules/ppcp-api-client/src/Endpoint/{class-requesttrait.php → RequestTrait.php} +12 -5
  24. modules/ppcp-api-client/src/Endpoint/{class-webhookendpoint.php → WebhookEndpoint.php} +0 -0
  25. modules/ppcp-api-client/src/Entity/{class-address.php → Address.php} +0 -0
  26. modules/ppcp-api-client/src/Entity/{class-amount.php → Amount.php} +0 -0
  27. modules/ppcp-api-client/src/Entity/{class-amountbreakdown.php → AmountBreakdown.php} +14 -14
  28. modules/ppcp-api-client/src/Entity/{class-applicationcontext.php → ApplicationContext.php} +0 -0
  29. modules/ppcp-api-client/src/Entity/{class-authorization.php → Authorization.php} +10 -0
  30. modules/ppcp-api-client/src/Entity/{class-authorizationstatus.php → AuthorizationStatus.php} +0 -0
  31. modules/ppcp-api-client/src/Entity/{class-authorizationstatusdetails.php → AuthorizationStatusDetails.php} +0 -0
  32. modules/ppcp-api-client/src/Entity/{class-capture.php → Capture.php} +6 -5
  33. modules/ppcp-api-client/src/Entity/{class-capturestatus.php → CaptureStatus.php} +0 -0
  34. modules/ppcp-api-client/src/Entity/{class-capturestatusdetails.php → CaptureStatusDetails.php} +0 -0
  35. modules/ppcp-api-client/src/Entity/{class-cardauthenticationresult.php → CardAuthenticationResult.php} +0 -0
  36. modules/ppcp-api-client/src/Entity/{class-item.php → Item.php} +0 -0
  37. modules/ppcp-api-client/src/Entity/{class-money.php → Money.php} +0 -0
  38. modules/ppcp-api-client/src/Entity/{class-order.php → Order.php} +0 -0
  39. modules/ppcp-api-client/src/Entity/{class-orderstatus.php → OrderStatus.php} +0 -0
  40. modules/ppcp-api-client/src/Entity/{class-patch.php → Patch.php} +0 -0
  41. modules/ppcp-api-client/src/Entity/{class-patchcollection.php → PatchCollection.php} +0 -0
  42. modules/ppcp-api-client/src/Entity/{class-payee.php → Payee.php} +0 -0
  43. modules/ppcp-api-client/src/Entity/{class-payer.php → Payer.php} +0 -0
  44. modules/ppcp-api-client/src/Entity/{class-payername.php → PayerName.php} +0 -0
  45. modules/ppcp-api-client/src/Entity/{class-payertaxinfo.php → PayerTaxInfo.php} +0 -0
  46. modules/ppcp-api-client/src/Entity/{class-paymentmethod.php → PaymentMethod.php} +0 -0
  47. modules/ppcp-api-client/src/Entity/{class-paymentsource.php → PaymentSource.php} +0 -0
  48. modules/ppcp-api-client/src/Entity/{class-paymentsourcecard.php → PaymentSourceCard.php} +0 -0
  49. modules/ppcp-api-client/src/Entity/{class-paymentsourcewallet.php → PaymentSourceWallet.php} +0 -0
  50. modules/ppcp-api-client/src/Entity/{class-paymenttoken.php → PaymentToken.php} +0 -0
  51. modules/ppcp-api-client/src/Entity/{class-payments.php → Payments.php} +0 -0
  52. modules/ppcp-api-client/src/Entity/{class-phone.php → Phone.php} +0 -0
  53. modules/ppcp-api-client/src/Entity/{class-phonewithtype.php → PhoneWithType.php} +0 -0
  54. modules/ppcp-api-client/src/Entity/{class-purchaseunit.php → PurchaseUnit.php} +59 -35
  55. modules/ppcp-api-client/src/Entity/{class-refund.php → Refund.php} +0 -0
  56. modules/ppcp-api-client/src/Entity/{class-sellerstatus.php → SellerStatus.php} +0 -0
  57. modules/ppcp-api-client/src/Entity/{class-sellerstatusproduct.php → SellerStatusProduct.php} +0 -0
  58. modules/ppcp-api-client/src/Entity/{class-shipping.php → Shipping.php} +0 -0
  59. modules/ppcp-api-client/src/Entity/{class-token.php → Token.php} +0 -0
  60. modules/ppcp-api-client/src/Entity/{class-webhook.php → Webhook.php} +3 -3
  61. modules/ppcp-api-client/src/Entity/{class-webhookevent.php → WebhookEvent.php} +0 -0
  62. modules/ppcp-api-client/src/Exception/{class-notfoundexception.php → NotFoundException.php} +0 -0
  63. modules/ppcp-api-client/src/Exception/{class-paypalapiexception.php → PayPalApiException.php} +0 -0
  64. modules/ppcp-api-client/src/Exception/{class-runtimeexception.php → RuntimeException.php} +0 -0
  65. modules/ppcp-api-client/src/Factory/{class-addressfactory.php → AddressFactory.php} +0 -0
  66. modules/ppcp-api-client/src/Factory/{class-amountfactory.php → AmountFactory.php} +0 -0
  67. modules/ppcp-api-client/src/Factory/{class-applicationcontextfactory.php → ApplicationContextFactory.php} +0 -0
  68. modules/ppcp-api-client/src/Factory/{class-authorizationfactory.php → AuthorizationFactory.php} +0 -0
  69. modules/ppcp-api-client/src/Factory/{class-capturefactory.php → CaptureFactory.php} +1 -1
  70. modules/ppcp-api-client/src/Factory/{class-itemfactory.php → ItemFactory.php} +0 -0
  71. modules/ppcp-api-client/src/Factory/{class-orderfactory.php → OrderFactory.php} +0 -0
  72. modules/ppcp-api-client/src/Factory/{class-patchcollectionfactory.php → PatchCollectionFactory.php} +1 -3
  73. modules/ppcp-api-client/src/Factory/{class-payeefactory.php → PayeeFactory.php} +0 -0
  74. modules/ppcp-api-client/src/Factory/{class-payerfactory.php → PayerFactory.php} +0 -0
  75. modules/ppcp-api-client/src/Factory/{class-paymentsourcefactory.php → PaymentSourceFactory.php} +0 -0
  76. modules/ppcp-api-client/src/Factory/{class-paymenttokenfactory.php → PaymentTokenFactory.php} +0 -0
  77. modules/ppcp-api-client/src/Factory/{class-paymentsfactory.php → PaymentsFactory.php} +1 -1
  78. modules/ppcp-api-client/src/Factory/{class-purchaseunitfactory.php → PurchaseUnitFactory.php} +4 -2
  79. modules/ppcp-api-client/src/Factory/{class-sellerstatusfactory.php → SellerStatusFactory.php} +0 -0
  80. modules/ppcp-api-client/src/Factory/{class-shippingfactory.php → ShippingFactory.php} +0 -0
  81. modules/ppcp-api-client/src/Factory/{class-webhookeventfactory.php → WebhookEventFactory.php} +0 -0
  82. modules/ppcp-api-client/src/Factory/{class-webhookfactory.php → WebhookFactory.php} +7 -6
  83. modules/ppcp-api-client/src/Helper/{class-cache.php → Cache.php} +0 -0
  84. modules/ppcp-api-client/src/Helper/{class-dccapplies.php → DccApplies.php} +0 -0
  85. modules/ppcp-api-client/src/Helper/{class-errorresponse.php → ErrorResponse.php} +0 -0
  86. modules/ppcp-api-client/src/Repository/{class-applicationcontextrepository.php → ApplicationContextRepository.php} +0 -0
  87. modules/ppcp-api-client/src/Repository/{class-cartrepository.php → CartRepository.php} +0 -0
  88. modules/ppcp-api-client/src/Repository/{class-partnerreferralsdata.php → PartnerReferralsData.php} +0 -0
  89. modules/ppcp-api-client/src/Repository/{class-paypalrequestidrepository.php → PayPalRequestIdRepository.php} +0 -0
  90. modules/ppcp-api-client/src/Repository/{class-payeerepository.php → PayeeRepository.php} +0 -0
  91. modules/ppcp-api-client/src/Repository/{class-purchaseunitrepositoryinterface.php → PurchaseUnitRepositoryInterface.php} +0 -0
  92. modules/ppcp-button/assets/js/button.js +1 -1
  93. modules/ppcp-button/composer.json +17 -0
  94. modules/ppcp-button/resources/js/modules/Renderer/CreditCardRenderer.js +4 -1
  95. modules/ppcp-button/services.php +26 -12
  96. modules/ppcp-button/src/Assets/{class-disabledsmartbutton.php → DisabledSmartButton.php} +0 -0
  97. modules/ppcp-button/src/Assets/{class-smartbutton.php → SmartButton.php} +17 -10
  98. modules/ppcp-button/src/Assets/{class-smartbuttoninterface.php → SmartButtonInterface.php} +0 -0
  99. modules/ppcp-button/src/{class-buttonmodule.php → ButtonModule.php} +10 -14
  100. modules/ppcp-button/src/Endpoint/{class-approveorderendpoint.php → ApproveOrderEndpoint.php} +1 -10
  101. modules/ppcp-button/src/Endpoint/{class-changecartendpoint.php → ChangeCartEndpoint.php} +0 -0
  102. modules/ppcp-button/src/Endpoint/{class-createorderendpoint.php → CreateOrderEndpoint.php} +28 -87
  103. modules/ppcp-button/src/Endpoint/{class-dataclientidendpoint.php → DataClientIdEndpoint.php} +0 -0
  104. modules/ppcp-button/src/Endpoint/{class-endpointinterface.php → EndpointInterface.php} +0 -0
  105. modules/ppcp-button/src/Endpoint/{class-requestdata.php → RequestData.php} +0 -0
  106. modules/ppcp-button/src/Exception/{class-runtimeexception.php → RuntimeException.php} +0 -0
  107. modules/ppcp-button/src/Helper/{class-earlyorderhandler.php → EarlyOrderHandler.php} +0 -0
  108. modules/ppcp-button/src/Helper/{class-messagesapply.php → MessagesApply.php} +0 -0
  109. modules/ppcp-button/src/Helper/{class-messagesdisclaimers.php → MessagesDisclaimers.php} +0 -0
  110. modules/ppcp-button/src/Helper/{class-threedsecure.php → ThreeDSecure.php} +0 -0
  111. modules/ppcp-compat/composer.json +17 -0
  112. modules/ppcp-compat/services.php +3 -1
  113. modules/ppcp-compat/src/{class-compatmodule.php → CompatModule.php} +3 -3
  114. modules/ppcp-compat/src/PPEC/{class-deactivatenote.php → DeactivateNote.php} +0 -0
  115. modules/ppcp-compat/src/PPEC/{class-mockgateway.php → MockGateway.php} +0 -0
  116. modules/ppcp-compat/src/PPEC/{class-ppechelper.php → PPECHelper.php} +6 -1
  117. modules/ppcp-compat/src/PPEC/{class-settingsimporter.php → SettingsImporter.php} +0 -0
  118. modules/ppcp-compat/src/PPEC/{class-subscriptionshandler.php → SubscriptionsHandler.php} +0 -0
  119. modules/ppcp-onboarding/composer.json +17 -0
  120. modules/ppcp-onboarding/services.php +23 -22
  121. modules/ppcp-onboarding/src/Assets/{class-onboardingassets.php → OnboardingAssets.php} +0 -0
  122. modules/ppcp-onboarding/src/Endpoint/{class-loginsellerendpoint.php → LoginSellerEndpoint.php} +0 -0
  123. modules/ppcp-onboarding/src/{class-environment.php → Environment.php} +0 -0
  124. modules/ppcp-onboarding/src/{class-onboardingmodule.php → OnboardingModule.php} +9 -13
  125. modules/ppcp-onboarding/src/{class-onboarding-rest-controller.php → OnboardingRESTController.php} +1 -1
  126. modules/ppcp-onboarding/src/Render/{class-onboardingrenderer.php → OnboardingRenderer.php} +0 -0
  127. modules/ppcp-onboarding/src/{class-state.php → State.php} +0 -0
  128. modules/ppcp-session/composer.json +17 -0
  129. modules/ppcp-session/services.php +4 -4
  130. modules/ppcp-session/src/Cancellation/{class-cancelcontroller.php → CancelController.php} +0 -0
  131. modules/ppcp-session/src/Cancellation/{class-cancelview.php → CancelView.php} +0 -0
  132. modules/ppcp-session/src/{class-sessionhandler.php → SessionHandler.php} +0 -0
  133. modules/ppcp-session/src/{class-sessionmodule.php → SessionModule.php} +5 -9
  134. modules/ppcp-status-report/composer.json +17 -0
  135. modules/ppcp-status-report/services.php +1 -1
  136. modules/ppcp-status-report/src/{class-renderer.php → Renderer.php} +0 -0
  137. modules/ppcp-status-report/src/{class-statusreportmodule.php → StatusReportModule.php} +8 -8
  138. modules/ppcp-subscription/composer.json +17 -0
  139. modules/ppcp-subscription/services.php +9 -2
  140. modules/ppcp-subscription/src/Helper/{class-subscriptionhelper.php → SubscriptionHelper.php} +1 -1
  141. modules/ppcp-subscription/src/{class-renewalhandler.php → RenewalHandler.php} +2 -1
  142. modules/ppcp-subscription/src/{class-subscriptionmodule.php → SubscriptionModule.php} +19 -23
  143. modules/ppcp-vaulting/composer.json +17 -0
  144. modules/ppcp-vaulting/services.php +5 -4
  145. modules/ppcp-vaulting/src/Assets/{class-myaccountpaymentsassets.php → MyAccountPaymentsAssets.php} +1 -1
  146. modules/ppcp-vaulting/src/Endpoint/{class-deletepaymenttokenendpoint.php → DeletePaymentTokenEndpoint.php} +0 -0
  147. modules/ppcp-vaulting/src/{class-paymenttokenrepository.php → PaymentTokenRepository.php} +0 -0
  148. modules/ppcp-vaulting/src/{class-paymenttokensrenderer.php → PaymentTokensRenderer.php} +0 -0
  149. modules/ppcp-vaulting/src/{class-vaultingmodule.php → VaultingModule.php} +21 -0
  150. modules/ppcp-wc-gateway/composer.json +17 -0
  151. modules/ppcp-wc-gateway/extensions.php +10 -8
  152. modules/ppcp-wc-gateway/module.php +1 -1
  153. modules/ppcp-wc-gateway/services.php +53 -45
  154. modules/ppcp-wc-gateway/src/Admin/{class-ordertablepaymentstatuscolumn.php → OrderTablePaymentStatusColumn.php} +3 -2
  155. modules/ppcp-wc-gateway/src/Admin/{class-paymentstatusorderdetail.php → PaymentStatusOrderDetail.php} +0 -0
  156. modules/ppcp-wc-gateway/src/Admin/{class-renderauthorizeaction.php → RenderAuthorizeAction.php} +21 -2
  157. modules/ppcp-wc-gateway/src/Assets/{class-settingspageassets.php → SettingsPageAssets.php} +0 -0
  158. modules/ppcp-wc-gateway/src/Checkout/{class-checkoutpaypaladdresspreset.php → CheckoutPayPalAddressPreset.php} +0 -1
  159. modules/ppcp-wc-gateway/src/Checkout/{class-disablegateways.php → DisableGateways.php} +18 -4
  160. modules/ppcp-wc-gateway/src/Endpoint/{class-returnurlendpoint.php → ReturnUrlEndpoint.php} +0 -3
  161. modules/ppcp-wc-gateway/src/Exception/{class-notfoundexception.php → NotFoundException.php} +0 -0
  162. modules/ppcp-wc-gateway/src/Gateway/{class-creditcardgateway.php → CreditCardGateway.php} +72 -22
  163. modules/ppcp-wc-gateway/src/Gateway/{class-paypalgateway.php → PayPalGateway.php} +85 -102
  164. modules/ppcp-wc-gateway/src/Gateway/{class-processpaymenttrait.php → ProcessPaymentTrait.php} +111 -2
  165. modules/ppcp-wc-gateway/src/Gateway/{class-transactionurlprovider.php → TransactionUrlProvider.php} +0 -0
  166. modules/ppcp-wc-gateway/src/Helper/{class-dccproductstatus.php → DCCProductStatus.php} +3 -3
  167. modules/ppcp-wc-gateway/src/Helper/{class-settingsstatus.php → SettingsStatus.php} +2 -2
  168. modules/ppcp-wc-gateway/src/Notice/{class-authorizeorderactionnotice.php → AuthorizeOrderActionNotice.php} +0 -0
  169. modules/ppcp-wc-gateway/src/Notice/{class-connectadminnotice.php → ConnectAdminNotice.php} +0 -0
  170. modules/ppcp-wc-gateway/src/Notice/{class-dccwithoutpaypaladminnotice.php → DccWithoutPayPalAdminNotice.php} +0 -0
  171. modules/ppcp-wc-gateway/src/Processor/{class-authorizedpaymentsprocessor.php → AuthorizedPaymentsProcessor.php} +86 -5
  172. modules/ppcp-wc-gateway/src/Processor/{class-ordermetatrait.php → OrderMetaTrait.php} +0 -0
  173. modules/ppcp-wc-gateway/src/Processor/{class-orderprocessor.php → OrderProcessor.php} +5 -56
  174. modules/ppcp-wc-gateway/src/Processor/{class-paymentstatushandlingtrait.php → PaymentsStatusHandlingTrait.php} +7 -5
  175. modules/ppcp-wc-gateway/src/Processor/{class-refundprocessor.php → RefundProcessor.php} +4 -13
  176. modules/ppcp-wc-gateway/src/Processor/TransactionIdHandlingTrait.php +85 -0
  177. modules/ppcp-wc-gateway/src/Settings/{class-pagematchertrait.php → PageMatcherTrait.php} +0 -7
  178. modules/ppcp-wc-gateway/src/Settings/{class-sectionsrenderer.php → SectionsRenderer.php} +0 -0
  179. modules/ppcp-wc-gateway/src/Settings/{class-settings.php → Settings.php} +0 -0
  180. modules/ppcp-wc-gateway/src/Settings/{class-settingslistener.php → SettingsListener.php} +0 -0
  181. modules/ppcp-wc-gateway/src/Settings/{class-settingsrenderer.php → SettingsRenderer.php} +5 -5
  182. modules/ppcp-wc-gateway/src/{class-wcgatewaymodule.php → WCGatewayModule.php} +30 -32
  183. modules/ppcp-webhooks/composer.json +17 -0
  184. modules/ppcp-webhooks/services.php +15 -15
  185. modules/ppcp-webhooks/src/Endpoint/{class-resubscribeendpoint.php → ResubscribeEndpoint.php} +0 -0
  186. modules/ppcp-webhooks/src/Endpoint/{class-simulateendpoint.php → SimulateEndpoint.php} +0 -0
  187. modules/ppcp-webhooks/src/Endpoint/{class-simulationstateendpoint.php → SimulationStateEndpoint.php} +0 -0
  188. modules/ppcp-webhooks/src/Handler/{class-checkoutorderapproved.php → CheckoutOrderApproved.php} +1 -1
  189. modules/ppcp-webhooks/src/Handler/{class-checkoutordercompleted.php → CheckoutOrderCompleted.php} +1 -1
  190. modules/ppcp-webhooks/src/Handler/PaymentCaptureCompleted.php +160 -0
  191. modules/ppcp-webhooks/src/Handler/{class-paymentcapturerefunded.php → PaymentCaptureRefunded.php} +1 -1
  192. modules/ppcp-webhooks/src/Handler/{class-paymentcapturereversed.php → PaymentCaptureReversed.php} +1 -1
  193. modules/ppcp-webhooks/src/Handler/{class-prefixtrait.php → PrefixTrait.php} +0 -0
  194. modules/ppcp-webhooks/src/Handler/{class-requesthandler.php → RequestHandler.php} +1 -1
  195. modules/ppcp-webhooks/src/Handler/class-paymentcapturecompleted.php +0 -141
  196. modules/ppcp-webhooks/src/{class-incomingwebhookendpoint.php → IncomingWebhookEndpoint.php} +14 -2
  197. modules/ppcp-webhooks/src/Status/Assets/{class-webhooksstatuspageassets.php → WebhooksStatusPageAssets.php} +3 -5
  198. modules/ppcp-webhooks/src/Status/{class-webhooksimulation.php → WebhookSimulation.php} +1 -1
  199. modules/ppcp-webhooks/src/Status/{class-webhooksstatuspage.php → WebhooksStatusPage.php} +0 -0
  200. modules/ppcp-webhooks/src/{class-webhookmodule.php → WebhookModule.php} +3 -7
  201. modules/ppcp-webhooks/src/{class-webhookregistrar.php → WebhookRegistrar.php} +0 -0
  202. modules/woocommerce-logging/composer.json +17 -0
  203. modules/woocommerce-logging/src/Logger/{class-nulllogger.php → NullLogger.php} +0 -0
  204. modules/woocommerce-logging/src/Logger/{class-woocommercelogger.php → WooCommerceLogger.php} +0 -0
  205. modules/woocommerce-logging/src/{class-woocommerceloggingmodule.php → WooCommerceLoggingModule.php} +3 -7
  206. psalm-baseline.xml +921 -0
  207. psalm.xml.dist +154 -0
  208. readme.txt +18 -1
  209. src/{class-pluginmodule.php → PluginModule.php} +3 -5
  210. vendor/autoload.php +1 -1
  211. vendor/composer/ClassLoader.php +14 -141
  212. vendor/composer/InstalledVersions.php +0 -337
  213. vendor/composer/autoload_classmap.php +0 -177
  214. vendor/composer/autoload_psr4.php +14 -5
  215. vendor/composer/autoload_real.php +9 -11
  216. vendor/composer/autoload_static.php +74 -207
  217. vendor/composer/installed.json +407 -660
  218. vendor/composer/installed.php +0 -131
  219. vendor/composer/platform_check.php +0 -26
  220. vendor/dhii/collections-interface/CHANGELOG.md +3 -0
  221. vendor/dhii/collections-interface/composer.json +1 -1
  222. vendor/dhii/collections-interface/psalm.xml.dist +0 -1
  223. vendor/dhii/containers/.editorconfig +16 -0
  224. vendor/dhii/containers/.env.example +7 -1
  225. vendor/dhii/containers/CHANGELOG.md +34 -1
  226. vendor/dhii/containers/README.md +143 -6
  227. vendor/dhii/containers/composer.json +12 -8
  228. vendor/dhii/containers/docker-compose.yml +28 -6
  229. vendor/dhii/containers/docker/Dockerfile +39 -0
  230. vendor/dhii/containers/docker/Dockerfile_php +0 -6
  231. vendor/dhii/containers/phpcs.xml.dist +39 -33
  232. vendor/dhii/containers/phpmd.xml +0 -24
  233. vendor/dhii/containers/phpunit.xml.dist +26 -0
  234. vendor/dhii/containers/psalm.xml.dist +152 -0
  235. vendor/dhii/containers/src/AliasingContainer.php +7 -4
  236. vendor/dhii/containers/src/CachingContainer.php +37 -24
  237. vendor/dhii/containers/src/CompositeCachingServiceProvider.php +35 -18
  238. vendor/dhii/containers/src/CompositeContainer.php +17 -8
  239. vendor/dhii/containers/src/DataStructureBasedFactory.php +9 -7
  240. vendor/dhii/containers/src/DataStructureBasedFactoryInterface.php +3 -2
  241. vendor/dhii/containers/src/DelegatingContainer.php +11 -9
  242. vendor/dhii/containers/src/DeprefixingContainer.php +8 -1
  243. vendor/dhii/containers/src/Dictionary.php +27 -3
  244. vendor/dhii/containers/src/DictionaryFactory.php +2 -1
  245. vendor/dhii/containers/src/Exception/ContainerException.php +7 -8
  246. vendor/dhii/containers/src/Exception/NotFoundException.php +7 -5
  247. vendor/dhii/containers/src/FlashContainer.php +135 -0
  248. vendor/dhii/containers/src/HierarchyContainer.php +11 -5
  249. vendor/dhii/containers/src/MappingContainer.php +7 -5
  250. vendor/dhii/containers/src/MaskingContainer.php +6 -5
  251. vendor/dhii/containers/src/NoOpContainer.php +99 -0
  252. vendor/dhii/containers/src/PathContainer.php +22 -4
  253. vendor/dhii/containers/src/PrefixingContainer.php +10 -3
  254. vendor/dhii/containers/src/ProxyContainer.php +4 -2
  255. vendor/dhii/containers/src/SegmentingContainer.php +4 -1
  256. vendor/dhii/containers/src/ServiceProvider.php +3 -1
  257. vendor/dhii/containers/src/SimpleCacheContainer.php +111 -0
  258. vendor/dhii/containers/src/Util/StringTranslatingTrait.php +14 -9
  259. vendor/dhii/containers/tests/bootstrap.php +5 -0
  260. vendor/dhii/containers/tests/functional/AliasingContainerTest.php +148 -0
  261. vendor/dhii/containers/tests/functional/CachingContainerTest.php +93 -0
  262. vendor/dhii/containers/tests/functional/CompositeCachingServiceProviderTest.php +108 -0
  263. vendor/dhii/containers/tests/functional/CompositeContainerTest.php +112 -0
  264. vendor/dhii/containers/tests/functional/DataStructureBasedFactoryTest.php +80 -0
  265. vendor/dhii/containers/tests/functional/DelegatingContainerTest.php +90 -0
  266. vendor/dhii/containers/tests/functional/DeprefixingContainerTest.php +167 -0
  267. vendor/dhii/containers/tests/functional/DictionaryTest.php +125 -0
  268. vendor/dhii/containers/tests/functional/Exception/ContainerExceptionTest.php +60 -0
  269. vendor/dhii/containers/tests/functional/Exception/NotFoundExceptionTest.php +59 -0
  270. vendor/dhii/containers/tests/functional/FlashContainerTest.php +124 -0
  271. vendor/dhii/containers/tests/functional/HierarchyContainerTest.php +158 -0
  272. vendor/dhii/containers/tests/functional/MappingContainerTest.php +125 -0
  273. vendor/dhii/containers/tests/functional/MaskingContainerTest.php +187 -0
  274. vendor/dhii/containers/tests/functional/NoOpContainerTest.php +60 -0
  275. vendor/dhii/containers/tests/functional/PathContainerTest.php +159 -0
  276. vendor/dhii/containers/tests/functional/PrefixingContainerTest.php +335 -0
  277. vendor/dhii/containers/tests/functional/SegmentingContainerTest.php +162 -0
  278. vendor/dhii/containers/tests/functional/ServiceProviderTest.php +56 -0
  279. vendor/dhii/containers/tests/functional/SimpleCacheContainerTest.php +101 -0
  280. vendor/dhii/containers/tests/helpers/AbstractMockHelper.php +70 -0
  281. vendor/dhii/containers/tests/helpers/ComponentMockeryTrait.php +258 -0
  282. vendor/dhii/containers/tests/helpers/ContainerMock.php +156 -0
  283. vendor/dhii/containers/tests/helpers/InvocableMock.php +99 -0
  284. vendor/dhii/containers/tests/helpers/ServiceProviderMock.php +69 -0
  285. vendor/dhii/containers/tests/system/MultipleAccessTypesWithMapsTest.php +93 -0
  286. vendor/dhii/containers/tests/unit/CompositeCachingServiceProviderTest.php +100 -0
  287. vendor/dhii/containers/tests/unit/ProxyContainerTest.php +84 -0
  288. vendor/dhii/data-container-interface/CHANGELOG.md +0 -38
  289. vendor/dhii/data-container-interface/LICENSE +0 -19
  290. vendor/dhii/data-container-interface/README.md +0 -79
  291. vendor/dhii/data-container-interface/composer.json +0 -50
  292. vendor/dhii/data-container-interface/src/ClearCapableContainerInterface.php +0 -16
  293. vendor/dhii/data-container-interface/src/ClearCapableInterface.php +0 -22
  294. vendor/dhii/data-container-interface/src/ContainerAwareInterface.php +0 -22
  295. vendor/dhii/data-container-interface/src/ContainerFactoryInterface.php +0 -38
  296. vendor/dhii/data-container-interface/src/ContainerInterface.php +0 -30
  297. vendor/dhii/data-container-interface/src/DataKeyAwareInterface.php +0 -22
  298. vendor/dhii/data-container-interface/src/DeleteCapableContainerInterface.php +0 -28
  299. vendor/dhii/data-container-interface/src/DeleteCapableInterface.php +0 -25
  300. vendor/dhii/data-container-interface/src/Exception/ContainerExceptionInterface.php +0 -19
  301. vendor/dhii/data-container-interface/src/Exception/NotFoundExceptionInterface.php +0 -18
  302. vendor/dhii/data-container-interface/src/HasCapableInterface.php +0 -27
  303. vendor/dhii/data-container-interface/src/SetCapableContainerInterface.php +0 -14
  304. vendor/dhii/data-container-interface/src/SetCapableInterface.php +0 -26
  305. vendor/dhii/data-container-interface/src/WritableContainerInterface.php +0 -14
  306. vendor/dhii/exception-interface/CHANGELOG.md +0 -27
  307. vendor/dhii/exception-interface/LICENSE +0 -19
  308. vendor/dhii/exception-interface/README.md +0 -46
  309. vendor/dhii/exception-interface/composer.json +0 -44
  310. vendor/dhii/exception-interface/phpmd.xml +0 -25
  311. vendor/dhii/exception-interface/src/ArgumentCodeAwareInterface.php +0 -24
  312. vendor/dhii/exception-interface/src/BadSubjectExceptionInterface.php +0 -20
  313. vendor/dhii/exception-interface/src/InternalExceptionInterface.php +0 -27
  314. vendor/dhii/exception-interface/src/InvalidArgumentExceptionInterface.php +0 -12
  315. vendor/dhii/exception-interface/src/OutOfBoundsExceptionInterface.php +0 -12
  316. vendor/dhii/exception-interface/src/OutOfRangeExceptionInterface.php +0 -12
  317. vendor/dhii/exception-interface/src/RuntimeExceptionInterface.php +0 -12
  318. vendor/dhii/exception-interface/src/ThrowableInterface.php +0 -89
  319. vendor/dhii/factory-interface/CHANGELOG.md +0 -19
  320. vendor/dhii/factory-interface/LICENSE +0 -21
  321. vendor/dhii/factory-interface/README.md +0 -22
  322. vendor/dhii/factory-interface/composer.json +0 -46
  323. vendor/dhii/factory-interface/phpmd.xml +0 -25
  324. vendor/dhii/factory-interface/src/DataObjectFactoryInterface.php +0 -20
  325. vendor/dhii/factory-interface/src/Exception/CouldNotMakeExceptionInterface.php +0 -23
  326. vendor/dhii/factory-interface/src/Exception/FactoryExceptionInterface.php +0 -17
  327. vendor/dhii/factory-interface/src/FactoryAwareInterface.php +0 -20
  328. vendor/dhii/factory-interface/src/FactoryFactoryInterface.php +0 -20
  329. vendor/dhii/factory-interface/src/FactoryInterface.php +0 -32
  330. vendor/dhii/stringable-interface/.php_cs +0 -23
  331. vendor/dhii/stringable-interface/CHANGELOG.md +0 -12
  332. vendor/dhii/stringable-interface/README.md +0 -7
  333. vendor/dhii/stringable-interface/composer.json +0 -27
  334. vendor/dhii/stringable-interface/composer.lock +0 -1620
changelog.txt CHANGED
@@ -1,5 +1,22 @@
1
  *** Changelog ***
2
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3
  = 1.6.1 - 2021-10-12 =
4
  * Fix - Handle authorization capture failures #312
5
  * Fix - Handle denied payment authorization #302
1
  *** Changelog ***
2
 
3
+ = 1.6.2 - 2021-11-22 =
4
+ * Fix - Order of WooCommerce checkout actions causing incompatibility with AvaTax address validation #335
5
+ * Fix - Can't checkout to certain countries with optional postcode #330
6
+ * Fix - Prevent subscription from being purchased when saving payment fails #308
7
+ * Fix - Guest users must checkout twice for subscriptions, no smart buttons loaded #342
8
+ * Fix - Failed PayPal API request causing strange error #347
9
+ * Fix - PayPal payments page empty after switching packages #350
10
+ * Fix - Could Not Validate Nonce Error #239
11
+ * Fix - Refund via PayPal dashboard does not set the WooCommerce order to "Refunded" #241
12
+ * Fix - Uncaught TypeError: round() #344
13
+ * Fix - Broken multi-level (nested) associative array values after getting submitted from checkout page #307
14
+ * Fix - Transaction id missing in some cases #328
15
+ * Fix - Payment not possible in pay for order form because of terms checkbox missing #294
16
+ * Fix - "Save your Credit Card" shouldn't be optional when paying for a subscription #368
17
+ * Fix - When paying for a subscription and vaulting fails, cart is cleared #367
18
+ * Fix - Fatal error when activating PayPal Checkout plugin #363
19
+
20
  = 1.6.1 - 2021-10-12 =
21
  * Fix - Handle authorization capture failures #312
22
  * Fix - Handle denied payment authorization #302
modules/ppcp-admin-notices/composer.json ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "woocommerce/ppcp-admin-notices",
3
+ "type": "dhii-mod",
4
+ "description": "Admin notices module for PPCP",
5
+ "license": "GPL-2.0",
6
+ "require": {
7
+ "php": "^7.1 | ^8.0",
8
+ "dhii/module-interface": "^0.3.0-alpha1"
9
+ },
10
+ "autoload": {
11
+ "psr-4": {
12
+ "WooCommerce\\PayPalCommerce\\AdminNotices\\": "src"
13
+ }
14
+ },
15
+ "minimum-stability": "dev",
16
+ "prefer-stable": true
17
+ }
modules/ppcp-admin-notices/services.php CHANGED
@@ -9,19 +9,19 @@ declare(strict_types=1);
9
 
10
  namespace WooCommerce\PayPalCommerce\AdminNotices;
11
 
12
- use Dhii\Data\Container\ContainerInterface;
13
  use WooCommerce\PayPalCommerce\AdminNotices\Renderer\Renderer;
14
  use WooCommerce\PayPalCommerce\AdminNotices\Renderer\RendererInterface;
15
  use WooCommerce\PayPalCommerce\AdminNotices\Repository\Repository;
16
  use WooCommerce\PayPalCommerce\AdminNotices\Repository\RepositoryInterface;
17
 
18
  return array(
19
- 'admin-notices.renderer' => static function ( $container ): RendererInterface {
20
 
21
  $repository = $container->get( 'admin-notices.repository' );
22
  return new Renderer( $repository );
23
  },
24
- 'admin-notices.repository' => static function ( $container ): RepositoryInterface {
25
 
26
  return new Repository();
27
  },
9
 
10
  namespace WooCommerce\PayPalCommerce\AdminNotices;
11
 
12
+ use Psr\Container\ContainerInterface;
13
  use WooCommerce\PayPalCommerce\AdminNotices\Renderer\Renderer;
14
  use WooCommerce\PayPalCommerce\AdminNotices\Renderer\RendererInterface;
15
  use WooCommerce\PayPalCommerce\AdminNotices\Repository\Repository;
16
  use WooCommerce\PayPalCommerce\AdminNotices\Repository\RepositoryInterface;
17
 
18
  return array(
19
+ 'admin-notices.renderer' => static function ( ContainerInterface $container ): RendererInterface {
20
 
21
  $repository = $container->get( 'admin-notices.repository' );
22
  return new Renderer( $repository );
23
  },
24
+ 'admin-notices.repository' => static function ( ContainerInterface $container ): RepositoryInterface {
25
 
26
  return new Repository();
27
  },
modules/ppcp-admin-notices/src/{class-adminnotices.php → AdminNotices.php} RENAMED
@@ -20,9 +20,7 @@ use Psr\Container\ContainerInterface;
20
  class AdminNotices implements ModuleInterface {
21
 
22
  /**
23
- * Sets up the module.
24
- *
25
- * @return ServiceProviderInterface
26
  */
27
  public function setup(): ServiceProviderInterface {
28
  return new ServiceProvider(
@@ -32,15 +30,13 @@ class AdminNotices implements ModuleInterface {
32
  }
33
 
34
  /**
35
- * Runs the module.
36
- *
37
- * @param ContainerInterface $container The container.
38
  */
39
- public function run( ContainerInterface $container ): void {
40
  add_action(
41
  'admin_notices',
42
- function() use ( $container ) {
43
- $renderer = $container->get( 'admin-notices.renderer' );
44
  $renderer->render();
45
  }
46
  );
20
  class AdminNotices implements ModuleInterface {
21
 
22
  /**
23
+ * {@inheritDoc}
 
 
24
  */
25
  public function setup(): ServiceProviderInterface {
26
  return new ServiceProvider(
30
  }
31
 
32
  /**
33
+ * {@inheritDoc}
 
 
34
  */
35
+ public function run( ContainerInterface $c ): void {
36
  add_action(
37
  'admin_notices',
38
+ function() use ( $c ) {
39
+ $renderer = $c->get( 'admin-notices.renderer' );
40
  $renderer->render();
41
  }
42
  );
modules/ppcp-admin-notices/src/Entity/{class-message.php → Message.php} RENAMED
File without changes
modules/ppcp-admin-notices/src/Renderer/{class-renderer.php → Renderer.php} RENAMED
File without changes
modules/ppcp-admin-notices/src/Renderer/{class-rendererinterface.php → RendererInterface.php} RENAMED
File without changes
modules/ppcp-admin-notices/src/Repository/{class-repository.php → Repository.php} RENAMED
File without changes
modules/ppcp-admin-notices/src/Repository/{class-repositoryinterface.php → RepositoryInterface.php} RENAMED
File without changes
modules/ppcp-api-client/composer.json ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "woocommerce/ppcp-api-client",
3
+ "type": "dhii-mod",
4
+ "description": "API client module for PPCP",
5
+ "license": "GPL-2.0",
6
+ "require": {
7
+ "php": "^7.1 | ^8.0",
8
+ "dhii/module-interface": "^0.3.0-alpha1"
9
+ },
10
+ "autoload": {
11
+ "psr-4": {
12
+ "WooCommerce\\PayPalCommerce\\ApiClient\\": "src"
13
+ }
14
+ },
15
+ "minimum-stability": "dev",
16
+ "prefer-stable": true
17
+ }
modules/ppcp-api-client/services.php CHANGED
@@ -9,6 +9,7 @@ declare(strict_types=1);
9
 
10
  namespace WooCommerce\PayPalCommerce\ApiClient;
11
 
 
12
  use WooCommerce\PayPalCommerce\ApiClient\Authentication\Bearer;
13
  use WooCommerce\PayPalCommerce\ApiClient\Authentication\PayPalBearer;
14
  use WooCommerce\PayPalCommerce\ApiClient\Endpoint\IdentityToken;
@@ -47,10 +48,10 @@ use WooCommerce\PayPalCommerce\ApiClient\Repository\PayPalRequestIdRepository;
47
  use WooCommerce\PayPalCommerce\WcGateway\Settings\Settings;
48
 
49
  return array(
50
- 'api.host' => function( $container ) : string {
51
  return PAYPAL_API_URL;
52
  },
53
- 'api.paypal-host' => function( $container ) : string {
54
  return PAYPAL_API_URL;
55
  },
56
  'api.partner_merchant_id' => static function () : string {
@@ -71,7 +72,7 @@ return array(
71
  'api.prefix' => static function (): string {
72
  return 'WC-';
73
  },
74
- 'api.bearer' => static function ( $container ): Bearer {
75
  $cache = new Cache( 'ppcp-paypal-bearer' );
76
  $key = $container->get( 'api.key' );
77
  $secret = $container->get( 'api.secret' );
@@ -87,7 +88,7 @@ return array(
87
  $settings
88
  );
89
  },
90
- 'api.endpoint.partners' => static function ( $container ) : PartnersEndpoint {
91
  return new PartnersEndpoint(
92
  $container->get( 'api.host' ),
93
  $container->get( 'api.bearer' ),
@@ -97,10 +98,10 @@ return array(
97
  $container->get( 'api.merchant_id' )
98
  );
99
  },
100
- 'api.factory.sellerstatus' => static function ( $container ) : SellerStatusFactory {
101
  return new SellerStatusFactory();
102
  },
103
- 'api.endpoint.payment-token' => static function ( $container ) : PaymentTokenEndpoint {
104
  return new PaymentTokenEndpoint(
105
  $container->get( 'api.host' ),
106
  $container->get( 'api.bearer' ),
@@ -109,7 +110,7 @@ return array(
109
  $container->get( 'api.prefix' )
110
  );
111
  },
112
- 'api.endpoint.webhook' => static function ( $container ) : WebhookEndpoint {
113
 
114
  return new WebhookEndpoint(
115
  $container->get( 'api.host' ),
@@ -119,7 +120,7 @@ return array(
119
  $container->get( 'woocommerce.logger.woocommerce' )
120
  );
121
  },
122
- 'api.endpoint.partner-referrals' => static function ( $container ) : PartnerReferrals {
123
 
124
  return new PartnerReferrals(
125
  $container->get( 'api.host' ),
@@ -128,7 +129,7 @@ return array(
128
  $container->get( 'woocommerce.logger.woocommerce' )
129
  );
130
  },
131
- 'api.endpoint.identity-token' => static function ( $container ) : IdentityToken {
132
 
133
  $logger = $container->get( 'woocommerce.logger.woocommerce' );
134
  $prefix = $container->get( 'api.prefix' );
@@ -139,7 +140,7 @@ return array(
139
  $prefix
140
  );
141
  },
142
- 'api.endpoint.payments' => static function ( $container ): PaymentsEndpoint {
143
  $authorizations_factory = $container->get( 'api.factory.authorization' );
144
  $capture_factory = $container->get( 'api.factory.capture' );
145
  $logger = $container->get( 'woocommerce.logger.woocommerce' );
@@ -152,7 +153,7 @@ return array(
152
  $logger
153
  );
154
  },
155
- 'api.endpoint.login-seller' => static function ( $container ) : LoginSeller {
156
 
157
  $logger = $container->get( 'woocommerce.logger.woocommerce' );
158
  return new LoginSeller(
@@ -161,7 +162,7 @@ return array(
161
  $logger
162
  );
163
  },
164
- 'api.endpoint.order' => static function ( $container ): OrderEndpoint {
165
  $order_factory = $container->get( 'api.factory.order' );
166
  $patch_collection_factory = $container->get( 'api.factory.patch-collection-factory' );
167
  $logger = $container->get( 'woocommerce.logger.woocommerce' );
@@ -175,6 +176,7 @@ return array(
175
  $intent = $settings->has( 'intent' ) && strtoupper( (string) $settings->get( 'intent' ) ) === 'AUTHORIZE' ? 'AUTHORIZE' : 'CAPTURE';
176
  $application_context_repository = $container->get( 'api.repository.application-context' );
177
  $paypal_request_id = $container->get( 'api.repository.paypal-request-id' );
 
178
  return new OrderEndpoint(
179
  $container->get( 'api.host' ),
180
  $container->get( 'api.bearer' ),
@@ -183,50 +185,51 @@ return array(
183
  $intent,
184
  $logger,
185
  $application_context_repository,
186
- $paypal_request_id
 
187
  );
188
  },
189
- 'api.repository.paypal-request-id' => static function( $container ) : PayPalRequestIdRepository {
190
  return new PayPalRequestIdRepository();
191
  },
192
- 'api.repository.application-context' => static function( $container ) : ApplicationContextRepository {
193
 
194
  $settings = $container->get( 'wcgateway.settings' );
195
  return new ApplicationContextRepository( $settings );
196
  },
197
- 'api.repository.partner-referrals-data' => static function ( $container ) : PartnerReferralsData {
198
 
199
  $merchant_email = $container->get( 'api.merchant_email' );
200
  $dcc_applies = $container->get( 'api.helpers.dccapplies' );
201
  return new PartnerReferralsData( $merchant_email, $dcc_applies );
202
  },
203
- 'api.repository.cart' => static function ( $container ): CartRepository {
204
  $factory = $container->get( 'api.factory.purchase-unit' );
205
  return new CartRepository( $factory );
206
  },
207
- 'api.repository.payee' => static function ( $container ): PayeeRepository {
208
  $merchant_email = $container->get( 'api.merchant_email' );
209
  $merchant_id = $container->get( 'api.merchant_id' );
210
  return new PayeeRepository( $merchant_email, $merchant_id );
211
  },
212
- 'api.factory.application-context' => static function ( $container ) : ApplicationContextFactory {
213
  return new ApplicationContextFactory();
214
  },
215
- 'api.factory.payment-token' => static function ( $container ) : PaymentTokenFactory {
216
  return new PaymentTokenFactory();
217
  },
218
- 'api.factory.webhook' => static function ( $container ): WebhookFactory {
219
  return new WebhookFactory();
220
  },
221
- 'api.factory.webhook-event' => static function ( $container ): WebhookEventFactory {
222
  return new WebhookEventFactory();
223
  },
224
- 'api.factory.capture' => static function ( $container ): CaptureFactory {
225
 
226
  $amount_factory = $container->get( 'api.factory.amount' );
227
  return new CaptureFactory( $amount_factory );
228
  },
229
- 'api.factory.purchase-unit' => static function ( $container ): PurchaseUnitFactory {
230
 
231
  $amount_factory = $container->get( 'api.factory.amount' );
232
  $payee_repository = $container->get( 'api.repository.payee' );
@@ -246,34 +249,34 @@ return array(
246
  $prefix
247
  );
248
  },
249
- 'api.factory.patch-collection-factory' => static function ( $container ): PatchCollectionFactory {
250
  return new PatchCollectionFactory();
251
  },
252
- 'api.factory.payee' => static function ( $container ): PayeeFactory {
253
  return new PayeeFactory();
254
  },
255
- 'api.factory.item' => static function ( $container ): ItemFactory {
256
  return new ItemFactory();
257
  },
258
- 'api.factory.shipping' => static function ( $container ): ShippingFactory {
259
  $address_factory = $container->get( 'api.factory.address' );
260
  return new ShippingFactory( $address_factory );
261
  },
262
- 'api.factory.amount' => static function ( $container ): AmountFactory {
263
  $item_factory = $container->get( 'api.factory.item' );
264
  return new AmountFactory( $item_factory );
265
  },
266
- 'api.factory.payer' => static function ( $container ): PayerFactory {
267
  $address_factory = $container->get( 'api.factory.address' );
268
  return new PayerFactory( $address_factory );
269
  },
270
- 'api.factory.address' => static function ( $container ): AddressFactory {
271
  return new AddressFactory();
272
  },
273
- 'api.factory.payment-source' => static function ( $container ): PaymentSourceFactory {
274
  return new PaymentSourceFactory();
275
  },
276
- 'api.factory.order' => static function ( $container ): OrderFactory {
277
  $purchase_unit_factory = $container->get( 'api.factory.purchase-unit' );
278
  $payer_factory = $container->get( 'api.factory.payer' );
279
  $application_context_repository = $container->get( 'api.repository.application-context' );
@@ -287,15 +290,15 @@ return array(
287
  $payment_source_factory
288
  );
289
  },
290
- 'api.factory.payments' => static function ( $container ): PaymentsFactory {
291
  $authorizations_factory = $container->get( 'api.factory.authorization' );
292
  $capture_factory = $container->get( 'api.factory.capture' );
293
  return new PaymentsFactory( $authorizations_factory, $capture_factory );
294
  },
295
- 'api.factory.authorization' => static function ( $container ): AuthorizationFactory {
296
  return new AuthorizationFactory();
297
  },
298
- 'api.helpers.dccapplies' => static function ( $container ) : DccApplies {
299
  return new DccApplies();
300
  },
301
  );
9
 
10
  namespace WooCommerce\PayPalCommerce\ApiClient;
11
 
12
+ use Psr\Container\ContainerInterface;
13
  use WooCommerce\PayPalCommerce\ApiClient\Authentication\Bearer;
14
  use WooCommerce\PayPalCommerce\ApiClient\Authentication\PayPalBearer;
15
  use WooCommerce\PayPalCommerce\ApiClient\Endpoint\IdentityToken;
48
  use WooCommerce\PayPalCommerce\WcGateway\Settings\Settings;
49
 
50
  return array(
51
+ 'api.host' => function( ContainerInterface $container ) : string {
52
  return PAYPAL_API_URL;
53
  },
54
+ 'api.paypal-host' => function( ContainerInterface $container ) : string {
55
  return PAYPAL_API_URL;
56
  },
57
  'api.partner_merchant_id' => static function () : string {
72
  'api.prefix' => static function (): string {
73
  return 'WC-';
74
  },
75
+ 'api.bearer' => static function ( ContainerInterface $container ): Bearer {
76
  $cache = new Cache( 'ppcp-paypal-bearer' );
77
  $key = $container->get( 'api.key' );
78
  $secret = $container->get( 'api.secret' );
88
  $settings
89
  );
90
  },
91
+ 'api.endpoint.partners' => static function ( ContainerInterface $container ) : PartnersEndpoint {
92
  return new PartnersEndpoint(
93
  $container->get( 'api.host' ),
94
  $container->get( 'api.bearer' ),
98
  $container->get( 'api.merchant_id' )
99
  );
100
  },
101
+ 'api.factory.sellerstatus' => static function ( ContainerInterface $container ) : SellerStatusFactory {
102
  return new SellerStatusFactory();
103
  },
104
+ 'api.endpoint.payment-token' => static function ( ContainerInterface $container ) : PaymentTokenEndpoint {
105
  return new PaymentTokenEndpoint(
106
  $container->get( 'api.host' ),
107
  $container->get( 'api.bearer' ),
110
  $container->get( 'api.prefix' )
111
  );
112
  },
113
+ 'api.endpoint.webhook' => static function ( ContainerInterface $container ) : WebhookEndpoint {
114
 
115
  return new WebhookEndpoint(
116
  $container->get( 'api.host' ),
120
  $container->get( 'woocommerce.logger.woocommerce' )
121
  );
122
  },
123
+ 'api.endpoint.partner-referrals' => static function ( ContainerInterface $container ) : PartnerReferrals {
124
 
125
  return new PartnerReferrals(
126
  $container->get( 'api.host' ),
129
  $container->get( 'woocommerce.logger.woocommerce' )
130
  );
131
  },
132
+ 'api.endpoint.identity-token' => static function ( ContainerInterface $container ) : IdentityToken {
133
 
134
  $logger = $container->get( 'woocommerce.logger.woocommerce' );
135
  $prefix = $container->get( 'api.prefix' );
140
  $prefix
141
  );
142
  },
143
+ 'api.endpoint.payments' => static function ( ContainerInterface $container ): PaymentsEndpoint {
144
  $authorizations_factory = $container->get( 'api.factory.authorization' );
145
  $capture_factory = $container->get( 'api.factory.capture' );
146
  $logger = $container->get( 'woocommerce.logger.woocommerce' );
153
  $logger
154
  );
155
  },
156
+ 'api.endpoint.login-seller' => static function ( ContainerInterface $container ) : LoginSeller {
157
 
158
  $logger = $container->get( 'woocommerce.logger.woocommerce' );
159
  return new LoginSeller(
162
  $logger
163
  );
164
  },
165
+ 'api.endpoint.order' => static function ( ContainerInterface $container ): OrderEndpoint {
166
  $order_factory = $container->get( 'api.factory.order' );
167
  $patch_collection_factory = $container->get( 'api.factory.patch-collection-factory' );
168
  $logger = $container->get( 'woocommerce.logger.woocommerce' );
176
  $intent = $settings->has( 'intent' ) && strtoupper( (string) $settings->get( 'intent' ) ) === 'AUTHORIZE' ? 'AUTHORIZE' : 'CAPTURE';
177
  $application_context_repository = $container->get( 'api.repository.application-context' );
178
  $paypal_request_id = $container->get( 'api.repository.paypal-request-id' );
179
+ $subscription_helper = $container->get( 'subscription.helper' );
180
  return new OrderEndpoint(
181
  $container->get( 'api.host' ),
182
  $container->get( 'api.bearer' ),
185
  $intent,
186
  $logger,
187
  $application_context_repository,
188
+ $paypal_request_id,
189
+ $subscription_helper
190
  );
191
  },
192
+ 'api.repository.paypal-request-id' => static function( ContainerInterface $container ) : PayPalRequestIdRepository {
193
  return new PayPalRequestIdRepository();
194
  },
195
+ 'api.repository.application-context' => static function( ContainerInterface $container ) : ApplicationContextRepository {
196
 
197
  $settings = $container->get( 'wcgateway.settings' );
198
  return new ApplicationContextRepository( $settings );
199
  },
200
+ 'api.repository.partner-referrals-data' => static function ( ContainerInterface $container ) : PartnerReferralsData {
201
 
202
  $merchant_email = $container->get( 'api.merchant_email' );
203
  $dcc_applies = $container->get( 'api.helpers.dccapplies' );
204
  return new PartnerReferralsData( $merchant_email, $dcc_applies );
205
  },
206
+ 'api.repository.cart' => static function ( ContainerInterface $container ): CartRepository {
207
  $factory = $container->get( 'api.factory.purchase-unit' );
208
  return new CartRepository( $factory );
209
  },
210
+ 'api.repository.payee' => static function ( ContainerInterface $container ): PayeeRepository {
211
  $merchant_email = $container->get( 'api.merchant_email' );
212
  $merchant_id = $container->get( 'api.merchant_id' );
213
  return new PayeeRepository( $merchant_email, $merchant_id );
214
  },
215
+ 'api.factory.application-context' => static function ( ContainerInterface $container ) : ApplicationContextFactory {
216
  return new ApplicationContextFactory();
217
  },
218
+ 'api.factory.payment-token' => static function ( ContainerInterface $container ) : PaymentTokenFactory {
219
  return new PaymentTokenFactory();
220
  },
221
+ 'api.factory.webhook' => static function ( ContainerInterface $container ): WebhookFactory {
222
  return new WebhookFactory();
223
  },
224
+ 'api.factory.webhook-event' => static function ( ContainerInterface $container ): WebhookEventFactory {
225
  return new WebhookEventFactory();
226
  },
227
+ 'api.factory.capture' => static function ( ContainerInterface $container ): CaptureFactory {
228
 
229
  $amount_factory = $container->get( 'api.factory.amount' );
230
  return new CaptureFactory( $amount_factory );
231
  },
232
+ 'api.factory.purchase-unit' => static function ( ContainerInterface $container ): PurchaseUnitFactory {
233
 
234
  $amount_factory = $container->get( 'api.factory.amount' );
235
  $payee_repository = $container->get( 'api.repository.payee' );
249
  $prefix
250
  );
251
  },
252
+ 'api.factory.patch-collection-factory' => static function ( ContainerInterface $container ): PatchCollectionFactory {
253
  return new PatchCollectionFactory();
254
  },
255
+ 'api.factory.payee' => static function ( ContainerInterface $container ): PayeeFactory {
256
  return new PayeeFactory();
257
  },
258
+ 'api.factory.item' => static function ( ContainerInterface $container ): ItemFactory {
259
  return new ItemFactory();
260
  },
261
+ 'api.factory.shipping' => static function ( ContainerInterface $container ): ShippingFactory {
262
  $address_factory = $container->get( 'api.factory.address' );
263
  return new ShippingFactory( $address_factory );
264
  },
265
+ 'api.factory.amount' => static function ( ContainerInterface $container ): AmountFactory {
266
  $item_factory = $container->get( 'api.factory.item' );
267
  return new AmountFactory( $item_factory );
268
  },
269
+ 'api.factory.payer' => static function ( ContainerInterface $container ): PayerFactory {
270
  $address_factory = $container->get( 'api.factory.address' );
271
  return new PayerFactory( $address_factory );
272
  },
273
+ 'api.factory.address' => static function ( ContainerInterface $container ): AddressFactory {
274
  return new AddressFactory();
275
  },
276
+ 'api.factory.payment-source' => static function ( ContainerInterface $container ): PaymentSourceFactory {
277
  return new PaymentSourceFactory();
278
  },
279
+ 'api.factory.order' => static function ( ContainerInterface $container ): OrderFactory {
280
  $purchase_unit_factory = $container->get( 'api.factory.purchase-unit' );
281
  $payer_factory = $container->get( 'api.factory.payer' );
282
  $application_context_repository = $container->get( 'api.repository.application-context' );
290
  $payment_source_factory
291
  );
292
  },
293
+ 'api.factory.payments' => static function ( ContainerInterface $container ): PaymentsFactory {
294
  $authorizations_factory = $container->get( 'api.factory.authorization' );
295
  $capture_factory = $container->get( 'api.factory.capture' );
296
  return new PaymentsFactory( $authorizations_factory, $capture_factory );
297
  },
298
+ 'api.factory.authorization' => static function ( ContainerInterface $container ): AuthorizationFactory {
299
  return new AuthorizationFactory();
300
  },
301
+ 'api.helpers.dccapplies' => static function ( ContainerInterface $container ) : DccApplies {
302
  return new DccApplies();
303
  },
304
  );
modules/ppcp-api-client/src/{class-apimodule.php → ApiModule.php} RENAMED
@@ -20,9 +20,7 @@ use Psr\Container\ContainerInterface;
20
  class ApiModule implements ModuleInterface {
21
 
22
  /**
23
- * Sets up the module.
24
- *
25
- * @return ServiceProviderInterface
26
  */
27
  public function setup(): ServiceProviderInterface {
28
  return new ServiceProvider(
@@ -32,11 +30,9 @@ class ApiModule implements ModuleInterface {
32
  }
33
 
34
  /**
35
- * Runs the module.
36
- *
37
- * @param ContainerInterface $container The container.
38
  */
39
- public function run( ContainerInterface $container ): void {
40
  add_action(
41
  'woocommerce_after_calculate_totals',
42
  function ( \WC_Cart $cart ) {
20
  class ApiModule implements ModuleInterface {
21
 
22
  /**
23
+ * {@inheritDoc}
 
 
24
  */
25
  public function setup(): ServiceProviderInterface {
26
  return new ServiceProvider(
30
  }
31
 
32
  /**
33
+ * {@inheritDoc}
 
 
34
  */
35
+ public function run( ContainerInterface $c ): void {
36
  add_action(
37
  'woocommerce_after_calculate_totals',
38
  function ( \WC_Cart $cart ) {
modules/ppcp-api-client/src/Authentication/{class-bearer.php → Bearer.php} RENAMED
File without changes
modules/ppcp-api-client/src/Authentication/{class-connectbearer.php → ConnectBearer.php} RENAMED
File without changes
modules/ppcp-api-client/src/Authentication/{class-paypalbearer.php → PayPalBearer.php} RENAMED
File without changes
modules/ppcp-api-client/src/Endpoint/{class-identitytoken.php → IdentityToken.php} RENAMED
File without changes
modules/ppcp-api-client/src/Endpoint/{class-loginseller.php → LoginSeller.php} RENAMED
File without changes
modules/ppcp-api-client/src/Endpoint/{class-orderendpoint.php → OrderEndpoint.php} RENAMED
@@ -27,6 +27,7 @@ use WooCommerce\PayPalCommerce\ApiClient\Helper\ErrorResponse;
27
  use WooCommerce\PayPalCommerce\ApiClient\Repository\ApplicationContextRepository;
28
  use WooCommerce\PayPalCommerce\ApiClient\Repository\PayPalRequestIdRepository;
29
  use Psr\Log\LoggerInterface;
 
30
 
31
  /**
32
  * Class OrderEndpoint
@@ -35,6 +36,13 @@ class OrderEndpoint {
35
 
36
  use RequestTrait;
37
 
 
 
 
 
 
 
 
38
  /**
39
  * The host.
40
  *
@@ -109,6 +117,7 @@ class OrderEndpoint {
109
  * @param LoggerInterface $logger The logger.
110
  * @param ApplicationContextRepository $application_context_repository The application context repository.
111
  * @param PayPalRequestIdRepository $paypal_request_id_repository The paypal request id repository.
 
112
  * @param string $bn_code The BN Code.
113
  */
114
  public function __construct(
@@ -120,6 +129,7 @@ class OrderEndpoint {
120
  LoggerInterface $logger,
121
  ApplicationContextRepository $application_context_repository,
122
  PayPalRequestIdRepository $paypal_request_id_repository,
 
123
  string $bn_code = ''
124
  ) {
125
 
@@ -132,6 +142,7 @@ class OrderEndpoint {
132
  $this->application_context_repository = $application_context_repository;
133
  $this->bn_code = $bn_code;
134
  $this->paypal_request_id_repository = $paypal_request_id_repository;
 
135
  }
136
 
137
  /**
@@ -193,9 +204,13 @@ class OrderEndpoint {
193
  : ApplicationContext::SHIPPING_PREFERENCE_GET_FROM_FILE
194
  : ApplicationContext::SHIPPING_PREFERENCE_NO_SHIPPING;
195
 
 
 
 
 
196
  $bearer = $this->bearer->bearer();
197
  $data = array(
198
- 'intent' => $this->intent,
199
  'purchase_units' => array_map(
200
  static function ( PurchaseUnit $item ): array {
201
  return $item->to_array();
@@ -572,4 +587,20 @@ class OrderEndpoint {
572
  $new_order = $this->order( $order_to_update->id() );
573
  return $new_order;
574
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
575
  }
27
  use WooCommerce\PayPalCommerce\ApiClient\Repository\ApplicationContextRepository;
28
  use WooCommerce\PayPalCommerce\ApiClient\Repository\PayPalRequestIdRepository;
29
  use Psr\Log\LoggerInterface;
30
+ use WooCommerce\PayPalCommerce\Subscription\Helper\SubscriptionHelper;
31
 
32
  /**
33
  * Class OrderEndpoint
36
 
37
  use RequestTrait;
38
 
39
+ /**
40
+ * The subscription helper
41
+ *
42
+ * @var SubscriptionHelper
43
+ */
44
+ protected $subscription_helper;
45
+
46
  /**
47
  * The host.
48
  *
117
  * @param LoggerInterface $logger The logger.
118
  * @param ApplicationContextRepository $application_context_repository The application context repository.
119
  * @param PayPalRequestIdRepository $paypal_request_id_repository The paypal request id repository.
120
+ * @param SubscriptionHelper $subscription_helper The subscription helper.
121
  * @param string $bn_code The BN Code.
122
  */
123
  public function __construct(
129
  LoggerInterface $logger,
130
  ApplicationContextRepository $application_context_repository,
131
  PayPalRequestIdRepository $paypal_request_id_repository,
132
+ SubscriptionHelper $subscription_helper,
133
  string $bn_code = ''
134
  ) {
135
 
142
  $this->application_context_repository = $application_context_repository;
143
  $this->bn_code = $bn_code;
144
  $this->paypal_request_id_repository = $paypal_request_id_repository;
145
+ $this->subscription_helper = $subscription_helper;
146
  }
147
 
148
  /**
204
  : ApplicationContext::SHIPPING_PREFERENCE_GET_FROM_FILE
205
  : ApplicationContext::SHIPPING_PREFERENCE_NO_SHIPPING;
206
 
207
+ if ( $this->has_items_without_shipping( $items ) ) {
208
+ $shipping_preferences = ApplicationContext::SHIPPING_PREFERENCE_NO_SHIPPING;
209
+ }
210
+
211
  $bearer = $this->bearer->bearer();
212
  $data = array(
213
+ 'intent' => ( $this->subscription_helper->cart_contains_subscription() || $this->subscription_helper->current_product_is_subscription() ) ? 'AUTHORIZE' : $this->intent,
214
  'purchase_units' => array_map(
215
  static function ( PurchaseUnit $item ): array {
216
  return $item->to_array();
587
  $new_order = $this->order( $order_to_update->id() );
588
  return $new_order;
589
  }
590
+
591
+ /**
592
+ * Checks if there is at least one item without shipping.
593
+ *
594
+ * @param array $items The items.
595
+ * @return bool Whether items contains shipping or not.
596
+ */
597
+ private function has_items_without_shipping( array $items ): bool {
598
+ foreach ( $items as $item ) {
599
+ if ( ! $item->shipping() ) {
600
+ return true;
601
+ }
602
+ }
603
+
604
+ return false;
605
+ }
606
  }
modules/ppcp-api-client/src/Endpoint/{class-partnerreferrals.php → PartnerReferrals.php} RENAMED
File without changes
modules/ppcp-api-client/src/Endpoint/{class-partnersendpoint.php → PartnersEndpoint.php} RENAMED
File without changes
modules/ppcp-api-client/src/Endpoint/{class-paymenttokenendpoint.php → PaymentTokenEndpoint.php} RENAMED
File without changes
modules/ppcp-api-client/src/Endpoint/{class-paymentsendpoint.php → PaymentsEndpoint.php} RENAMED
@@ -11,7 +11,7 @@ namespace WooCommerce\PayPalCommerce\ApiClient\Endpoint;
11
 
12
  use WooCommerce\PayPalCommerce\ApiClient\Authentication\Bearer;
13
  use WooCommerce\PayPalCommerce\ApiClient\Entity\Authorization;
14
- use Woocommerce\PayPalCommerce\ApiClient\Entity\Capture;
15
  use WooCommerce\PayPalCommerce\ApiClient\Entity\Refund;
16
  use WooCommerce\PayPalCommerce\ApiClient\Exception\PayPalApiException;
17
  use WooCommerce\PayPalCommerce\ApiClient\Exception\RuntimeException;
11
 
12
  use WooCommerce\PayPalCommerce\ApiClient\Authentication\Bearer;
13
  use WooCommerce\PayPalCommerce\ApiClient\Entity\Authorization;
14
+ use WooCommerce\PayPalCommerce\ApiClient\Entity\Capture;
15
  use WooCommerce\PayPalCommerce\ApiClient\Entity\Refund;
16
  use WooCommerce\PayPalCommerce\ApiClient\Exception\PayPalApiException;
17
  use WooCommerce\PayPalCommerce\ApiClient\Exception\RuntimeException;
modules/ppcp-api-client/src/Endpoint/{class-requesttrait.php → RequestTrait.php} RENAMED
@@ -9,6 +9,8 @@ declare(strict_types=1);
9
 
10
  namespace WooCommerce\PayPalCommerce\ApiClient\Endpoint;
11
 
 
 
12
  /**
13
  * Trait RequestTrait
14
  */
@@ -20,7 +22,7 @@ trait RequestTrait {
20
  * @param string $url The URL to request.
21
  * @param array $args The arguments by which to request.
22
  *
23
- * @return array|\WP_Error
24
  */
25
  private function request( string $url, array $args ) {
26
 
@@ -44,12 +46,12 @@ trait RequestTrait {
44
  /**
45
  * Returns request and response information as string.
46
  *
47
- * @param string $url The request URL.
48
- * @param array $args The request arguments.
49
- * @param array $response The response.
50
  * @return string
51
  */
52
- private function request_response_string( string $url, array $args, array $response ): string {
53
  $method = $args['method'] ?? '';
54
  $output = $method . ' ' . $url . "\n";
55
  if ( isset( $args['body'] ) ) {
@@ -65,6 +67,11 @@ trait RequestTrait {
65
  }
66
  }
67
 
 
 
 
 
 
68
  if ( isset( $response['headers']->getAll()['paypal-debug-id'] ) ) {
69
  $output .= 'Response Debug ID: ' . $response['headers']->getAll()['paypal-debug-id'] . "\n";
70
  }
9
 
10
  namespace WooCommerce\PayPalCommerce\ApiClient\Endpoint;
11
 
12
+ use WP_Error;
13
+
14
  /**
15
  * Trait RequestTrait
16
  */
22
  * @param string $url The URL to request.
23
  * @param array $args The arguments by which to request.
24
  *
25
+ * @return array|WP_Error
26
  */
27
  private function request( string $url, array $args ) {
28
 
46
  /**
47
  * Returns request and response information as string.
48
  *
49
+ * @param string $url The request URL.
50
+ * @param array $args The request arguments.
51
+ * @param array|WP_Error $response The response.
52
  * @return string
53
  */
54
+ private function request_response_string( string $url, array $args, $response ): string {
55
  $method = $args['method'] ?? '';
56
  $output = $method . ' ' . $url . "\n";
57
  if ( isset( $args['body'] ) ) {
67
  }
68
  }
69
 
70
+ if ( $response instanceof WP_Error ) {
71
+ $output .= 'Request failed. WP error message: ' . implode( "\n", $response->get_error_messages() ) . "\n";
72
+ return $output;
73
+ }
74
+
75
  if ( isset( $response['headers']->getAll()['paypal-debug-id'] ) ) {
76
  $output .= 'Response Debug ID: ' . $response['headers']->getAll()['paypal-debug-id'] . "\n";
77
  }
modules/ppcp-api-client/src/Endpoint/{class-webhookendpoint.php → WebhookEndpoint.php} RENAMED
File without changes
modules/ppcp-api-client/src/Entity/{class-address.php → Address.php} RENAMED
File without changes
modules/ppcp-api-client/src/Entity/{class-amount.php → Amount.php} RENAMED
File without changes
modules/ppcp-api-client/src/Entity/{class-amountbreakdown.php → AmountBreakdown.php} RENAMED
@@ -17,49 +17,49 @@ class AmountBreakdown {
17
  /**
18
  * The item total.
19
  *
20
- * @var Money
21
  */
22
  private $item_total;
23
 
24
  /**
25
  * The shipping.
26
  *
27
- * @var Money
28
  */
29
  private $shipping;
30
 
31
  /**
32
  * The tax total.
33
  *
34
- * @var Money
35
  */
36
  private $tax_total;
37
 
38
  /**
39
  * The handling.
40
  *
41
- * @var Money
42
  */
43
  private $handling;
44
 
45
  /**
46
  * The insurance.
47
  *
48
- * @var Money
49
  */
50
  private $insurance;
51
 
52
  /**
53
  * The shipping discount.
54
  *
55
- * @var Money
56
  */
57
  private $shipping_discount;
58
 
59
  /**
60
  * The discount.
61
  *
62
- * @var Money
63
  */
64
  private $discount;
65
 
@@ -75,13 +75,13 @@ class AmountBreakdown {
75
  * @param Money|null $discount The discount.
76
  */
77
  public function __construct(
78
- Money $item_total = null,
79
- Money $shipping = null,
80
- Money $tax_total = null,
81
- Money $handling = null,
82
- Money $insurance = null,
83
- Money $shipping_discount = null,
84
- Money $discount = null
85
  ) {
86
 
87
  $this->item_total = $item_total;
17
  /**
18
  * The item total.
19
  *
20
+ * @var Money|null
21
  */
22
  private $item_total;
23
 
24
  /**
25
  * The shipping.
26
  *
27
+ * @var Money|null
28
  */
29
  private $shipping;
30
 
31
  /**
32
  * The tax total.
33
  *
34
+ * @var Money|null
35
  */
36
  private $tax_total;
37
 
38
  /**
39
  * The handling.
40
  *
41
+ * @var Money|null
42
  */
43
  private $handling;
44
 
45
  /**
46
  * The insurance.
47
  *
48
+ * @var Money|null
49
  */
50
  private $insurance;
51
 
52
  /**
53
  * The shipping discount.
54
  *
55
+ * @var Money|null
56
  */
57
  private $shipping_discount;
58
 
59
  /**
60
  * The discount.
61
  *
62
+ * @var Money|null
63
  */
64
  private $discount;
65
 
75
  * @param Money|null $discount The discount.
76
  */
77
  public function __construct(
78
+ ?Money $item_total = null,
79
+ ?Money $shipping = null,
80
+ ?Money $tax_total = null,
81
+ ?Money $handling = null,
82
+ ?Money $insurance = null,
83
+ ?Money $shipping_discount = null,
84
+ ?Money $discount = null
85
  ) {
86
 
87
  $this->item_total = $item_total;
modules/ppcp-api-client/src/Entity/{class-applicationcontext.php → ApplicationContext.php} RENAMED
File without changes
modules/ppcp-api-client/src/Entity/{class-authorization.php → Authorization.php} RENAMED
@@ -61,6 +61,16 @@ class Authorization {
61
  return $this->authorization_status;
62
  }
63
 
 
 
 
 
 
 
 
 
 
 
64
  /**
65
  * Returns the object as array.
66
  *
61
  return $this->authorization_status;
62
  }
63
 
64
+ /**
65
+ * Checks whether the authorization can be voided.
66
+ *
67
+ * @return bool
68
+ */
69
+ public function is_voidable(): bool {
70
+ return $this->authorization_status->is( AuthorizationStatus::CREATED ) ||
71
+ $this->authorization_status->is( AuthorizationStatus::PENDING );
72
+ }
73
+
74
  /**
75
  * Returns the object as array.
76
  *
modules/ppcp-api-client/src/Entity/{class-authorizationstatus.php → AuthorizationStatus.php} RENAMED
File without changes
modules/ppcp-api-client/src/Entity/{class-authorizationstatusdetails.php → AuthorizationStatusDetails.php} RENAMED
File without changes
modules/ppcp-api-client/src/Entity/{class-capture.php → Capture.php} RENAMED
@@ -4,12 +4,12 @@
4
  *
5
  * @link https://developer.paypal.com/docs/api/orders/v2/#definition-capture
6
  *
7
- * @package Woocommerce\PayPalCommerce\ApiClient\Entity
8
  */
9
 
10
  declare( strict_types=1 );
11
 
12
- namespace Woocommerce\PayPalCommerce\ApiClient\Entity;
13
 
14
  /**
15
  * Class Capture
@@ -164,7 +164,7 @@ class Capture {
164
  * @return array
165
  */
166
  public function to_array() : array {
167
- $data = array(
168
  'id' => $this->id(),
169
  'status' => $this->status()->name(),
170
  'amount' => $this->amount()->to_array(),
@@ -173,8 +173,9 @@ class Capture {
173
  'invoice_id' => $this->invoice_id(),
174
  'custom_id' => $this->custom_id(),
175
  );
176
- if ( $this->status()->details() ) {
177
- $data['status_details'] = array( 'reason' => $this->status()->details()->reason() );
 
178
  }
179
  return $data;
180
  }
4
  *
5
  * @link https://developer.paypal.com/docs/api/orders/v2/#definition-capture
6
  *
7
+ * @package WooCommerce\PayPalCommerce\ApiClient\Entity
8
  */
9
 
10
  declare( strict_types=1 );
11
 
12
+ namespace WooCommerce\PayPalCommerce\ApiClient\Entity;
13
 
14
  /**
15
  * Class Capture
164
  * @return array
165
  */
166
  public function to_array() : array {
167
+ $data = array(
168
  'id' => $this->id(),
169
  'status' => $this->status()->name(),
170
  'amount' => $this->amount()->to_array(),
173
  'invoice_id' => $this->invoice_id(),
174
  'custom_id' => $this->custom_id(),
175
  );
176
+ $details = $this->status()->details();
177
+ if ( $details ) {
178
+ $data['status_details'] = array( 'reason' => $details->reason() );
179
  }
180
  return $data;
181
  }
modules/ppcp-api-client/src/Entity/{class-capturestatus.php → CaptureStatus.php} RENAMED
File without changes
modules/ppcp-api-client/src/Entity/{class-capturestatusdetails.php → CaptureStatusDetails.php} RENAMED
File without changes
modules/ppcp-api-client/src/Entity/{class-cardauthenticationresult.php → CardAuthenticationResult.php} RENAMED
File without changes
modules/ppcp-api-client/src/Entity/{class-item.php → Item.php} RENAMED
File without changes
modules/ppcp-api-client/src/Entity/{class-money.php → Money.php} RENAMED
File without changes
modules/ppcp-api-client/src/Entity/{class-order.php → Order.php} RENAMED
File without changes
modules/ppcp-api-client/src/Entity/{class-orderstatus.php → OrderStatus.php} RENAMED
File without changes
modules/ppcp-api-client/src/Entity/{class-patch.php → Patch.php} RENAMED
File without changes
modules/ppcp-api-client/src/Entity/{class-patchcollection.php → PatchCollection.php} RENAMED
File without changes
modules/ppcp-api-client/src/Entity/{class-payee.php → Payee.php} RENAMED
File without changes
modules/ppcp-api-client/src/Entity/{class-payer.php → Payer.php} RENAMED
File without changes
modules/ppcp-api-client/src/Entity/{class-payername.php → PayerName.php} RENAMED
File without changes
modules/ppcp-api-client/src/Entity/{class-payertaxinfo.php → PayerTaxInfo.php} RENAMED
File without changes
modules/ppcp-api-client/src/Entity/{class-paymentmethod.php → PaymentMethod.php} RENAMED
File without changes
modules/ppcp-api-client/src/Entity/{class-paymentsource.php → PaymentSource.php} RENAMED
File without changes
modules/ppcp-api-client/src/Entity/{class-paymentsourcecard.php → PaymentSourceCard.php} RENAMED
File without changes
modules/ppcp-api-client/src/Entity/{class-paymentsourcewallet.php → PaymentSourceWallet.php} RENAMED
File without changes
modules/ppcp-api-client/src/Entity/{class-paymenttoken.php → PaymentToken.php} RENAMED
File without changes
modules/ppcp-api-client/src/Entity/{class-payments.php → Payments.php} RENAMED
File without changes
modules/ppcp-api-client/src/Entity/{class-phone.php → Phone.php} RENAMED
File without changes
modules/ppcp-api-client/src/Entity/{class-phonewithtype.php → PhoneWithType.php} RENAMED
File without changes
modules/ppcp-api-client/src/Entity/{class-purchaseunit.php → PurchaseUnit.php} RENAMED
@@ -303,55 +303,79 @@ class PurchaseUnit {
303
  * @return bool
304
  */
305
  private function ditch_items_when_mismatch( Amount $amount, Item ...$items ): bool {
306
- $fee_items_total = ( $amount->breakdown() && $amount->breakdown()->item_total() ) ?
307
- $amount->breakdown()->item_total()->value() : null;
308
- $fee_tax_total = ( $amount->breakdown() && $amount->breakdown()->tax_total() ) ?
309
- $amount->breakdown()->tax_total()->value() : null;
310
-
311
- foreach ( $items as $item ) {
312
- if ( null !== $fee_items_total ) {
313
- $fee_items_total -= $item->unit_amount()->value() * $item->quantity();
314
- }
315
- if ( null !== $fee_tax_total ) {
316
- $fee_tax_total -= $item->tax()->value() * $item->quantity();
317
- }
318
  }
319
 
320
- $fee_items_total = round( $fee_items_total, 2 );
321
- $fee_tax_total = round( $fee_tax_total, 2 );
 
 
 
 
 
 
 
 
 
322
 
323
- if ( 0.0 !== $fee_items_total || 0.0 !== $fee_tax_total ) {
324
- return true;
 
325
  }
326
 
327
- $breakdown = $this->amount()->breakdown();
328
- if ( ! $breakdown ) {
329
- return false;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
330
  }
331
- $amount_total = 0;
332
- if ( $breakdown->shipping() ) {
333
- $amount_total += $breakdown->shipping()->value();
 
 
 
 
 
 
 
334
  }
335
- if ( $breakdown->item_total() ) {
336
- $amount_total += $breakdown->item_total()->value();
337
  }
338
- if ( $breakdown->discount() ) {
339
- $amount_total -= $breakdown->discount()->value();
340
  }
341
- if ( $breakdown->tax_total() ) {
342
- $amount_total += $breakdown->tax_total()->value();
343
  }
344
- if ( $breakdown->shipping_discount() ) {
345
- $amount_total -= $breakdown->shipping_discount()->value();
346
  }
347
- if ( $breakdown->handling() ) {
348
- $amount_total += $breakdown->handling()->value();
349
  }
350
- if ( $breakdown->insurance() ) {
351
- $amount_total += $breakdown->insurance()->value();
352
  }
353
 
354
- $amount_value = $this->amount()->value();
355
  $needs_to_ditch = (string) $amount_total !== (string) $amount_value;
356
  return $needs_to_ditch;
357
  }
303
  * @return bool
304
  */
305
  private function ditch_items_when_mismatch( Amount $amount, Item ...$items ): bool {
306
+ $breakdown = $amount->breakdown();
307
+ if ( ! $breakdown ) {
308
+ return false;
 
 
 
 
 
 
 
 
 
309
  }
310
 
311
+ $item_total = $breakdown->item_total();
312
+ if ( $item_total ) {
313
+ $remaining_item_total = array_reduce(
314
+ $items,
315
+ function ( float $total, Item $item ): float {
316
+ return $total - $item->unit_amount()->value() * (float) $item->quantity();
317
+ },
318
+ $item_total->value()
319
+ );
320
+
321
+ $remaining_item_total = round( $remaining_item_total, 2 );
322
 
323
+ if ( 0.0 !== $remaining_item_total ) {
324
+ return true;
325
+ }
326
  }
327
 
328
+ $tax_total = $breakdown->tax_total();
329
+ if ( $tax_total ) {
330
+ $remaining_tax_total = array_reduce(
331
+ $items,
332
+ function ( float $total, Item $item ): float {
333
+ $tax = $item->tax();
334
+ if ( $tax ) {
335
+ $total -= $tax->value() * (float) $item->quantity();
336
+ }
337
+ return $total;
338
+ },
339
+ $tax_total->value()
340
+ );
341
+
342
+ $remaining_tax_total = round( $remaining_tax_total, 2 );
343
+
344
+ if ( 0.0 !== $remaining_tax_total ) {
345
+ return true;
346
+ }
347
  }
348
+
349
+ $shipping = $breakdown->shipping();
350
+ $discount = $breakdown->discount();
351
+ $shipping_discount = $breakdown->shipping_discount();
352
+ $handling = $breakdown->handling();
353
+ $insurance = $breakdown->insurance();
354
+
355
+ $amount_total = 0.0;
356
+ if ( $shipping ) {
357
+ $amount_total += $shipping->value();
358
  }
359
+ if ( $item_total ) {
360
+ $amount_total += $item_total->value();
361
  }
362
+ if ( $discount ) {
363
+ $amount_total -= $discount->value();
364
  }
365
+ if ( $tax_total ) {
366
+ $amount_total += $tax_total->value();
367
  }
368
+ if ( $shipping_discount ) {
369
+ $amount_total -= $shipping_discount->value();
370
  }
371
+ if ( $handling ) {
372
+ $amount_total += $handling->value();
373
  }
374
+ if ( $insurance ) {
375
+ $amount_total += $insurance->value();
376
  }
377
 
378
+ $amount_value = $amount->value();
379
  $needs_to_ditch = (string) $amount_total !== (string) $amount_value;
380
  return $needs_to_ditch;
381
  }
modules/ppcp-api-client/src/Entity/{class-refund.php → Refund.php} RENAMED
File without changes
modules/ppcp-api-client/src/Entity/{class-sellerstatus.php → SellerStatus.php} RENAMED
File without changes
modules/ppcp-api-client/src/Entity/{class-sellerstatusproduct.php → SellerStatusProduct.php} RENAMED
File without changes
modules/ppcp-api-client/src/Entity/{class-shipping.php → Shipping.php} RENAMED
File without changes
modules/ppcp-api-client/src/Entity/{class-token.php → Token.php} RENAMED
File without changes
modules/ppcp-api-client/src/Entity/{class-webhook.php → Webhook.php} RENAMED
@@ -40,9 +40,9 @@ class Webhook {
40
  /**
41
  * Webhook constructor.
42
  *
43
- * @param string $url The URL of the webhook.
44
- * @param string[] $event_types The associated event types.
45
- * @param string $id The id of the webhook.
46
  */
47
  public function __construct( string $url, array $event_types, string $id = '' ) {
48
  $this->url = $url;
40
  /**
41
  * Webhook constructor.
42
  *
43
+ * @param string $url The URL of the webhook.
44
+ * @param stdClass[] $event_types The associated event types.
45
+ * @param string $id The id of the webhook.
46
  */
47
  public function __construct( string $url, array $event_types, string $id = '' ) {
48
  $this->url = $url;
modules/ppcp-api-client/src/Entity/{class-webhookevent.php → WebhookEvent.php} RENAMED
File without changes
modules/ppcp-api-client/src/Exception/{class-notfoundexception.php → NotFoundException.php} RENAMED
File without changes
modules/ppcp-api-client/src/Exception/{class-paypalapiexception.php → PayPalApiException.php} RENAMED
File without changes
modules/ppcp-api-client/src/Exception/{class-runtimeexception.php → RuntimeException.php} RENAMED
File without changes
modules/ppcp-api-client/src/Factory/{class-addressfactory.php → AddressFactory.php} RENAMED
File without changes
modules/ppcp-api-client/src/Factory/{class-amountfactory.php → AmountFactory.php} RENAMED
File without changes
modules/ppcp-api-client/src/Factory/{class-applicationcontextfactory.php → ApplicationContextFactory.php} RENAMED
File without changes
modules/ppcp-api-client/src/Factory/{class-authorizationfactory.php → AuthorizationFactory.php} RENAMED
File without changes
modules/ppcp-api-client/src/Factory/{class-capturefactory.php → CaptureFactory.php} RENAMED
@@ -9,7 +9,7 @@ declare( strict_types=1 );
9
 
10
  namespace WooCommerce\PayPalCommerce\ApiClient\Factory;
11
 
12
- use Woocommerce\PayPalCommerce\ApiClient\Entity\Capture;
13
  use WooCommerce\PayPalCommerce\ApiClient\Entity\CaptureStatus;
14
  use WooCommerce\PayPalCommerce\ApiClient\Entity\CaptureStatusDetails;
15
 
9
 
10
  namespace WooCommerce\PayPalCommerce\ApiClient\Factory;
11
 
12
+ use WooCommerce\PayPalCommerce\ApiClient\Entity\Capture;
13
  use WooCommerce\PayPalCommerce\ApiClient\Entity\CaptureStatus;
14
  use WooCommerce\PayPalCommerce\ApiClient\Entity\CaptureStatusDetails;
15
 
modules/ppcp-api-client/src/Factory/{class-itemfactory.php → ItemFactory.php} RENAMED
File without changes
modules/ppcp-api-client/src/Factory/{class-orderfactory.php → OrderFactory.php} RENAMED
File without changes
modules/ppcp-api-client/src/Factory/{class-patchcollectionfactory.php → PatchCollectionFactory.php} RENAMED
@@ -52,14 +52,12 @@ class PatchCollectionFactory {
52
  array_filter(
53
  $from,
54
  static function ( PurchaseUnit $unit ) use ( $purchase_unit_to ): bool {
55
- //phpcs:disable WordPress.PHP.StrictComparisons.LooseComparison
56
  // Loose comparison needed to compare two objects.
 
57
  return $unit == $purchase_unit_to;
58
- //phpcs:enable WordPress.PHP.StrictComparisons.LooseComparison
59
  }
60
  )
61
  );
62
- $needs_update = true;
63
  if ( ! $needs_update ) {
64
  continue;
65
  }
52
  array_filter(
53
  $from,
54
  static function ( PurchaseUnit $unit ) use ( $purchase_unit_to ): bool {
 
55
  // Loose comparison needed to compare two objects.
56
+ // phpcs:ignore WordPress.PHP.StrictComparisons.LooseComparison
57
  return $unit == $purchase_unit_to;
 
58
  }
59
  )
60
  );
 
61
  if ( ! $needs_update ) {
62
  continue;
63
  }
modules/ppcp-api-client/src/Factory/{class-payeefactory.php → PayeeFactory.php} RENAMED
File without changes
modules/ppcp-api-client/src/Factory/{class-payerfactory.php → PayerFactory.php} RENAMED
File without changes
modules/ppcp-api-client/src/Factory/{class-paymentsourcefactory.php → PaymentSourceFactory.php} RENAMED
File without changes
modules/ppcp-api-client/src/Factory/{class-paymenttokenfactory.php → PaymentTokenFactory.php} RENAMED
File without changes
modules/ppcp-api-client/src/Factory/{class-paymentsfactory.php → PaymentsFactory.php} RENAMED
@@ -10,7 +10,7 @@ declare(strict_types=1);
10
  namespace WooCommerce\PayPalCommerce\ApiClient\Factory;
11
 
12
  use WooCommerce\PayPalCommerce\ApiClient\Entity\Authorization;
13
- use Woocommerce\PayPalCommerce\ApiClient\Entity\Capture;
14
  use WooCommerce\PayPalCommerce\ApiClient\Entity\Payments;
15
 
16
  /**
10
  namespace WooCommerce\PayPalCommerce\ApiClient\Factory;
11
 
12
  use WooCommerce\PayPalCommerce\ApiClient\Entity\Authorization;
13
+ use WooCommerce\PayPalCommerce\ApiClient\Entity\Capture;
14
  use WooCommerce\PayPalCommerce\ApiClient\Entity\Payments;
15
 
16
  /**
modules/ppcp-api-client/src/Factory/{class-purchaseunitfactory.php → PurchaseUnitFactory.php} RENAMED
@@ -121,9 +121,11 @@ class PurchaseUnitFactory {
121
  $payee = $this->payee_repository->payee();
122
  $wc_order_id = $order->get_order_number();
123
  $custom_id = $this->prefix . $wc_order_id;
124
- $invoice_id = $this->prefix . $wc_order_id;
 
125
  $soft_descriptor = '';
126
- $purchase_unit = new PurchaseUnit(
 
127
  $amount,
128
  $items,
129
  $shipping,
121
  $payee = $this->payee_repository->payee();
122
  $wc_order_id = $order->get_order_number();
123
  $custom_id = $this->prefix . $wc_order_id;
124
+ $retry = $order->get_meta( 'ppcp-retry' ) ? '-' . $order->get_meta( 'ppcp-retry' ) : '';
125
+ $invoice_id = $this->prefix . $wc_order_id . $retry;
126
  $soft_descriptor = '';
127
+
128
+ $purchase_unit = new PurchaseUnit(
129
  $amount,
130
  $items,
131
  $shipping,
modules/ppcp-api-client/src/Factory/{class-sellerstatusfactory.php → SellerStatusFactory.php} RENAMED
File without changes
modules/ppcp-api-client/src/Factory/{class-shippingfactory.php → ShippingFactory.php} RENAMED
File without changes
modules/ppcp-api-client/src/Factory/{class-webhookeventfactory.php → WebhookEventFactory.php} RENAMED
File without changes
modules/ppcp-api-client/src/Factory/{class-webhookfactory.php → WebhookFactory.php} RENAMED
@@ -9,6 +9,7 @@ declare(strict_types=1);
9
 
10
  namespace WooCommerce\PayPalCommerce\ApiClient\Factory;
11
 
 
12
  use WooCommerce\PayPalCommerce\ApiClient\Entity\Webhook;
13
  use WooCommerce\PayPalCommerce\ApiClient\Exception\RuntimeException;
14
 
@@ -20,15 +21,15 @@ class WebhookFactory {
20
  /**
21
  * Returns a webhook for a URL with an array of event types associated to this URL.
22
  *
23
- * @param string $url The URL.
24
- * @param array $event_types The event types to which this URL listens to.
25
  *
26
  * @return Webhook
27
  */
28
  public function for_url_and_events( string $url, array $event_types ): Webhook {
29
  $event_types = array_map(
30
- static function ( string $type ): array {
31
- return array( 'name' => $type );
32
  },
33
  $event_types
34
  );
@@ -52,12 +53,12 @@ class WebhookFactory {
52
  /**
53
  * Returns a Webhook based of a PayPal JSON response.
54
  *
55
- * @param \stdClass $data The JSON object.
56
  *
57
  * @return Webhook
58
  * @throws RuntimeException When JSON object is malformed.
59
  */
60
- public function from_paypal_response( \stdClass $data ): Webhook {
61
  if ( ! isset( $data->id ) ) {
62
  throw new RuntimeException(
63
  __( 'No id for webhook given.', 'woocommerce-paypal-payments' )
9
 
10
  namespace WooCommerce\PayPalCommerce\ApiClient\Factory;
11
 
12
+ use stdClass;
13
  use WooCommerce\PayPalCommerce\ApiClient\Entity\Webhook;
14
  use WooCommerce\PayPalCommerce\ApiClient\Exception\RuntimeException;
15
 
21
  /**
22
  * Returns a webhook for a URL with an array of event types associated to this URL.
23
  *
24
+ * @param string $url The URL.
25
+ * @param string[] $event_types The event types to which this URL listens to.
26
  *
27
  * @return Webhook
28
  */
29
  public function for_url_and_events( string $url, array $event_types ): Webhook {
30
  $event_types = array_map(
31
+ static function ( string $type ): stdClass {
32
+ return (object) array( 'name' => $type );
33
  },
34
  $event_types
35
  );
53
  /**
54
  * Returns a Webhook based of a PayPal JSON response.
55
  *
56
+ * @param stdClass $data The JSON object.
57
  *
58
  * @return Webhook
59
  * @throws RuntimeException When JSON object is malformed.
60
  */
61
+ public function from_paypal_response( stdClass $data ): Webhook {
62
  if ( ! isset( $data->id ) ) {
63
  throw new RuntimeException(
64
  __( 'No id for webhook given.', 'woocommerce-paypal-payments' )
modules/ppcp-api-client/src/Helper/{class-cache.php → Cache.php} RENAMED
File without changes
modules/ppcp-api-client/src/Helper/{class-dccapplies.php → DccApplies.php} RENAMED
File without changes
modules/ppcp-api-client/src/Helper/{class-errorresponse.php → ErrorResponse.php} RENAMED
File without changes
modules/ppcp-api-client/src/Repository/{class-applicationcontextrepository.php → ApplicationContextRepository.php} RENAMED
File without changes
modules/ppcp-api-client/src/Repository/{class-cartrepository.php → CartRepository.php} RENAMED
File without changes
modules/ppcp-api-client/src/Repository/{class-partnerreferralsdata.php → PartnerReferralsData.php} RENAMED
File without changes
modules/ppcp-api-client/src/Repository/{class-paypalrequestidrepository.php → PayPalRequestIdRepository.php} RENAMED
File without changes
modules/ppcp-api-client/src/Repository/{class-payeerepository.php → PayeeRepository.php} RENAMED
File without changes
modules/ppcp-api-client/src/Repository/{class-purchaseunitrepositoryinterface.php → PurchaseUnitRepositoryInterface.php} RENAMED
File without changes
modules/ppcp-button/assets/js/button.js CHANGED
@@ -1 +1 @@
1
- (()=>{"use strict";var __webpack_modules__={94:()=>{eval("\n;// CONCATENATED MODULE: ./resources/js/modules/ErrorHandler.js\nclass ErrorHandler {\n constructor(genericErrorText) {\n this.genericErrorText = genericErrorText;\n this.wrapper = document.querySelector('.woocommerce-notices-wrapper');\n this.messagesList = document.querySelector('ul.woocommerce-error');\n }\n\n genericError() {\n if (this.wrapper.classList.contains('ppcp-persist')) {\n return;\n }\n\n this.clear();\n this.message(this.genericErrorText);\n }\n\n appendPreparedErrorMessageElement(errorMessageElement) {\n if (this.messagesList === null) {\n this.prepareMessagesList();\n }\n\n this.messagesList.replaceWith(errorMessageElement);\n }\n\n message(text, persist = false) {\n if (!typeof String || text.length === 0) {\n throw new Error('A new message text must be a non-empty string.');\n }\n\n if (this.messagesList === null) {\n this.prepareMessagesList();\n }\n\n if (persist) {\n this.wrapper.classList.add('ppcp-persist');\n } else {\n this.wrapper.classList.remove('ppcp-persist');\n }\n\n let messageNode = this.prepareMessagesListItem(text);\n this.messagesList.appendChild(messageNode);\n jQuery.scroll_to_notices(jQuery('.woocommerce-notices-wrapper'));\n }\n\n prepareMessagesList() {\n if (this.messagesList === null) {\n this.messagesList = document.createElement('ul');\n this.messagesList.setAttribute('class', 'woocommerce-error');\n this.messagesList.setAttribute('role', 'alert');\n this.wrapper.appendChild(this.messagesList);\n }\n }\n\n prepareMessagesListItem(message) {\n const li = document.createElement('li');\n li.innerHTML = message;\n return li;\n }\n\n sanitize(text) {\n const textarea = document.createElement('textarea');\n textarea.innerHTML = text;\n return textarea.value.replace('Error: ', '');\n }\n\n clear() {\n if (!this.wrapper.classList.contains('woocommerce-error')) {\n return;\n }\n\n this.wrapper.classList.remove('woocommerce-error');\n this.wrapper.innerText = '';\n }\n\n}\n\n/* harmony default export */ const modules_ErrorHandler = (ErrorHandler);\n;// CONCATENATED MODULE: ./resources/js/modules/OnApproveHandler/onApproveForContinue.js\nconst onApprove = (context, errorHandler) => {\n return (data, actions) => {\n return fetch(context.config.ajax.approve_order.endpoint, {\n method: 'POST',\n body: JSON.stringify({\n nonce: context.config.ajax.approve_order.nonce,\n order_id: data.orderID\n })\n }).then(res => {\n return res.json();\n }).then(data => {\n if (!data.success) {\n errorHandler.genericError();\n return actions.restart().catch(err => {\n errorHandler.genericError();\n });\n ;\n }\n\n location.href = context.config.redirect;\n });\n };\n};\n\n/* harmony default export */ const onApproveForContinue = (onApprove);\n;// CONCATENATED MODULE: ./resources/js/modules/Helper/PayerData.js\nconst payerData = () => {\n const payer = PayPalCommerceGateway.payer;\n\n if (!payer) {\n return null;\n }\n\n const phone = document.querySelector('#billing_phone') || typeof payer.phone !== 'undefined' ? {\n phone_type: \"HOME\",\n phone_number: {\n national_number: document.querySelector('#billing_phone') ? document.querySelector('#billing_phone').value : payer.phone.phone_number.national_number\n }\n } : null;\n const payerData = {\n email_address: document.querySelector('#billing_email') ? document.querySelector('#billing_email').value : payer.email_address,\n name: {\n surname: document.querySelector('#billing_last_name') ? document.querySelector('#billing_last_name').value : payer.name.surname,\n given_name: document.querySelector('#billing_first_name') ? document.querySelector('#billing_first_name').value : payer.name.given_name\n },\n address: {\n country_code: document.querySelector('#billing_country') ? document.querySelector('#billing_country').value : payer.address.country_code,\n address_line_1: document.querySelector('#billing_address_1') ? document.querySelector('#billing_address_1').value : payer.address.address_line_1,\n address_line_2: document.querySelector('#billing_address_2') ? document.querySelector('#billing_address_2').value : payer.address.address_line_2,\n admin_area_1: document.querySelector('#billing_state') ? document.querySelector('#billing_state').value : payer.address.admin_area_1,\n admin_area_2: document.querySelector('#billing_city') ? document.querySelector('#billing_city').value : payer.address.admin_area_2,\n postal_code: document.querySelector('#billing_postcode') ? document.querySelector('#billing_postcode').value : payer.address.postal_code\n }\n };\n\n if (phone) {\n payerData.phone = phone;\n }\n\n return payerData;\n};\n;// CONCATENATED MODULE: ./resources/js/modules/ActionHandler/CartActionHandler.js\n\n\n\nclass CartActionHandler {\n constructor(config, errorHandler) {\n this.config = config;\n this.errorHandler = errorHandler;\n }\n\n configuration() {\n const createOrder = (data, actions) => {\n const payer = payerData();\n const bnCode = typeof this.config.bn_codes[this.config.context] !== 'undefined' ? this.config.bn_codes[this.config.context] : '';\n return fetch(this.config.ajax.create_order.endpoint, {\n method: 'POST',\n body: JSON.stringify({\n nonce: this.config.ajax.create_order.nonce,\n purchase_units: [],\n bn_code: bnCode,\n payer,\n context: this.config.context\n })\n }).then(function (res) {\n return res.json();\n }).then(function (data) {\n if (!data.success) {\n console.error(data);\n throw Error(data.data.message);\n }\n\n return data.data.id;\n });\n };\n\n return {\n createOrder,\n onApprove: onApproveForContinue(this, this.errorHandler),\n onError: error => {\n this.errorHandler.genericError();\n }\n };\n }\n\n}\n\n/* harmony default export */ const ActionHandler_CartActionHandler = (CartActionHandler);\n;// CONCATENATED MODULE: ./resources/js/modules/ContextBootstrap/MiniCartBootstap.js\n\n\n\nclass MiniCartBootstap {\n constructor(gateway, renderer) {\n this.gateway = gateway;\n this.renderer = renderer;\n this.actionHandler = null;\n }\n\n init() {\n this.actionHandler = new ActionHandler_CartActionHandler(PayPalCommerceGateway, new modules_ErrorHandler(this.gateway.labels.error.generic));\n this.render();\n jQuery(document.body).on('wc_fragments_loaded wc_fragments_refreshed', () => {\n this.render();\n });\n }\n\n shouldRender() {\n return document.querySelector(this.gateway.button.mini_cart_wrapper) !== null || document.querySelector(this.gateway.hosted_fields.mini_cart_wrapper) !== null;\n }\n\n render() {\n if (!this.shouldRender()) {\n return;\n }\n\n this.renderer.render(this.gateway.button.mini_cart_wrapper, this.gateway.hosted_fields.mini_cart_wrapper, this.actionHandler.configuration());\n }\n\n}\n\n/* harmony default export */ const ContextBootstrap_MiniCartBootstap = (MiniCartBootstap);\n;// CONCATENATED MODULE: ./resources/js/modules/Helper/UpdateCart.js\n\n\nclass UpdateCart {\n constructor(endpoint, nonce) {\n this.endpoint = endpoint;\n this.nonce = nonce;\n }\n /**\n *\n * @param onResolve\n * @param {Product[]} products\n * @returns {Promise<unknown>}\n */\n\n\n update(onResolve, products) {\n return new Promise((resolve, reject) => {\n fetch(this.endpoint, {\n method: 'POST',\n body: JSON.stringify({\n nonce: this.nonce,\n products\n })\n }).then(result => {\n return result.json();\n }).then(result => {\n if (!result.success) {\n reject(result.data);\n return;\n }\n\n const resolved = onResolve(result.data);\n resolve(resolved);\n });\n });\n }\n\n}\n\n/* harmony default export */ const Helper_UpdateCart = (UpdateCart);\n;// CONCATENATED MODULE: ./resources/js/modules/Helper/ButtonsToggleListener.js\n/**\n * When you can't add something to the cart, the PayPal buttons should not show.\n * Therefore we listen for changes on the add to cart button and show/hide the buttons accordingly.\n */\nclass ButtonsToggleListener {\n constructor(element, showCallback, hideCallback) {\n this.element = element;\n this.showCallback = showCallback;\n this.hideCallback = hideCallback;\n this.observer = null;\n }\n\n init() {\n const config = {\n attributes: true\n };\n\n const callback = () => {\n if (this.element.classList.contains('disabled')) {\n this.hideCallback();\n return;\n }\n\n this.showCallback();\n };\n\n this.observer = new MutationObserver(callback);\n this.observer.observe(this.element, config);\n callback();\n }\n\n disconnect() {\n this.observer.disconnect();\n }\n\n}\n\n/* harmony default export */ const Helper_ButtonsToggleListener = (ButtonsToggleListener);\n;// CONCATENATED MODULE: ./resources/js/modules/Entity/Product.js\nclass Product {\n constructor(id, quantity, variations) {\n this.id = id;\n this.quantity = quantity;\n this.variations = variations;\n }\n\n data() {\n return {\n id: this.id,\n quantity: this.quantity,\n variations: this.variations\n };\n }\n\n}\n\n/* harmony default export */ const Entity_Product = (Product);\n;// CONCATENATED MODULE: ./resources/js/modules/ActionHandler/SingleProductActionHandler.js\n\n\n\n\n\nclass SingleProductActionHandler {\n constructor(config, updateCart, showButtonCallback, hideButtonCallback, formElement, errorHandler) {\n this.config = config;\n this.updateCart = updateCart;\n this.showButtonCallback = showButtonCallback;\n this.hideButtonCallback = hideButtonCallback;\n this.formElement = formElement;\n this.errorHandler = errorHandler;\n }\n\n configuration() {\n if (this.hasVariations()) {\n const observer = new Helper_ButtonsToggleListener(this.formElement.querySelector('.single_add_to_cart_button'), this.showButtonCallback, this.hideButtonCallback);\n observer.init();\n }\n\n return {\n createOrder: this.createOrder(),\n onApprove: onApproveForContinue(this, this.errorHandler),\n onError: error => {\n this.errorHandler.genericError();\n }\n };\n }\n\n createOrder() {\n var getProducts = null;\n\n if (!this.isGroupedProduct()) {\n getProducts = () => {\n const id = document.querySelector('[name=\"add-to-cart\"]').value;\n const qty = document.querySelector('[name=\"quantity\"]').value;\n const variations = this.variations();\n return [new Entity_Product(id, qty, variations)];\n };\n } else {\n getProducts = () => {\n const products = [];\n this.formElement.querySelectorAll('input[type=\"number\"]').forEach(element => {\n if (!element.value) {\n return;\n }\n\n const elementName = element.getAttribute('name').match(/quantity\\[([\\d]*)\\]/);\n\n if (elementName.length !== 2) {\n return;\n }\n\n const id = parseInt(elementName[1]);\n const quantity = parseInt(element.value);\n products.push(new Entity_Product(id, quantity, null));\n });\n return products;\n };\n }\n\n const createOrder = (data, actions) => {\n this.errorHandler.clear();\n\n const onResolve = purchase_units => {\n const payer = payerData();\n const bnCode = typeof this.config.bn_codes[this.config.context] !== 'undefined' ? this.config.bn_codes[this.config.context] : '';\n return fetch(this.config.ajax.create_order.endpoint, {\n method: 'POST',\n body: JSON.stringify({\n nonce: this.config.ajax.create_order.nonce,\n purchase_units,\n payer,\n bn_code: bnCode,\n context: this.config.context\n })\n }).then(function (res) {\n return res.json();\n }).then(function (data) {\n if (!data.success) {\n console.error(data);\n throw Error(data.data.message);\n }\n\n return data.data.id;\n });\n };\n\n const promise = this.updateCart.update(onResolve, getProducts());\n return promise;\n };\n\n return createOrder;\n }\n\n variations() {\n if (!this.hasVariations()) {\n return null;\n }\n\n const attributes = [...this.formElement.querySelectorAll(\"[name^='attribute_']\")].map(element => {\n return {\n value: element.value,\n name: element.name\n };\n });\n return attributes;\n }\n\n hasVariations() {\n return this.formElement.classList.contains('variations_form');\n }\n\n isGroupedProduct() {\n return this.formElement.classList.contains('grouped_form');\n }\n\n}\n\n/* harmony default export */ const ActionHandler_SingleProductActionHandler = (SingleProductActionHandler);\n;// CONCATENATED MODULE: ./resources/js/modules/ContextBootstrap/SingleProductBootstap.js\n\n\n\n\nclass SingleProductBootstap {\n constructor(gateway, renderer, messages) {\n this.gateway = gateway;\n this.renderer = renderer;\n this.messages = messages;\n }\n\n init() {\n if (!this.shouldRender()) {\n this.renderer.hideButtons(this.gateway.hosted_fields.wrapper);\n return;\n }\n\n this.render();\n }\n\n shouldRender() {\n if (document.querySelector('form.cart') === null) {\n return false;\n }\n\n return true;\n }\n\n render() {\n const actionHandler = new ActionHandler_SingleProductActionHandler(this.gateway, new Helper_UpdateCart(this.gateway.ajax.change_cart.endpoint, this.gateway.ajax.change_cart.nonce), () => {\n this.renderer.showButtons(this.gateway.button.wrapper);\n this.renderer.showButtons(this.gateway.hosted_fields.wrapper);\n let priceText = \"0\";\n\n if (document.querySelector('form.cart ins .woocommerce-Price-amount')) {\n priceText = document.querySelector('form.cart ins .woocommerce-Price-amount').innerText;\n } else if (document.querySelector('form.cart .woocommerce-Price-amount')) {\n priceText = document.querySelector('form.cart .woocommerce-Price-amount').innerText;\n }\n\n const amount = parseInt(priceText.replace(/([^\\d,\\.\\s]*)/g, ''));\n this.messages.renderWithAmount(amount);\n }, () => {\n this.renderer.hideButtons(this.gateway.button.wrapper);\n this.renderer.hideButtons(this.gateway.hosted_fields.wrapper);\n }, document.querySelector('form.cart'), new modules_ErrorHandler(this.gateway.labels.error.generic));\n this.renderer.render(this.gateway.button.wrapper, this.gateway.hosted_fields.wrapper, actionHandler.configuration());\n }\n\n}\n\n/* harmony default export */ const ContextBootstrap_SingleProductBootstap = (SingleProductBootstap);\n;// CONCATENATED MODULE: ./resources/js/modules/ContextBootstrap/CartBootstap.js\n\n\n\nclass CartBootstrap {\n constructor(gateway, renderer) {\n this.gateway = gateway;\n this.renderer = renderer;\n }\n\n init() {\n if (!this.shouldRender()) {\n return;\n }\n\n this.render();\n jQuery(document.body).on('updated_cart_totals updated_checkout', () => {\n this.render();\n });\n }\n\n shouldRender() {\n return document.querySelector(this.gateway.button.wrapper) !== null || document.querySelector(this.gateway.hosted_fields.wrapper) !== null;\n }\n\n render() {\n const actionHandler = new ActionHandler_CartActionHandler(PayPalCommerceGateway, new modules_ErrorHandler(this.gateway.labels.error.generic));\n this.renderer.render(this.gateway.button.wrapper, this.gateway.hosted_fields.wrapper, actionHandler.configuration());\n }\n\n}\n\n/* harmony default export */ const CartBootstap = (CartBootstrap);\n;// CONCATENATED MODULE: ./resources/js/modules/OnApproveHandler/onApproveForPayNow.js\nconst onApproveForPayNow_onApprove = (context, errorHandler, spinner) => {\n return (data, actions) => {\n spinner.block();\n return fetch(context.config.ajax.approve_order.endpoint, {\n method: 'POST',\n body: JSON.stringify({\n nonce: context.config.ajax.approve_order.nonce,\n order_id: data.orderID\n })\n }).then(res => {\n return res.json();\n }).then(data => {\n spinner.unblock();\n\n if (!data.success) {\n if (data.data.code === 100) {\n errorHandler.message(data.data.message);\n } else {\n errorHandler.genericError();\n }\n\n if (typeof actions !== 'undefined' && typeof actions.restart !== 'undefined') {\n return actions.restart();\n }\n\n throw new Error(data.data.message);\n }\n\n document.querySelector('#place_order').click();\n });\n };\n};\n\n/* harmony default export */ const onApproveForPayNow = (onApproveForPayNow_onApprove);\n;// CONCATENATED MODULE: ./resources/js/modules/ActionHandler/CheckoutActionHandler.js\n\n\n\nclass CheckoutActionHandler {\n constructor(config, errorHandler, spinner) {\n this.config = config;\n this.errorHandler = errorHandler;\n this.spinner = spinner;\n }\n\n configuration() {\n const spinner = this.spinner;\n\n const createOrder = (data, actions) => {\n const payer = payerData();\n const bnCode = typeof this.config.bn_codes[this.config.context] !== 'undefined' ? this.config.bn_codes[this.config.context] : '';\n const errorHandler = this.errorHandler;\n const formSelector = this.config.context === 'checkout' ? 'form.checkout' : 'form#order_review';\n const formValues = jQuery(formSelector).serialize();\n const createaccount = jQuery('#createaccount').is(\":checked\") ? true : false;\n return fetch(this.config.ajax.create_order.endpoint, {\n method: 'POST',\n body: JSON.stringify({\n nonce: this.config.ajax.create_order.nonce,\n payer,\n bn_code: bnCode,\n context: this.config.context,\n order_id: this.config.order_id,\n form: formValues,\n createaccount: createaccount\n })\n }).then(function (res) {\n return res.json();\n }).then(function (data) {\n if (!data.success) {\n spinner.unblock(); //handle both messages sent from Woocommerce (data.messages) and this plugin (data.data.message)\n\n if (typeof data.messages !== 'undefined') {\n const domParser = new DOMParser();\n errorHandler.appendPreparedErrorMessageElement(domParser.parseFromString(data.messages, 'text/html').querySelector('ul'));\n } else {\n errorHandler.message(data.data.message, true);\n }\n\n return;\n }\n\n const input = document.createElement('input');\n input.setAttribute('type', 'hidden');\n input.setAttribute('name', 'ppcp-resume-order');\n input.setAttribute('value', data.data.purchase_units[0].custom_id);\n document.querySelector(formSelector).append(input);\n return data.data.id;\n });\n };\n\n return {\n createOrder,\n onApprove: onApproveForPayNow(this, this.errorHandler, this.spinner),\n onCancel: () => {\n spinner.unblock();\n },\n onError: () => {\n this.errorHandler.genericError();\n spinner.unblock();\n }\n };\n }\n\n}\n\n/* harmony default export */ const ActionHandler_CheckoutActionHandler = (CheckoutActionHandler);\n;// CONCATENATED MODULE: ./resources/js/modules/ContextBootstrap/CheckoutBootstap.js\n\n\n\nclass CheckoutBootstap {\n constructor(gateway, renderer, messages, spinner) {\n this.gateway = gateway;\n this.renderer = renderer;\n this.messages = messages;\n this.spinner = spinner;\n }\n\n init() {\n this.render();\n jQuery(document.body).on('updated_checkout', () => {\n this.render();\n });\n jQuery(document.body).on('updated_checkout payment_method_selected', () => {\n this.switchBetweenPayPalandOrderButton();\n this.displayPlaceOrderButtonForSavedCreditCards();\n });\n jQuery(document).on('hosted_fields_loaded', () => {\n jQuery('#saved-credit-card').on('change', () => {\n this.displayPlaceOrderButtonForSavedCreditCards();\n });\n });\n this.switchBetweenPayPalandOrderButton();\n this.displayPlaceOrderButtonForSavedCreditCards();\n }\n\n shouldRender() {\n if (document.querySelector(this.gateway.button.cancel_wrapper)) {\n return false;\n }\n\n return document.querySelector(this.gateway.button.wrapper) !== null || document.querySelector(this.gateway.hosted_fields.wrapper) !== null;\n }\n\n render() {\n if (!this.shouldRender()) {\n return;\n }\n\n if (document.querySelector(this.gateway.hosted_fields.wrapper + '>div')) {\n document.querySelector(this.gateway.hosted_fields.wrapper + '>div').setAttribute('style', '');\n }\n\n const actionHandler = new ActionHandler_CheckoutActionHandler(PayPalCommerceGateway, new modules_ErrorHandler(this.gateway.labels.error.generic), this.spinner);\n this.renderer.render(this.gateway.button.wrapper, this.gateway.hosted_fields.wrapper, actionHandler.configuration());\n }\n\n switchBetweenPayPalandOrderButton() {\n jQuery('#saved-credit-card').val(jQuery('#saved-credit-card option:first').val());\n const currentPaymentMethod = jQuery('input[name=\"payment_method\"]:checked').val();\n\n if (currentPaymentMethod !== 'ppcp-gateway' && currentPaymentMethod !== 'ppcp-credit-card-gateway') {\n this.renderer.hideButtons(this.gateway.button.wrapper);\n this.renderer.hideButtons(this.gateway.messages.wrapper);\n this.renderer.hideButtons(this.gateway.hosted_fields.wrapper);\n jQuery('#place_order').show();\n } else {\n jQuery('#place_order').hide();\n\n if (currentPaymentMethod === 'ppcp-gateway') {\n this.renderer.showButtons(this.gateway.button.wrapper);\n this.renderer.showButtons(this.gateway.messages.wrapper);\n this.messages.render();\n this.renderer.hideButtons(this.gateway.hosted_fields.wrapper);\n }\n\n if (currentPaymentMethod === 'ppcp-credit-card-gateway') {\n this.renderer.hideButtons(this.gateway.button.wrapper);\n this.renderer.hideButtons(this.gateway.messages.wrapper);\n this.renderer.showButtons(this.gateway.hosted_fields.wrapper);\n }\n }\n }\n\n displayPlaceOrderButtonForSavedCreditCards() {\n const currentPaymentMethod = jQuery('input[name=\"payment_method\"]:checked').val();\n\n if (currentPaymentMethod !== 'ppcp-credit-card-gateway') {\n return;\n }\n\n if (jQuery('#saved-credit-card').length && jQuery('#saved-credit-card').val() !== '') {\n this.renderer.hideButtons(this.gateway.button.wrapper);\n this.renderer.hideButtons(this.gateway.messages.wrapper);\n this.renderer.hideButtons(this.gateway.hosted_fields.wrapper);\n jQuery('#place_order').show();\n this.disableCreditCardFields();\n } else {\n jQuery('#place_order').hide();\n this.renderer.hideButtons(this.gateway.button.wrapper);\n this.renderer.hideButtons(this.gateway.messages.wrapper);\n this.renderer.showButtons(this.gateway.hosted_fields.wrapper);\n this.enableCreditCardFields();\n }\n }\n\n disableCreditCardFields() {\n jQuery('label[for=\"ppcp-credit-card-gateway-card-number\"]').addClass('ppcp-credit-card-gateway-form-field-disabled');\n jQuery('#ppcp-credit-card-gateway-card-number').addClass('ppcp-credit-card-gateway-form-field-disabled');\n jQuery('label[for=\"ppcp-credit-card-gateway-card-expiry\"]').addClass('ppcp-credit-card-gateway-form-field-disabled');\n jQuery('#ppcp-credit-card-gateway-card-expiry').addClass('ppcp-credit-card-gateway-form-field-disabled');\n jQuery('label[for=\"ppcp-credit-card-gateway-card-cvc\"]').addClass('ppcp-credit-card-gateway-form-field-disabled');\n jQuery('#ppcp-credit-card-gateway-card-cvc').addClass('ppcp-credit-card-gateway-form-field-disabled');\n jQuery('label[for=\"vault\"]').addClass('ppcp-credit-card-gateway-form-field-disabled');\n jQuery('#ppcp-credit-card-vault').addClass('ppcp-credit-card-gateway-form-field-disabled');\n jQuery('#ppcp-credit-card-vault').attr(\"disabled\", true);\n this.renderer.disableCreditCardFields();\n }\n\n enableCreditCardFields() {\n jQuery('label[for=\"ppcp-credit-card-gateway-card-number\"]').removeClass('ppcp-credit-card-gateway-form-field-disabled');\n jQuery('#ppcp-credit-card-gateway-card-number').removeClass('ppcp-credit-card-gateway-form-field-disabled');\n jQuery('label[for=\"ppcp-credit-card-gateway-card-expiry\"]').removeClass('ppcp-credit-card-gateway-form-field-disabled');\n jQuery('#ppcp-credit-card-gateway-card-expiry').removeClass('ppcp-credit-card-gateway-form-field-disabled');\n jQuery('label[for=\"ppcp-credit-card-gateway-card-cvc\"]').removeClass('ppcp-credit-card-gateway-form-field-disabled');\n jQuery('#ppcp-credit-card-gateway-card-cvc').removeClass('ppcp-credit-card-gateway-form-field-disabled');\n jQuery('label[for=\"vault\"]').removeClass('ppcp-credit-card-gateway-form-field-disabled');\n jQuery('#ppcp-credit-card-vault').removeClass('ppcp-credit-card-gateway-form-field-disabled');\n jQuery('#ppcp-credit-card-vault').attr(\"disabled\", false);\n this.renderer.enableCreditCardFields();\n }\n\n}\n\n/* harmony default export */ const ContextBootstrap_CheckoutBootstap = (CheckoutBootstap);\n;// CONCATENATED MODULE: ./resources/js/modules/ContextBootstrap/PayNowBootstrap.js\n\n\n\nclass PayNowBootstrap {\n constructor(gateway, renderer, messages, spinner) {\n this.gateway = gateway;\n this.renderer = renderer;\n this.messages = messages;\n this.spinner = spinner;\n }\n\n init() {\n this.render();\n jQuery(document.body).on('updated_checkout', () => {\n this.render();\n });\n jQuery(document.body).on('updated_checkout payment_method_selected', () => {\n this.switchBetweenPayPalandOrderButton();\n });\n this.switchBetweenPayPalandOrderButton();\n }\n\n shouldRender() {\n if (document.querySelector(this.gateway.button.cancel_wrapper)) {\n return false;\n }\n\n return document.querySelector(this.gateway.button.wrapper) !== null || document.querySelector(this.gateway.hosted_fields.wrapper) !== null;\n }\n\n render() {\n if (!this.shouldRender()) {\n return;\n }\n\n if (document.querySelector(this.gateway.hosted_fields.wrapper + '>div')) {\n document.querySelector(this.gateway.hosted_fields.wrapper + '>div').setAttribute('style', '');\n }\n\n const actionHandler = new ActionHandler_CheckoutActionHandler(PayPalCommerceGateway, new modules_ErrorHandler(this.gateway.labels.error.generic), this.spinner);\n this.renderer.render(this.gateway.button.wrapper, this.gateway.hosted_fields.wrapper, actionHandler.configuration());\n }\n\n switchBetweenPayPalandOrderButton() {\n const urlParams = new URLSearchParams(window.location.search);\n\n if (urlParams.has('change_payment_method')) {\n return;\n }\n\n const currentPaymentMethod = jQuery('input[name=\"payment_method\"]:checked').val();\n\n if (currentPaymentMethod !== 'ppcp-gateway' && currentPaymentMethod !== 'ppcp-credit-card-gateway') {\n this.renderer.hideButtons(this.gateway.button.wrapper);\n this.renderer.hideButtons(this.gateway.messages.wrapper);\n this.renderer.hideButtons(this.gateway.hosted_fields.wrapper);\n jQuery('#place_order').show();\n } else {\n jQuery('#place_order').hide();\n\n if (currentPaymentMethod === 'ppcp-gateway') {\n this.renderer.showButtons(this.gateway.button.wrapper);\n this.renderer.showButtons(this.gateway.messages.wrapper);\n this.messages.render();\n this.renderer.hideButtons(this.gateway.hosted_fields.wrapper);\n }\n\n if (currentPaymentMethod === 'ppcp-credit-card-gateway') {\n this.renderer.hideButtons(this.gateway.button.wrapper);\n this.renderer.hideButtons(this.gateway.messages.wrapper);\n this.renderer.showButtons(this.gateway.hosted_fields.wrapper);\n }\n }\n }\n\n}\n\n/* harmony default export */ const ContextBootstrap_PayNowBootstrap = (PayNowBootstrap);\n;// CONCATENATED MODULE: ./resources/js/modules/Renderer/Renderer.js\nclass Renderer {\n constructor(creditCardRenderer, defaultConfig) {\n this.defaultConfig = defaultConfig;\n this.creditCardRenderer = creditCardRenderer;\n }\n\n render(wrapper, hostedFieldsWrapper, contextConfig) {\n this.renderButtons(wrapper, contextConfig);\n this.creditCardRenderer.render(hostedFieldsWrapper, contextConfig);\n }\n\n renderButtons(wrapper, contextConfig) {\n if (!document.querySelector(wrapper) || this.isAlreadyRendered(wrapper) || 'undefined' === typeof paypal.Buttons) {\n return;\n }\n\n const style = wrapper === this.defaultConfig.button.wrapper ? this.defaultConfig.button.style : this.defaultConfig.button.mini_cart_style;\n paypal.Buttons({\n style,\n ...contextConfig\n }).render(wrapper);\n }\n\n isAlreadyRendered(wrapper) {\n return document.querySelector(wrapper).hasChildNodes();\n }\n\n hideButtons(element) {\n const domElement = document.querySelector(element);\n\n if (!domElement) {\n return false;\n }\n\n domElement.style.display = 'none';\n return true;\n }\n\n showButtons(element) {\n const domElement = document.querySelector(element);\n\n if (!domElement) {\n return false;\n }\n\n domElement.style.display = 'block';\n return true;\n }\n\n disableCreditCardFields() {\n this.creditCardRenderer.disableFields();\n }\n\n enableCreditCardFields() {\n this.creditCardRenderer.enableFields();\n }\n\n}\n\n/* harmony default export */ const Renderer_Renderer = (Renderer);\n;// CONCATENATED MODULE: ./resources/js/modules/Helper/DccInputFactory.js\nconst dccInputFactory = original => {\n const styles = window.getComputedStyle(original);\n const newElement = document.createElement('span');\n newElement.setAttribute('id', original.id);\n Object.values(styles).forEach(prop => {\n if (!styles[prop] || !isNaN(prop)) {\n return;\n }\n\n newElement.style.setProperty(prop, '' + styles[prop]);\n });\n return newElement;\n};\n\n/* harmony default export */ const DccInputFactory = (dccInputFactory);\n;// CONCATENATED MODULE: ./resources/js/modules/Renderer/CreditCardRenderer.js\n\n\nclass CreditCardRenderer {\n constructor(defaultConfig, errorHandler, spinner) {\n this.defaultConfig = defaultConfig;\n this.errorHandler = errorHandler;\n this.spinner = spinner;\n this.cardValid = false;\n this.formValid = false;\n this.currentHostedFieldsInstance = null;\n this.formSubmissionSubscribed = false;\n }\n\n render(wrapper, contextConfig) {\n if (this.defaultConfig.context !== 'checkout' && this.defaultConfig.context !== 'pay-now' || wrapper === null || document.querySelector(wrapper) === null) {\n return;\n }\n\n if (typeof paypal.HostedFields === 'undefined' || !paypal.HostedFields.isEligible()) {\n const wrapperElement = document.querySelector(wrapper);\n wrapperElement.parentNode.removeChild(wrapperElement);\n return;\n }\n\n if (this.currentHostedFieldsInstance) {\n this.currentHostedFieldsInstance.teardown().catch(err => console.error(`Hosted fields teardown error: ${err}`));\n this.currentHostedFieldsInstance = null;\n }\n\n const gateWayBox = document.querySelector('.payment_box.payment_method_ppcp-credit-card-gateway');\n const oldDisplayStyle = gateWayBox.style.display;\n gateWayBox.style.display = 'block';\n const hideDccGateway = document.querySelector('#ppcp-hide-dcc');\n\n if (hideDccGateway) {\n hideDccGateway.parentNode.removeChild(hideDccGateway);\n }\n\n const cardNumberField = document.querySelector('#ppcp-credit-card-gateway-card-number');\n const stylesRaw = window.getComputedStyle(cardNumberField);\n let styles = {};\n Object.values(stylesRaw).forEach(prop => {\n if (!stylesRaw[prop]) {\n return;\n }\n\n styles[prop] = '' + stylesRaw[prop];\n });\n const cardNumber = DccInputFactory(cardNumberField);\n cardNumberField.parentNode.replaceChild(cardNumber, cardNumberField);\n const cardExpiryField = document.querySelector('#ppcp-credit-card-gateway-card-expiry');\n const cardExpiry = DccInputFactory(cardExpiryField);\n cardExpiryField.parentNode.replaceChild(cardExpiry, cardExpiryField);\n const cardCodeField = document.querySelector('#ppcp-credit-card-gateway-card-cvc');\n const cardCode = DccInputFactory(cardCodeField);\n cardCodeField.parentNode.replaceChild(cardCode, cardCodeField);\n gateWayBox.style.display = oldDisplayStyle;\n const formWrapper = '.payment_box payment_method_ppcp-credit-card-gateway';\n\n if (this.defaultConfig.enforce_vault && document.querySelector(formWrapper + ' .ppcp-credit-card-vault')) {\n document.querySelector(formWrapper + ' .ppcp-credit-card-vault').checked = true;\n document.querySelector(formWrapper + ' .ppcp-credit-card-vault').setAttribute('disabled', true);\n }\n\n paypal.HostedFields.render({\n createOrder: contextConfig.createOrder,\n styles: {\n 'input': styles\n },\n fields: {\n number: {\n selector: '#ppcp-credit-card-gateway-card-number',\n placeholder: this.defaultConfig.hosted_fields.labels.credit_card_number\n },\n cvv: {\n selector: '#ppcp-credit-card-gateway-card-cvc',\n placeholder: this.defaultConfig.hosted_fields.labels.cvv\n },\n expirationDate: {\n selector: '#ppcp-credit-card-gateway-card-expiry',\n placeholder: this.defaultConfig.hosted_fields.labels.mm_yy\n }\n }\n }).then(hostedFields => {\n document.dispatchEvent(new CustomEvent(\"hosted_fields_loaded\"));\n this.currentHostedFieldsInstance = hostedFields;\n hostedFields.on('inputSubmitRequest', () => {\n this._submit(contextConfig);\n });\n hostedFields.on('cardTypeChange', event => {\n if (!event.cards.length) {\n this.cardValid = false;\n return;\n }\n\n const validCards = this.defaultConfig.hosted_fields.valid_cards;\n this.cardValid = validCards.indexOf(event.cards[0].type) !== -1;\n });\n hostedFields.on('validityChange', event => {\n const formValid = Object.keys(event.fields).every(function (key) {\n return event.fields[key].isValid;\n });\n this.formValid = formValid;\n });\n\n if (!this.formSubmissionSubscribed) {\n document.querySelector(wrapper + ' button').addEventListener('click', event => {\n event.preventDefault();\n\n this._submit(contextConfig);\n });\n this.formSubmissionSubscribed = true;\n }\n });\n document.querySelector('#payment_method_ppcp-credit-card-gateway').addEventListener('click', () => {\n document.querySelector('label[for=ppcp-credit-card-gateway-card-number]').click();\n });\n }\n\n disableFields() {\n if (this.currentHostedFieldsInstance) {\n this.currentHostedFieldsInstance.setAttribute({\n field: 'number',\n attribute: 'disabled'\n });\n this.currentHostedFieldsInstance.setAttribute({\n field: 'cvv',\n attribute: 'disabled'\n });\n this.currentHostedFieldsInstance.setAttribute({\n field: 'expirationDate',\n attribute: 'disabled'\n });\n }\n }\n\n enableFields() {\n if (this.currentHostedFieldsInstance) {\n this.currentHostedFieldsInstance.removeAttribute({\n field: 'number',\n attribute: 'disabled'\n });\n this.currentHostedFieldsInstance.removeAttribute({\n field: 'cvv',\n attribute: 'disabled'\n });\n this.currentHostedFieldsInstance.removeAttribute({\n field: 'expirationDate',\n attribute: 'disabled'\n });\n }\n }\n\n _submit(contextConfig) {\n this.spinner.block();\n this.errorHandler.clear();\n\n if (this.formValid && this.cardValid) {\n const save_card = this.defaultConfig.save_card ? true : false;\n const vault = document.getElementById('ppcp-credit-card-vault') ? document.getElementById('ppcp-credit-card-vault').checked : save_card;\n const contingency = this.defaultConfig.hosted_fields.contingency;\n const hostedFieldsData = {\n vault: vault\n };\n\n if (contingency !== 'NO_3D_SECURE') {\n hostedFieldsData.contingencies = [contingency];\n }\n\n this.currentHostedFieldsInstance.submit(hostedFieldsData).then(payload => {\n payload.orderID = payload.orderId;\n this.spinner.unblock();\n return contextConfig.onApprove(payload);\n }).catch(err => {\n console.error(err);\n this.spinner.unblock();\n });\n } else {\n this.spinner.unblock();\n const message = !this.cardValid ? this.defaultConfig.hosted_fields.labels.card_not_supported : this.defaultConfig.hosted_fields.labels.fields_not_valid;\n this.errorHandler.message(message);\n }\n }\n\n}\n\n/* harmony default export */ const Renderer_CreditCardRenderer = (CreditCardRenderer);\n;// CONCATENATED MODULE: ./resources/js/modules/DataClientIdAttributeHandler.js\nconst storageKey = 'ppcp-data-client-id';\n\nconst validateToken = (token, user) => {\n if (!token) {\n return false;\n }\n\n if (token.user !== user) {\n return false;\n }\n\n const currentTime = new Date().getTime();\n const isExpired = currentTime >= token.expiration * 1000;\n return !isExpired;\n};\n\nconst storedTokenForUser = user => {\n const token = JSON.parse(sessionStorage.getItem(storageKey));\n\n if (validateToken(token, user)) {\n return token.token;\n }\n\n return null;\n};\n\nconst storeToken = token => {\n sessionStorage.setItem(storageKey, JSON.stringify(token));\n};\n\nconst dataClientIdAttributeHandler = (script, config) => {\n fetch(config.endpoint, {\n method: 'POST',\n body: JSON.stringify({\n nonce: config.nonce\n })\n }).then(res => {\n return res.json();\n }).then(data => {\n const isValid = validateToken(data, config.user);\n\n if (!isValid) {\n return;\n }\n\n storeToken(data);\n script.setAttribute('data-client-token', data.token);\n document.body.append(script);\n });\n};\n\n/* harmony default export */ const DataClientIdAttributeHandler = (dataClientIdAttributeHandler);\n;// CONCATENATED MODULE: ./resources/js/modules/Renderer/MessageRenderer.js\nclass MessageRenderer {\n constructor(config) {\n this.config = config;\n }\n\n render() {\n if (!this.shouldRender()) {\n return;\n }\n\n paypal.Messages({\n amount: this.config.amount,\n placement: this.config.placement,\n style: this.config.style\n }).render(this.config.wrapper);\n }\n\n renderWithAmount(amount) {\n if (!this.shouldRender()) {\n return;\n }\n\n const newWrapper = document.createElement('div');\n newWrapper.setAttribute('id', this.config.wrapper.replace('#', ''));\n const sibling = document.querySelector(this.config.wrapper).nextSibling;\n document.querySelector(this.config.wrapper).parentElement.removeChild(document.querySelector(this.config.wrapper));\n sibling.parentElement.insertBefore(newWrapper, sibling);\n paypal.Messages({\n amount,\n placement: this.config.placement,\n style: this.config.style\n }).render(this.config.wrapper);\n }\n\n shouldRender() {\n if (typeof paypal.Messages === 'undefined' || typeof this.config.wrapper === 'undefined') {\n return false;\n }\n\n if (!document.querySelector(this.config.wrapper)) {\n return false;\n }\n\n return true;\n }\n\n}\n\n/* harmony default export */ const Renderer_MessageRenderer = (MessageRenderer);\n;// CONCATENATED MODULE: ./resources/js/modules/Helper/Spinner.js\nclass Spinner {\n constructor() {\n this.target = 'form.woocommerce-checkout';\n }\n\n setTarget(target) {\n this.target = target;\n }\n\n block() {\n jQuery(this.target).block({\n message: null,\n overlayCSS: {\n background: '#fff',\n opacity: 0.6\n }\n });\n }\n\n unblock() {\n jQuery(this.target).unblock();\n }\n\n}\n\n/* harmony default export */ const Helper_Spinner = (Spinner);\n;// CONCATENATED MODULE: ./resources/js/button.js\n\n\n\n\n\n\n\n\n\n\n\n\nconst bootstrap = () => {\n const errorHandler = new modules_ErrorHandler(PayPalCommerceGateway.labels.error.generic);\n const spinner = new Helper_Spinner();\n const creditCardRenderer = new Renderer_CreditCardRenderer(PayPalCommerceGateway, errorHandler, spinner);\n const renderer = new Renderer_Renderer(creditCardRenderer, PayPalCommerceGateway);\n const messageRenderer = new Renderer_MessageRenderer(PayPalCommerceGateway.messages);\n const context = PayPalCommerceGateway.context;\n\n if (context === 'mini-cart' || context === 'product') {\n if (PayPalCommerceGateway.mini_cart_buttons_enabled === '1') {\n const miniCartBootstrap = new ContextBootstrap_MiniCartBootstap(PayPalCommerceGateway, renderer);\n miniCartBootstrap.init();\n }\n }\n\n if (context === 'product' && PayPalCommerceGateway.single_product_buttons_enabled === '1') {\n const singleProductBootstrap = new ContextBootstrap_SingleProductBootstap(PayPalCommerceGateway, renderer, messageRenderer);\n singleProductBootstrap.init();\n }\n\n if (context === 'cart') {\n const cartBootstrap = new CartBootstap(PayPalCommerceGateway, renderer);\n cartBootstrap.init();\n }\n\n if (context === 'checkout') {\n const checkoutBootstap = new ContextBootstrap_CheckoutBootstap(PayPalCommerceGateway, renderer, messageRenderer, spinner);\n checkoutBootstap.init();\n }\n\n if (context === 'pay-now') {\n const payNowBootstrap = new ContextBootstrap_PayNowBootstrap(PayPalCommerceGateway, renderer, messageRenderer, spinner);\n payNowBootstrap.init();\n }\n\n if (context !== 'checkout') {\n messageRenderer.render();\n }\n};\n\ndocument.addEventListener('DOMContentLoaded', () => {\n if (!typeof PayPalCommerceGateway) {\n console.error('PayPal button could not be configured.');\n return;\n }\n\n const script = document.createElement('script');\n script.addEventListener('load', event => {\n bootstrap();\n });\n script.setAttribute('src', PayPalCommerceGateway.button.url);\n Object.entries(PayPalCommerceGateway.script_attributes).forEach(keyValue => {\n script.setAttribute(keyValue[0], keyValue[1]);\n });\n\n if (PayPalCommerceGateway.data_client_id.set_attribute) {\n DataClientIdAttributeHandler(script, PayPalCommerceGateway.data_client_id);\n return;\n }\n\n document.body.append(script);\n});//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,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QUFBQSxPQUFPLENBQUNDLEtBQVIsQ0FBYyx3Q0FBZDtBQUNBO0FBQ0g7O0FBQ0QsUUFBTWdOLE1BQU0sR0FBR3ZTLFFBQVEsQ0FBQ3dCLGFBQVQsQ0FBdUIsUUFBdkIsQ0FBZjtBQUVBK1EsRUFBQUEsTUFBTSxDQUFDaEMsZ0JBQVAsQ0FBd0IsTUFBeEIsRUFBaUNWLEtBQUQsSUFBVztBQUN2Q3lELElBQUFBLFNBQVM7QUFDWixHQUZEO0FBR0FmLEVBQUFBLE1BQU0sQ0FBQzlRLFlBQVAsQ0FBb0IsS0FBcEIsRUFBMkJxQyxxQkFBcUIsQ0FBQ3NDLE1BQXRCLENBQTZCMk4sR0FBeEQ7QUFDQTVHLEVBQUFBLE1BQU0sQ0FBQzZHLE9BQVAsQ0FBZWxRLHFCQUFxQixDQUFDbVEsaUJBQXJDLEVBQXdEMUwsT0FBeEQsQ0FDSzJMLFFBQUQsSUFBYztBQUNWM0IsSUFBQUEsTUFBTSxDQUFDOVEsWUFBUCxDQUFvQnlTLFFBQVEsQ0FBQyxDQUFELENBQTVCLEVBQWlDQSxRQUFRLENBQUMsQ0FBRCxDQUF6QztBQUNILEdBSEw7O0FBTUEsTUFBSXBRLHFCQUFxQixDQUFDcVEsY0FBdEIsQ0FBcUNDLGFBQXpDLEVBQXdEO0FBQ3BEOUIsSUFBQUEsNEJBQTRCLENBQUNDLE1BQUQsRUFBU3pPLHFCQUFxQixDQUFDcVEsY0FBL0IsQ0FBNUI7QUFDQTtBQUNIOztBQUVEblUsRUFBQUEsUUFBUSxDQUFDNEMsSUFBVCxDQUFjNkgsTUFBZCxDQUFxQjhILE1BQXJCO0FBQ0gsQ0F6QkwiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9wcGMtYnV0dG9uLy4vcmVzb3VyY2VzL2pzL21vZHVsZXMvRXJyb3JIYW5kbGVyLmpzP2U2NWEiLCJ3ZWJwYWNrOi8vcHBjLWJ1dHRvbi8uL3Jlc291cmNlcy9qcy9tb2R1bGVzL09uQXBwcm92ZUhhbmRsZXIvb25BcHByb3ZlRm9yQ29udGludWUuanM/YzQ1NCIsIndlYnBhY2s6Ly9wcGMtYnV0dG9uLy4vcmVzb3VyY2VzL2pzL21vZHVsZXMvSGVscGVyL1BheWVyRGF0YS5qcz8yYWYxIiwid2VicGFjazovL3BwYy1idXR0b24vLi9yZXNvdXJjZXMvanMvbW9kdWxlcy9BY3Rpb25IYW5kbGVyL0NhcnRBY3Rpb25IYW5kbGVyLmpzPzgyY2YiLCJ3ZWJwYWNrOi8vcHBjLWJ1dHRvbi8uL3Jlc291cmNlcy9qcy9tb2R1bGVzL0NvbnRleHRCb290c3RyYXAvTWluaUNhcnRCb290c3RhcC5qcz9kNTUyIiwid2VicGFjazovL3BwYy1idXR0b24vLi9yZXNvdXJjZXMvanMvbW9kdWxlcy9IZWxwZXIvVXBkYXRlQ2FydC5qcz9lNDIyIiwid2VicGFjazovL3BwYy1idXR0b24vLi9yZXNvdXJjZXMvanMvbW9kdWxlcy9IZWxwZXIvQnV0dG9uc1RvZ2dsZUxpc3RlbmVyLmpzP2UxOTMiLCJ3ZWJwYWNrOi8vcHBjLWJ1dHRvbi8uL3Jlc291cmNlcy9qcy9tb2R1bGVzL0VudGl0eS9Qcm9kdWN0LmpzPzlmZmYiLCJ3ZWJwYWNrOi8vcHBjLWJ1dHRvbi8uL3Jlc291cmNlcy9qcy9tb2R1bGVzL0FjdGlvbkhhbmRsZXIvU2luZ2xlUHJvZHVjdEFjdGlvbkhhbmRsZXIuanM/ZDliNyIsIndlYnBhY2s6Ly9wcGMtYnV0dG9uLy4vcmVzb3VyY2VzL2pzL21vZHVsZXMvQ29udGV4dEJvb3RzdHJhcC9TaW5nbGVQcm9kdWN0Qm9vdHN0YXAuanM/N2MxOSIsIndlYnBhY2s6Ly9wcGMtYnV0dG9uLy4vcmVzb3VyY2VzL2pzL21vZHVsZXMvQ29udGV4dEJvb3RzdHJhcC9DYXJ0Qm9vdHN0YXAuanM/NWU5NCIsIndlYnBhY2s6Ly9wcGMtYnV0dG9uLy4vcmVzb3VyY2VzL2pzL21vZHVsZXMvT25BcHByb3ZlSGFuZGxlci9vbkFwcHJvdmVGb3JQYXlOb3cuanM/OTMwNSIsIndlYnBhY2s6Ly9wcGMtYnV0dG9uLy4vcmVzb3VyY2VzL2pzL21vZHVsZXMvQWN0aW9uSGFuZGxlci9DaGVja291dEFjdGlvbkhhbmRsZXIuanM/ODUxNSIsIndlYnBhY2s6Ly9wcGMtYnV0dG9uLy4vcmVzb3VyY2VzL2pzL21vZHVsZXMvQ29udGV4dEJvb3RzdHJhcC9DaGVja291dEJvb3RzdGFwLmpzP2M4NTUiLCJ3ZWJwYWNrOi8vcHBjLWJ1dHRvbi8uL3Jlc291cmNlcy9qcy9tb2R1bGVzL0NvbnRleHRCb290c3RyYXAvUGF5Tm93Qm9vdHN0cmFwLmpzP2Q5ZjUiLCJ3ZWJwYWNrOi8vcHBjLWJ1dHRvbi8uL3Jlc291cmNlcy9qcy9tb2R1bGVzL1JlbmRlcmVyL1JlbmRlcmVyLmpzP2ZhOTMiLCJ3ZWJwYWNrOi8vcHBjLWJ1dHRvbi8uL3Jlc291cmNlcy9qcy9tb2R1bGVzL0hlbHBlci9EY2NJbnB1dEZhY3RvcnkuanM/MmEyZiIsIndlYnBhY2s6Ly9wcGMtYnV0dG9uLy4vcmVzb3VyY2VzL2pzL21vZHVsZXMvUmVuZGVyZXIvQ3JlZGl0Q2FyZFJlbmRlcmVyLmpzPzM4N2EiLCJ3ZWJwYWNrOi8vcHBjLWJ1dHRvbi8uL3Jlc291cmNlcy9qcy9tb2R1bGVzL0RhdGFDbGllbnRJZEF0dHJpYnV0ZUhhbmRsZXIuanM/ZWUwYiIsIndlYnBhY2s6Ly9wcGMtYnV0dG9uLy4vcmVzb3VyY2VzL2pzL21vZHVsZXMvUmVuZGVyZXIvTWVzc2FnZVJlbmRlcmVyLmpzP2NkMDIiLCJ3ZWJwYWNrOi8vcHBjLWJ1dHRvbi8uL3Jlc291cmNlcy9qcy9tb2R1bGVzL0hlbHBlci9TcGlubmVyLmpzPzE3MDgiLCJ3ZWJwYWNrOi8vcHBjLWJ1dHRvbi8uL3Jlc291cmNlcy9qcy9idXR0b24uanM/MDYwZiJdLCJzb3VyY2VzQ29udGVudCI6WyJjbGFzcyBFcnJvckhhbmRsZXIge1xuXG4gICAgY29uc3RydWN0b3IoZ2VuZXJpY0Vycm9yVGV4dClcbiAgICB7XG4gICAgICAgIHRoaXMuZ2VuZXJpY0Vycm9yVGV4dCA9IGdlbmVyaWNFcnJvclRleHQ7XG4gICAgICAgIHRoaXMud3JhcHBlciA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJy53b29jb21tZXJjZS1ub3RpY2VzLXdyYXBwZXInKTtcbiAgICAgICAgdGhpcy5tZXNzYWdlc0xpc3QgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCd1bC53b29jb21tZXJjZS1lcnJvcicpO1xuICAgIH1cblxuICAgIGdlbmVyaWNFcnJvcigpIHtcbiAgICAgICAgaWYgKHRoaXMud3JhcHBlci5jbGFzc0xpc3QuY29udGFpbnMoJ3BwY3AtcGVyc2lzdCcpKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5jbGVhcigpO1xuICAgICAgICB0aGlzLm1lc3NhZ2UodGhpcy5nZW5lcmljRXJyb3JUZXh0KVxuICAgIH1cblxuICAgIGFwcGVuZFByZXBhcmVkRXJyb3JNZXNzYWdlRWxlbWVudChlcnJvck1lc3NhZ2VFbGVtZW50KVxuICAgIHtcbiAgICAgICAgaWYodGhpcy5tZXNzYWdlc0xpc3QgPT09IG51bGwpIHtcbiAgICAgICAgICAgIHRoaXMucHJlcGFyZU1lc3NhZ2VzTGlzdCgpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5tZXNzYWdlc0xpc3QucmVwbGFjZVdpdGgoZXJyb3JNZXNzYWdlRWxlbWVudCk7XG4gICAgfVxuXG4gICAgbWVzc2FnZSh0ZXh0LCBwZXJzaXN0ID0gZmFsc2UpXG4gICAge1xuICAgICAgICBpZighIHR5cGVvZiBTdHJpbmcgfHwgdGV4dC5sZW5ndGggPT09IDApe1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdBIG5ldyBtZXNzYWdlIHRleHQgbXVzdCBiZSBhIG5vbi1lbXB0eSBzdHJpbmcuJyk7XG4gICAgICAgIH1cblxuICAgICAgICBpZih0aGlzLm1lc3NhZ2VzTGlzdCA9PT0gbnVsbCl7XG4gICAgICAgICAgICB0aGlzLnByZXBhcmVNZXNzYWdlc0xpc3QoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChwZXJzaXN0KSB7XG4gICAgICAgICAgICB0aGlzLndyYXBwZXIuY2xhc3NMaXN0LmFkZCgncHBjcC1wZXJzaXN0Jyk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLndyYXBwZXIuY2xhc3NMaXN0LnJlbW92ZSgncHBjcC1wZXJzaXN0Jyk7XG4gICAgICAgIH1cblxuICAgICAgICBsZXQgbWVzc2FnZU5vZGUgPSB0aGlzLnByZXBhcmVNZXNzYWdlc0xpc3RJdGVtKHRleHQpO1xuICAgICAgICB0aGlzLm1lc3NhZ2VzTGlzdC5hcHBlbmRDaGlsZChtZXNzYWdlTm9kZSk7XG5cbiAgICAgICAgalF1ZXJ5LnNjcm9sbF90b19ub3RpY2VzKGpRdWVyeSgnLndvb2NvbW1lcmNlLW5vdGljZXMtd3JhcHBlcicpKVxuICAgIH1cblxuICAgIHByZXBhcmVNZXNzYWdlc0xpc3QoKVxuICAgIHtcbiAgICAgICAgaWYodGhpcy5tZXNzYWdlc0xpc3QgPT09IG51bGwpe1xuICAgICAgICAgICAgdGhpcy5tZXNzYWdlc0xpc3QgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCd1bCcpO1xuICAgICAgICAgICAgdGhpcy5tZXNzYWdlc0xpc3Quc2V0QXR0cmlidXRlKCdjbGFzcycsICd3b29jb21tZXJjZS1lcnJvcicpO1xuICAgICAgICAgICAgdGhpcy5tZXNzYWdlc0xpc3Quc2V0QXR0cmlidXRlKCdyb2xlJywgJ2FsZXJ0Jyk7XG4gICAgICAgICAgICB0aGlzLndyYXBwZXIuYXBwZW5kQ2hpbGQodGhpcy5tZXNzYWdlc0xpc3QpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJlcGFyZU1lc3NhZ2VzTGlzdEl0ZW0obWVzc2FnZSlcbiAgICB7XG4gICAgICAgIGNvbnN0IGxpID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnbGknKTtcbiAgICAgICAgbGkuaW5uZXJIVE1MID0gbWVzc2FnZTtcblxuICAgICAgICByZXR1cm4gbGk7XG4gICAgfVxuXG4gICAgc2FuaXRpemUodGV4dClcbiAgICB7XG4gICAgICAgIGNvbnN0IHRleHRhcmVhID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgndGV4dGFyZWEnKTtcbiAgICAgICAgdGV4dGFyZWEuaW5uZXJIVE1MID0gdGV4dDtcbiAgICAgICAgcmV0dXJuIHRleHRhcmVhLnZhbHVlLnJlcGxhY2UoJ0Vycm9yOiAnLCAnJyk7XG4gICAgfVxuXG4gICAgY2xlYXIoKVxuICAgIHtcbiAgICAgICAgaWYgKCEgdGhpcy53cmFwcGVyLmNsYXNzTGlzdC5jb250YWlucygnd29vY29tbWVyY2UtZXJyb3InKSkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMud3JhcHBlci5jbGFzc0xpc3QucmVtb3ZlKCd3b29jb21tZXJjZS1lcnJvcicpO1xuICAgICAgICB0aGlzLndyYXBwZXIuaW5uZXJUZXh0ID0gJyc7XG4gICAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBFcnJvckhhbmRsZXI7XG4iLCJjb25zdCBvbkFwcHJvdmUgPSAoY29udGV4dCwgZXJyb3JIYW5kbGVyKSA9PiB7XG4gICAgcmV0dXJuIChkYXRhLCBhY3Rpb25zKSA9PiB7XG4gICAgICAgIHJldHVybiBmZXRjaChjb250ZXh0LmNvbmZpZy5hamF4LmFwcHJvdmVfb3JkZXIuZW5kcG9pbnQsIHtcbiAgICAgICAgICAgIG1ldGhvZDogJ1BPU1QnLFxuICAgICAgICAgICAgYm9keTogSlNPTi5zdHJpbmdpZnkoe1xuICAgICAgICAgICAgICAgIG5vbmNlOiBjb250ZXh0LmNvbmZpZy5hamF4LmFwcHJvdmVfb3JkZXIubm9uY2UsXG4gICAgICAgICAgICAgICAgb3JkZXJfaWQ6ZGF0YS5vcmRlcklEXG4gICAgICAgICAgICB9KVxuICAgICAgICB9KS50aGVuKChyZXMpPT57XG4gICAgICAgICAgICByZXR1cm4gcmVzLmpzb24oKTtcbiAgICAgICAgfSkudGhlbigoZGF0YSk9PntcbiAgICAgICAgICAgIGlmICghZGF0YS5zdWNjZXNzKSB7XG4gICAgICAgICAgICAgICAgZXJyb3JIYW5kbGVyLmdlbmVyaWNFcnJvcigpO1xuICAgICAgICAgICAgICAgIHJldHVybiBhY3Rpb25zLnJlc3RhcnQoKS5jYXRjaChlcnIgPT4ge1xuICAgICAgICAgICAgICAgICAgICBlcnJvckhhbmRsZXIuZ2VuZXJpY0Vycm9yKCk7XG4gICAgICAgICAgICAgICAgfSk7O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgbG9jYXRpb24uaHJlZiA9IGNvbnRleHQuY29uZmlnLnJlZGlyZWN0O1xuICAgICAgICB9KTtcblxuICAgIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgb25BcHByb3ZlO1xuIiwiZXhwb3J0IGNvbnN0IHBheWVyRGF0YSA9ICgpID0+IHtcbiAgICBjb25zdCBwYXllciA9IFBheVBhbENvbW1lcmNlR2F0ZXdheS5wYXllcjtcbiAgICBpZiAoISBwYXllcikge1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG5cbiAgICBjb25zdCBwaG9uZSA9IChkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjYmlsbGluZ19waG9uZScpIHx8IHR5cGVvZiBwYXllci5waG9uZSAhPT0gJ3VuZGVmaW5lZCcpID9cbiAgICB7XG4gICAgICAgIHBob25lX3R5cGU6XCJIT01FXCIsXG4gICAgICAgICAgICBwaG9uZV9udW1iZXI6e1xuICAgICAgICAgICAgbmF0aW9uYWxfbnVtYmVyIDogKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNiaWxsaW5nX3Bob25lJykpID8gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI2JpbGxpbmdfcGhvbmUnKS52YWx1ZSA6IHBheWVyLnBob25lLnBob25lX251bWJlci5uYXRpb25hbF9udW1iZXJcbiAgICAgICAgfVxuICAgIH0gOiBudWxsO1xuICAgIGNvbnN0IHBheWVyRGF0YSA9IHtcbiAgICAgICAgZW1haWxfYWRkcmVzczooZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI2JpbGxpbmdfZW1haWwnKSkgPyBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjYmlsbGluZ19lbWFpbCcpLnZhbHVlIDogcGF5ZXIuZW1haWxfYWRkcmVzcyxcbiAgICAgICAgbmFtZSA6IHtcbiAgICAgICAgICAgIHN1cm5hbWU6IChkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjYmlsbGluZ19sYXN0X25hbWUnKSkgPyBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjYmlsbGluZ19sYXN0X25hbWUnKS52YWx1ZSA6IHBheWVyLm5hbWUuc3VybmFtZSxcbiAgICAgICAgICAgIGdpdmVuX25hbWU6IChkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjYmlsbGluZ19maXJzdF9uYW1lJykpID8gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI2JpbGxpbmdfZmlyc3RfbmFtZScpLnZhbHVlIDogcGF5ZXIubmFtZS5naXZlbl9uYW1lXG4gICAgICAgIH0sXG4gICAgICAgIGFkZHJlc3MgOiB7XG4gICAgICAgICAgICBjb3VudHJ5X2NvZGUgOiAoZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI2JpbGxpbmdfY291bnRyeScpKSA/IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNiaWxsaW5nX2NvdW50cnknKS52YWx1ZSA6IHBheWVyLmFkZHJlc3MuY291bnRyeV9jb2RlLFxuICAgICAgICAgICAgYWRkcmVzc19saW5lXzEgOiAoZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI2JpbGxpbmdfYWRkcmVzc18xJykpID8gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI2JpbGxpbmdfYWRkcmVzc18xJykudmFsdWUgOiBwYXllci5hZGRyZXNzLmFkZHJlc3NfbGluZV8xLFxuICAgICAgICAgICAgYWRkcmVzc19saW5lXzIgOiAoZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI2JpbGxpbmdfYWRkcmVzc18yJykpID8gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI2JpbGxpbmdfYWRkcmVzc18yJykudmFsdWUgOiBwYXllci5hZGRyZXNzLmFkZHJlc3NfbGluZV8yLFxuICAgICAgICAgICAgYWRtaW5fYXJlYV8xIDogKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNiaWxsaW5nX3N0YXRlJykpID8gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI2JpbGxpbmdfc3RhdGUnKS52YWx1ZSA6IHBheWVyLmFkZHJlc3MuYWRtaW5fYXJlYV8xLFxuICAgICAgICAgICAgYWRtaW5fYXJlYV8yIDogKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNiaWxsaW5nX2NpdHknKSkgPyBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjYmlsbGluZ19jaXR5JykudmFsdWUgOiBwYXllci5hZGRyZXNzLmFkbWluX2FyZWFfMixcbiAgICAgICAgICAgIHBvc3RhbF9jb2RlIDogKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNiaWxsaW5nX3Bvc3Rjb2RlJykpID8gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI2JpbGxpbmdfcG9zdGNvZGUnKS52YWx1ZSA6IHBheWVyLmFkZHJlc3MucG9zdGFsX2NvZGVcbiAgICAgICAgfVxuICAgIH07XG5cbiAgICBpZiAocGhvbmUpIHtcbiAgICAgICAgcGF5ZXJEYXRhLnBob25lID0gcGhvbmU7XG4gICAgfVxuICAgIHJldHVybiBwYXllckRhdGE7XG59XG4iLCJpbXBvcnQgb25BcHByb3ZlIGZyb20gJy4uL09uQXBwcm92ZUhhbmRsZXIvb25BcHByb3ZlRm9yQ29udGludWUuanMnO1xuaW1wb3J0IHtwYXllckRhdGF9IGZyb20gXCIuLi9IZWxwZXIvUGF5ZXJEYXRhXCI7XG5cbmNsYXNzIENhcnRBY3Rpb25IYW5kbGVyIHtcblxuICAgIGNvbnN0cnVjdG9yKGNvbmZpZywgZXJyb3JIYW5kbGVyKSB7XG4gICAgICAgIHRoaXMuY29uZmlnID0gY29uZmlnO1xuICAgICAgICB0aGlzLmVycm9ySGFuZGxlciA9IGVycm9ySGFuZGxlcjtcbiAgICB9XG5cbiAgICBjb25maWd1cmF0aW9uKCkge1xuICAgICAgICBjb25zdCBjcmVhdGVPcmRlciA9IChkYXRhLCBhY3Rpb25zKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBwYXllciA9IHBheWVyRGF0YSgpO1xuICAgICAgICAgICAgY29uc3QgYm5Db2RlID0gdHlwZW9mIHRoaXMuY29uZmlnLmJuX2NvZGVzW3RoaXMuY29uZmlnLmNvbnRleHRdICE9PSAndW5kZWZpbmVkJyA/XG4gICAgICAgICAgICAgICAgdGhpcy5jb25maWcuYm5fY29kZXNbdGhpcy5jb25maWcuY29udGV4dF0gOiAnJztcbiAgICAgICAgICAgIHJldHVybiBmZXRjaCh0aGlzLmNvbmZpZy5hamF4LmNyZWF0ZV9vcmRlci5lbmRwb2ludCwge1xuICAgICAgICAgICAgICAgIG1ldGhvZDogJ1BPU1QnLFxuICAgICAgICAgICAgICAgIGJvZHk6IEpTT04uc3RyaW5naWZ5KHtcbiAgICAgICAgICAgICAgICAgICAgbm9uY2U6IHRoaXMuY29uZmlnLmFqYXguY3JlYXRlX29yZGVyLm5vbmNlLFxuICAgICAgICAgICAgICAgICAgICBwdXJjaGFzZV91bml0czogW10sXG4gICAgICAgICAgICAgICAgICAgIGJuX2NvZGU6Ym5Db2RlLFxuICAgICAgICAgICAgICAgICAgICBwYXllcixcbiAgICAgICAgICAgICAgICAgICAgY29udGV4dDp0aGlzLmNvbmZpZy5jb250ZXh0XG4gICAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICB9KS50aGVuKGZ1bmN0aW9uKHJlcykge1xuICAgICAgICAgICAgICAgIHJldHVybiByZXMuanNvbigpO1xuICAgICAgICAgICAgfSkudGhlbihmdW5jdGlvbihkYXRhKSB7XG4gICAgICAgICAgICAgICAgaWYgKCFkYXRhLnN1Y2Nlc3MpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihkYXRhKTtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgRXJyb3IoZGF0YS5kYXRhLm1lc3NhZ2UpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gZGF0YS5kYXRhLmlkO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH07XG5cbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGNyZWF0ZU9yZGVyLFxuICAgICAgICAgICAgb25BcHByb3ZlOiBvbkFwcHJvdmUodGhpcywgdGhpcy5lcnJvckhhbmRsZXIpLFxuICAgICAgICAgICAgb25FcnJvcjogKGVycm9yKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5lcnJvckhhbmRsZXIuZ2VuZXJpY0Vycm9yKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBDYXJ0QWN0aW9uSGFuZGxlcjtcbiIsImltcG9ydCBFcnJvckhhbmRsZXIgZnJvbSAnLi4vRXJyb3JIYW5kbGVyJztcbmltcG9ydCBDYXJ0QWN0aW9uSGFuZGxlciBmcm9tICcuLi9BY3Rpb25IYW5kbGVyL0NhcnRBY3Rpb25IYW5kbGVyJztcblxuY2xhc3MgTWluaUNhcnRCb290c3RhcCB7XG4gICAgY29uc3RydWN0b3IoZ2F0ZXdheSwgcmVuZGVyZXIpIHtcbiAgICAgICAgdGhpcy5nYXRld2F5ID0gZ2F0ZXdheTtcbiAgICAgICAgdGhpcy5yZW5kZXJlciA9IHJlbmRlcmVyO1xuICAgICAgICB0aGlzLmFjdGlvbkhhbmRsZXIgPSBudWxsO1xuICAgIH1cblxuICAgIGluaXQoKSB7XG5cbiAgICAgICAgdGhpcy5hY3Rpb25IYW5kbGVyID0gbmV3IENhcnRBY3Rpb25IYW5kbGVyKFxuICAgICAgICAgICAgUGF5UGFsQ29tbWVyY2VHYXRld2F5LFxuICAgICAgICAgICAgbmV3IEVycm9ySGFuZGxlcih0aGlzLmdhdGV3YXkubGFiZWxzLmVycm9yLmdlbmVyaWMpLFxuICAgICAgICApO1xuICAgICAgICB0aGlzLnJlbmRlcigpO1xuXG4gICAgICAgIGpRdWVyeShkb2N1bWVudC5ib2R5KS5vbignd2NfZnJhZ21lbnRzX2xvYWRlZCB3Y19mcmFnbWVudHNfcmVmcmVzaGVkJywgKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5yZW5kZXIoKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgc2hvdWxkUmVuZGVyKCkge1xuICAgICAgICByZXR1cm4gZG9jdW1lbnQucXVlcnlTZWxlY3Rvcih0aGlzLmdhdGV3YXkuYnV0dG9uLm1pbmlfY2FydF93cmFwcGVyKSAhPT1cbiAgICAgICAgICAgIG51bGwgfHwgZG9jdW1lbnQucXVlcnlTZWxlY3Rvcih0aGlzLmdhdGV3YXkuaG9zdGVkX2ZpZWxkcy5taW5pX2NhcnRfd3JhcHBlcikgIT09XG4gICAgICAgIG51bGw7XG4gICAgfVxuXG4gICAgcmVuZGVyKCkge1xuICAgICAgICBpZiAoIXRoaXMuc2hvdWxkUmVuZGVyKCkpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMucmVuZGVyZXIucmVuZGVyKFxuICAgICAgICAgICAgdGhpcy5nYXRld2F5LmJ1dHRvbi5taW5pX2NhcnRfd3JhcHBlcixcbiAgICAgICAgICAgIHRoaXMuZ2F0ZXdheS5ob3N0ZWRfZmllbGRzLm1pbmlfY2FydF93cmFwcGVyLFxuICAgICAgICAgICAgdGhpcy5hY3Rpb25IYW5kbGVyLmNvbmZpZ3VyYXRpb24oKVxuICAgICAgICApO1xuICAgIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgTWluaUNhcnRCb290c3RhcDsiLCJpbXBvcnQgUHJvZHVjdCBmcm9tIFwiLi4vRW50aXR5L1Byb2R1Y3RcIjtcbmNsYXNzIFVwZGF0ZUNhcnQge1xuXG4gICAgY29uc3RydWN0b3IoZW5kcG9pbnQsIG5vbmNlKVxuICAgIHtcbiAgICAgICAgdGhpcy5lbmRwb2ludCA9IGVuZHBvaW50O1xuICAgICAgICB0aGlzLm5vbmNlID0gbm9uY2U7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICpcbiAgICAgKiBAcGFyYW0gb25SZXNvbHZlXG4gICAgICogQHBhcmFtIHtQcm9kdWN0W119IHByb2R1Y3RzXG4gICAgICogQHJldHVybnMge1Byb21pc2U8dW5rbm93bj59XG4gICAgICovXG4gICAgdXBkYXRlKG9uUmVzb2x2ZSwgcHJvZHVjdHMpXG4gICAge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgZmV0Y2goXG4gICAgICAgICAgICAgICAgdGhpcy5lbmRwb2ludCxcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIG1ldGhvZDogJ1BPU1QnLFxuICAgICAgICAgICAgICAgICAgICBib2R5OiBKU09OLnN0cmluZ2lmeSh7XG4gICAgICAgICAgICAgICAgICAgICAgICBub25jZTogdGhpcy5ub25jZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHByb2R1Y3RzLFxuICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICkudGhlbihcbiAgICAgICAgICAgICAgICAocmVzdWx0KSA9PiB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdC5qc29uKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgKS50aGVuKChyZXN1bHQpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoISByZXN1bHQuc3VjY2Vzcykge1xuICAgICAgICAgICAgICAgICAgICByZWplY3QocmVzdWx0LmRhdGEpO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHJlc29sdmVkID0gb25SZXNvbHZlKHJlc3VsdC5kYXRhKTtcbiAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZShyZXNvbHZlZCk7XG4gICAgICAgICAgICAgICAgfSlcbiAgICAgICAgfSk7XG4gICAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBVcGRhdGVDYXJ0OyIsIi8qKlxuICogV2hlbiB5b3UgY2FuJ3QgYWRkIHNvbWV0aGluZyB0byB0aGUgY2FydCwgdGhlIFBheVBhbCBidXR0b25zIHNob3VsZCBub3Qgc2hvdy5cbiAqIFRoZXJlZm9yZSB3ZSBsaXN0ZW4gZm9yIGNoYW5nZXMgb24gdGhlIGFkZCB0byBjYXJ0IGJ1dHRvbiBhbmQgc2hvdy9oaWRlIHRoZSBidXR0b25zIGFjY29yZGluZ2x5LlxuICovXG5cbmNsYXNzIEJ1dHRvbnNUb2dnbGVMaXN0ZW5lciB7XG4gICAgY29uc3RydWN0b3IoZWxlbWVudCwgc2hvd0NhbGxiYWNrLCBoaWRlQ2FsbGJhY2spXG4gICAge1xuICAgICAgICB0aGlzLmVsZW1lbnQgPSBlbGVtZW50O1xuICAgICAgICB0aGlzLnNob3dDYWxsYmFjayA9IHNob3dDYWxsYmFjaztcbiAgICAgICAgdGhpcy5oaWRlQ2FsbGJhY2sgPSBoaWRlQ2FsbGJhY2s7XG4gICAgICAgIHRoaXMub2JzZXJ2ZXIgPSBudWxsO1xuICAgIH1cblxuICAgIGluaXQoKVxuICAgIHtcbiAgICAgICAgY29uc3QgY29uZmlnID0geyBhdHRyaWJ1dGVzIDogdHJ1ZSB9O1xuICAgICAgICBjb25zdCBjYWxsYmFjayA9ICgpID0+IHtcbiAgICAgICAgICAgIGlmICh0aGlzLmVsZW1lbnQuY2xhc3NMaXN0LmNvbnRhaW5zKCdkaXNhYmxlZCcpKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5oaWRlQ2FsbGJhY2soKTtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLnNob3dDYWxsYmFjaygpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMub2JzZXJ2ZXIgPSBuZXcgTXV0YXRpb25PYnNlcnZlcihjYWxsYmFjayk7XG4gICAgICAgIHRoaXMub2JzZXJ2ZXIub2JzZXJ2ZSh0aGlzLmVsZW1lbnQsIGNvbmZpZyk7XG4gICAgICAgIGNhbGxiYWNrKCk7XG4gICAgfVxuXG4gICAgZGlzY29ubmVjdCgpXG4gICAge1xuICAgICAgICB0aGlzLm9ic2VydmVyLmRpc2Nvbm5lY3QoKTtcbiAgICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IEJ1dHRvbnNUb2dnbGVMaXN0ZW5lcjsiLCJjbGFzcyBQcm9kdWN0IHtcblxuICAgIGNvbnN0cnVjdG9yKGlkLCBxdWFudGl0eSwgdmFyaWF0aW9ucykge1xuICAgICAgICB0aGlzLmlkID0gaWQ7XG4gICAgICAgIHRoaXMucXVhbnRpdHkgPSBxdWFudGl0eTtcbiAgICAgICAgdGhpcy52YXJpYXRpb25zID0gdmFyaWF0aW9ucztcbiAgICB9XG5cbiAgICBkYXRhKCkge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgaWQ6dGhpcy5pZCxcbiAgICAgICAgICAgIHF1YW50aXR5OnRoaXMucXVhbnRpdHksXG4gICAgICAgICAgICB2YXJpYXRpb25zOnRoaXMudmFyaWF0aW9uc1xuICAgICAgICB9XG4gICAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBQcm9kdWN0OyIsImltcG9ydCBCdXR0b25zVG9nZ2xlTGlzdGVuZXIgZnJvbSAnLi4vSGVscGVyL0J1dHRvbnNUb2dnbGVMaXN0ZW5lcic7XG5pbXBvcnQgUHJvZHVjdCBmcm9tICcuLi9FbnRpdHkvUHJvZHVjdCc7XG5pbXBvcnQgb25BcHByb3ZlIGZyb20gJy4uL09uQXBwcm92ZUhhbmRsZXIvb25BcHByb3ZlRm9yQ29udGludWUnO1xuaW1wb3J0IHtwYXllckRhdGF9IGZyb20gXCIuLi9IZWxwZXIvUGF5ZXJEYXRhXCI7XG5cbmNsYXNzIFNpbmdsZVByb2R1Y3RBY3Rpb25IYW5kbGVyIHtcblxuICAgIGNvbnN0cnVjdG9yKFxuICAgICAgICBjb25maWcsXG4gICAgICAgIHVwZGF0ZUNhcnQsXG4gICAgICAgIHNob3dCdXR0b25DYWxsYmFjayxcbiAgICAgICAgaGlkZUJ1dHRvbkNhbGxiYWNrLFxuICAgICAgICBmb3JtRWxlbWVudCxcbiAgICAgICAgZXJyb3JIYW5kbGVyXG4gICAgKSB7XG4gICAgICAgIHRoaXMuY29uZmlnID0gY29uZmlnO1xuICAgICAgICB0aGlzLnVwZGF0ZUNhcnQgPSB1cGRhdGVDYXJ0O1xuICAgICAgICB0aGlzLnNob3dCdXR0b25DYWxsYmFjayA9IHNob3dCdXR0b25DYWxsYmFjaztcbiAgICAgICAgdGhpcy5oaWRlQnV0dG9uQ2FsbGJhY2sgPSBoaWRlQnV0dG9uQ2FsbGJhY2s7XG4gICAgICAgIHRoaXMuZm9ybUVsZW1lbnQgPSBmb3JtRWxlbWVudDtcbiAgICAgICAgdGhpcy5lcnJvckhhbmRsZXIgPSBlcnJvckhhbmRsZXI7XG4gICAgfVxuXG4gICAgY29uZmlndXJhdGlvbigpXG4gICAge1xuXG4gICAgICAgIGlmICggdGhpcy5oYXNWYXJpYXRpb25zKCkgKSB7XG4gICAgICAgICAgICBjb25zdCBvYnNlcnZlciA9IG5ldyBCdXR0b25zVG9nZ2xlTGlzdGVuZXIoXG4gICAgICAgICAgICAgICAgdGhpcy5mb3JtRWxlbWVudC5xdWVyeVNlbGVjdG9yKCcuc2luZ2xlX2FkZF90b19jYXJ0X2J1dHRvbicpLFxuICAgICAgICAgICAgICAgIHRoaXMuc2hvd0J1dHRvbkNhbGxiYWNrLFxuICAgICAgICAgICAgICAgIHRoaXMuaGlkZUJ1dHRvbkNhbGxiYWNrXG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgb2JzZXJ2ZXIuaW5pdCgpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGNyZWF0ZU9yZGVyOiB0aGlzLmNyZWF0ZU9yZGVyKCksXG4gICAgICAgICAgICBvbkFwcHJvdmU6IG9uQXBwcm92ZSh0aGlzLCB0aGlzLmVycm9ySGFuZGxlciksXG4gICAgICAgICAgICBvbkVycm9yOiAoZXJyb3IpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLmVycm9ySGFuZGxlci5nZW5lcmljRXJyb3IoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIGNyZWF0ZU9yZGVyKClcbiAgICB7XG4gICAgICAgIHZhciBnZXRQcm9kdWN0cyA9IG51bGw7XG4gICAgICAgIGlmICghIHRoaXMuaXNHcm91cGVkUHJvZHVjdCgpICkge1xuICAgICAgICAgICAgZ2V0UHJvZHVjdHMgPSAoKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgaWQgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCdbbmFtZT1cImFkZC10by1jYXJ0XCJdJykudmFsdWU7XG4gICAgICAgICAgICAgICAgY29uc3QgcXR5ID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignW25hbWU9XCJxdWFudGl0eVwiXScpLnZhbHVlO1xuICAgICAgICAgICAgICAgIGNvbnN0IHZhcmlhdGlvbnMgPSB0aGlzLnZhcmlhdGlvbnMoKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gW25ldyBQcm9kdWN0KGlkLCBxdHksIHZhcmlhdGlvbnMpXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGdldFByb2R1Y3RzID0gKCkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IHByb2R1Y3RzID0gW107XG4gICAgICAgICAgICAgICAgdGhpcy5mb3JtRWxlbWVudC5xdWVyeVNlbGVjdG9yQWxsKCdpbnB1dFt0eXBlPVwibnVtYmVyXCJdJykuZm9yRWFjaCgoZWxlbWVudCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAoISBlbGVtZW50LnZhbHVlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgY29uc3QgZWxlbWVudE5hbWUgPSBlbGVtZW50LmdldEF0dHJpYnV0ZSgnbmFtZScpLm1hdGNoKC9xdWFudGl0eVxcWyhbXFxkXSopXFxdLyk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChlbGVtZW50TmFtZS5sZW5ndGggIT09IDIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBjb25zdCBpZCA9IHBhcnNlSW50KGVsZW1lbnROYW1lWzFdKTtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgcXVhbnRpdHkgPSBwYXJzZUludChlbGVtZW50LnZhbHVlKTtcbiAgICAgICAgICAgICAgICAgICAgcHJvZHVjdHMucHVzaChuZXcgUHJvZHVjdChpZCwgcXVhbnRpdHksIG51bGwpKTtcbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgIHJldHVybiBwcm9kdWN0cztcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBjb25zdCBjcmVhdGVPcmRlciA9IChkYXRhLCBhY3Rpb25zKSA9PiB7XG4gICAgICAgICAgICB0aGlzLmVycm9ySGFuZGxlci5jbGVhcigpO1xuXG4gICAgICAgICAgICBjb25zdCBvblJlc29sdmUgPSAocHVyY2hhc2VfdW5pdHMpID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCBwYXllciA9IHBheWVyRGF0YSgpO1xuICAgICAgICAgICAgICAgIGNvbnN0IGJuQ29kZSA9IHR5cGVvZiB0aGlzLmNvbmZpZy5ibl9jb2Rlc1t0aGlzLmNvbmZpZy5jb250ZXh0XSAhPT0gJ3VuZGVmaW5lZCcgP1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmNvbmZpZy5ibl9jb2Rlc1t0aGlzLmNvbmZpZy5jb250ZXh0XSA6ICcnO1xuICAgICAgICAgICAgICAgIHJldHVybiBmZXRjaCh0aGlzLmNvbmZpZy5hamF4LmNyZWF0ZV9vcmRlci5lbmRwb2ludCwge1xuICAgICAgICAgICAgICAgICAgICBtZXRob2Q6ICdQT1NUJyxcbiAgICAgICAgICAgICAgICAgICAgYm9keTogSlNPTi5zdHJpbmdpZnkoe1xuICAgICAgICAgICAgICAgICAgICAgICAgbm9uY2U6IHRoaXMuY29uZmlnLmFqYXguY3JlYXRlX29yZGVyLm5vbmNlLFxuICAgICAgICAgICAgICAgICAgICAgICAgcHVyY2hhc2VfdW5pdHMsXG4gICAgICAgICAgICAgICAgICAgICAgICBwYXllcixcbiAgICAgICAgICAgICAgICAgICAgICAgIGJuX2NvZGU6Ym5Db2RlLFxuICAgICAgICAgICAgICAgICAgICAgICAgY29udGV4dDp0aGlzLmNvbmZpZy5jb250ZXh0XG4gICAgICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgfSkudGhlbihmdW5jdGlvbiAocmVzKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiByZXMuanNvbigpO1xuICAgICAgICAgICAgICAgIH0pLnRoZW4oZnVuY3Rpb24gKGRhdGEpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFkYXRhLnN1Y2Nlc3MpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZGF0YSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBFcnJvcihkYXRhLmRhdGEubWVzc2FnZSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGRhdGEuZGF0YS5pZDtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIGNvbnN0IHByb21pc2UgPSB0aGlzLnVwZGF0ZUNhcnQudXBkYXRlKG9uUmVzb2x2ZSwgZ2V0UHJvZHVjdHMoKSk7XG4gICAgICAgICAgICByZXR1cm4gcHJvbWlzZTtcbiAgICAgICAgfTtcbiAgICAgICAgcmV0dXJuIGNyZWF0ZU9yZGVyO1xuICAgIH1cblxuICAgIHZhcmlhdGlvbnMoKVxuICAgIHtcblxuICAgICAgICBpZiAoISB0aGlzLmhhc1ZhcmlhdGlvbnMoKSkge1xuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgYXR0cmlidXRlcyA9IFsuLi50aGlzLmZvcm1FbGVtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoXCJbbmFtZV49J2F0dHJpYnV0ZV8nXVwiKV0ubWFwKFxuICAgICAgICAgICAgKGVsZW1lbnQpID0+IHtcbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgICAgIHZhbHVlOmVsZW1lbnQudmFsdWUsXG4gICAgICAgICAgICAgICAgICAgIG5hbWU6ZWxlbWVudC5uYW1lXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICApO1xuICAgICAgICByZXR1cm4gYXR0cmlidXRlcztcbiAgICB9XG5cbiAgICBoYXNWYXJpYXRpb25zKClcbiAgICB7XG4gICAgICAgIHJldHVybiB0aGlzLmZvcm1FbGVtZW50LmNsYXNzTGlzdC5jb250YWlucygndmFyaWF0aW9uc19mb3JtJyk7XG4gICAgfVxuXG4gICAgaXNHcm91cGVkUHJvZHVjdCgpXG4gICAge1xuICAgICAgICByZXR1cm4gdGhpcy5mb3JtRWxlbWVudC5jbGFzc0xpc3QuY29udGFpbnMoJ2dyb3VwZWRfZm9ybScpO1xuICAgIH1cbn1cbmV4cG9ydCBkZWZhdWx0IFNpbmdsZVByb2R1Y3RBY3Rpb25IYW5kbGVyO1xuIiwiaW1wb3J0IEVycm9ySGFuZGxlciBmcm9tICcuLi9FcnJvckhhbmRsZXInO1xuaW1wb3J0IFVwZGF0ZUNhcnQgZnJvbSBcIi4uL0hlbHBlci9VcGRhdGVDYXJ0XCI7XG5pbXBvcnQgU2luZ2xlUHJvZHVjdEFjdGlvbkhhbmRsZXIgZnJvbSBcIi4uL0FjdGlvbkhhbmRsZXIvU2luZ2xlUHJvZHVjdEFjdGlvbkhhbmRsZXJcIjtcblxuY2xhc3MgU2luZ2xlUHJvZHVjdEJvb3RzdGFwIHtcbiAgICBjb25zdHJ1Y3RvcihnYXRld2F5LCByZW5kZXJlciwgbWVzc2FnZXMpIHtcbiAgICAgICAgdGhpcy5nYXRld2F5ID0gZ2F0ZXdheTtcbiAgICAgICAgdGhpcy5yZW5kZXJlciA9IHJlbmRlcmVyO1xuICAgICAgICB0aGlzLm1lc3NhZ2VzID0gbWVzc2FnZXM7XG4gICAgfVxuXG4gICAgaW5pdCgpIHtcbiAgICAgICAgaWYgKCF0aGlzLnNob3VsZFJlbmRlcigpKSB7XG4gICAgICAgICAgIHRoaXMucmVuZGVyZXIuaGlkZUJ1dHRvbnModGhpcy5nYXRld2F5Lmhvc3RlZF9maWVsZHMud3JhcHBlcik7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLnJlbmRlcigpO1xuICAgIH1cblxuICAgIHNob3VsZFJlbmRlcigpIHtcbiAgICAgICAgaWYgKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJ2Zvcm0uY2FydCcpID09PSBudWxsKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG5cbiAgICByZW5kZXIoKSB7XG4gICAgICAgIGNvbnN0IGFjdGlvbkhhbmRsZXIgPSBuZXcgU2luZ2xlUHJvZHVjdEFjdGlvbkhhbmRsZXIoXG4gICAgICAgICAgICB0aGlzLmdhdGV3YXksXG4gICAgICAgICAgICBuZXcgVXBkYXRlQ2FydChcbiAgICAgICAgICAgICAgICB0aGlzLmdhdGV3YXkuYWpheC5jaGFuZ2VfY2FydC5lbmRwb2ludCxcbiAgICAgICAgICAgICAgICB0aGlzLmdhdGV3YXkuYWpheC5jaGFuZ2VfY2FydC5ub25jZSxcbiAgICAgICAgICAgICksXG4gICAgICAgICAgICAoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5yZW5kZXJlci5zaG93QnV0dG9ucyh0aGlzLmdhdGV3YXkuYnV0dG9uLndyYXBwZXIpO1xuICAgICAgICAgICAgICAgIHRoaXMucmVuZGVyZXIuc2hvd0J1dHRvbnModGhpcy5nYXRld2F5Lmhvc3RlZF9maWVsZHMud3JhcHBlcik7XG4gICAgICAgICAgICAgICAgbGV0IHByaWNlVGV4dCA9IFwiMFwiO1xuICAgICAgICAgICAgICAgIGlmIChkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCdmb3JtLmNhcnQgaW5zIC53b29jb21tZXJjZS1QcmljZS1hbW91bnQnKSkge1xuICAgICAgICAgICAgICAgICAgICBwcmljZVRleHQgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCdmb3JtLmNhcnQgaW5zIC53b29jb21tZXJjZS1QcmljZS1hbW91bnQnKS5pbm5lclRleHQ7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2UgaWYgKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJ2Zvcm0uY2FydCAud29vY29tbWVyY2UtUHJpY2UtYW1vdW50JykpIHtcbiAgICAgICAgICAgICAgICAgICAgcHJpY2VUZXh0ID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignZm9ybS5jYXJ0IC53b29jb21tZXJjZS1QcmljZS1hbW91bnQnKS5pbm5lclRleHQ7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGNvbnN0IGFtb3VudCA9IHBhcnNlSW50KHByaWNlVGV4dC5yZXBsYWNlKC8oW15cXGQsXFwuXFxzXSopL2csICcnKSk7XG4gICAgICAgICAgICAgICAgdGhpcy5tZXNzYWdlcy5yZW5kZXJXaXRoQW1vdW50KGFtb3VudClcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5yZW5kZXJlci5oaWRlQnV0dG9ucyh0aGlzLmdhdGV3YXkuYnV0dG9uLndyYXBwZXIpO1xuICAgICAgICAgICAgICAgIHRoaXMucmVuZGVyZXIuaGlkZUJ1dHRvbnModGhpcy5nYXRld2F5Lmhvc3RlZF9maWVsZHMud3JhcHBlcik7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZG9jdW1lbnQucXVlcnlTZWxlY3RvcignZm9ybS5jYXJ0JyksXG4gICAgICAgICAgICBuZXcgRXJyb3JIYW5kbGVyKHRoaXMuZ2F0ZXdheS5sYWJlbHMuZXJyb3IuZ2VuZXJpYyksXG4gICAgICAgICk7XG5cbiAgICAgICAgdGhpcy5yZW5kZXJlci5yZW5kZXIoXG4gICAgICAgICAgICB0aGlzLmdhdGV3YXkuYnV0dG9uLndyYXBwZXIsXG4gICAgICAgICAgICB0aGlzLmdhdGV3YXkuaG9zdGVkX2ZpZWxkcy53cmFwcGVyLFxuICAgICAgICAgICAgYWN0aW9uSGFuZGxlci5jb25maWd1cmF0aW9uKCksXG4gICAgICAgICk7XG4gICAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBTaW5nbGVQcm9kdWN0Qm9vdHN0YXA7IiwiaW1wb3J0IENhcnRBY3Rpb25IYW5kbGVyIGZyb20gJy4uL0FjdGlvbkhhbmRsZXIvQ2FydEFjdGlvbkhhbmRsZXInO1xuaW1wb3J0IEVycm9ySGFuZGxlciBmcm9tICcuLi9FcnJvckhhbmRsZXInO1xuXG5jbGFzcyBDYXJ0Qm9vdHN0cmFwIHtcbiAgICBjb25zdHJ1Y3RvcihnYXRld2F5LCByZW5kZXJlcikge1xuICAgICAgICB0aGlzLmdhdGV3YXkgPSBnYXRld2F5O1xuICAgICAgICB0aGlzLnJlbmRlcmVyID0gcmVuZGVyZXI7XG4gICAgfVxuXG4gICAgaW5pdCgpIHtcbiAgICAgICAgaWYgKCF0aGlzLnNob3VsZFJlbmRlcigpKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLnJlbmRlcigpO1xuXG4gICAgICAgIGpRdWVyeShkb2N1bWVudC5ib2R5KS5vbigndXBkYXRlZF9jYXJ0X3RvdGFscyB1cGRhdGVkX2NoZWNrb3V0JywgKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5yZW5kZXIoKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgc2hvdWxkUmVuZGVyKCkge1xuICAgICAgICByZXR1cm4gZG9jdW1lbnQucXVlcnlTZWxlY3Rvcih0aGlzLmdhdGV3YXkuYnV0dG9uLndyYXBwZXIpICE9PVxuICAgICAgICAgICAgbnVsbCB8fCBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKHRoaXMuZ2F0ZXdheS5ob3N0ZWRfZmllbGRzLndyYXBwZXIpICE9PVxuICAgICAgICAgICAgbnVsbDtcbiAgICB9XG5cbiAgICByZW5kZXIoKSB7XG4gICAgICAgIGNvbnN0IGFjdGlvbkhhbmRsZXIgPSBuZXcgQ2FydEFjdGlvbkhhbmRsZXIoXG4gICAgICAgICAgICBQYXlQYWxDb21tZXJjZUdhdGV3YXksXG4gICAgICAgICAgICBuZXcgRXJyb3JIYW5kbGVyKHRoaXMuZ2F0ZXdheS5sYWJlbHMuZXJyb3IuZ2VuZXJpYyksXG4gICAgICAgICk7XG5cbiAgICAgICAgdGhpcy5yZW5kZXJlci5yZW5kZXIoXG4gICAgICAgICAgICB0aGlzLmdhdGV3YXkuYnV0dG9uLndyYXBwZXIsXG4gICAgICAgICAgICB0aGlzLmdhdGV3YXkuaG9zdGVkX2ZpZWxkcy53cmFwcGVyLFxuICAgICAgICAgICAgYWN0aW9uSGFuZGxlci5jb25maWd1cmF0aW9uKCksXG4gICAgICAgICk7XG4gICAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBDYXJ0Qm9vdHN0cmFwO1xuIiwiY29uc3Qgb25BcHByb3ZlID0gKGNvbnRleHQsIGVycm9ySGFuZGxlciwgc3Bpbm5lcikgPT4ge1xuICAgIHJldHVybiAoZGF0YSwgYWN0aW9ucykgPT4ge1xuICAgICAgICBzcGlubmVyLmJsb2NrKCk7XG4gICAgICAgIHJldHVybiBmZXRjaChjb250ZXh0LmNvbmZpZy5hamF4LmFwcHJvdmVfb3JkZXIuZW5kcG9pbnQsIHtcbiAgICAgICAgICAgIG1ldGhvZDogJ1BPU1QnLFxuICAgICAgICAgICAgYm9keTogSlNPTi5zdHJpbmdpZnkoe1xuICAgICAgICAgICAgICAgIG5vbmNlOiBjb250ZXh0LmNvbmZpZy5hamF4LmFwcHJvdmVfb3JkZXIubm9uY2UsXG4gICAgICAgICAgICAgICAgb3JkZXJfaWQ6ZGF0YS5vcmRlcklEXG4gICAgICAgICAgICB9KVxuICAgICAgICB9KS50aGVuKChyZXMpPT57XG4gICAgICAgICAgICByZXR1cm4gcmVzLmpzb24oKTtcbiAgICAgICAgfSkudGhlbigoZGF0YSk9PntcbiAgICAgICAgICAgIHNwaW5uZXIudW5ibG9jaygpO1xuICAgICAgICAgICAgaWYgKCFkYXRhLnN1Y2Nlc3MpIHtcbiAgICAgICAgICAgICAgICBpZiAoZGF0YS5kYXRhLmNvZGUgPT09IDEwMCkge1xuICAgICAgICAgICAgICAgICAgICBlcnJvckhhbmRsZXIubWVzc2FnZShkYXRhLmRhdGEubWVzc2FnZSk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgZXJyb3JIYW5kbGVyLmdlbmVyaWNFcnJvcigpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIGFjdGlvbnMgIT09ICd1bmRlZmluZWQnICYmIHR5cGVvZiBhY3Rpb25zLnJlc3RhcnQgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBhY3Rpb25zLnJlc3RhcnQoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGRhdGEuZGF0YS5tZXNzYWdlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNwbGFjZV9vcmRlcicpLmNsaWNrKClcbiAgICAgICAgfSk7XG5cbiAgICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IG9uQXBwcm92ZTtcbiIsImltcG9ydCBvbkFwcHJvdmUgZnJvbSAnLi4vT25BcHByb3ZlSGFuZGxlci9vbkFwcHJvdmVGb3JQYXlOb3cuanMnO1xuaW1wb3J0IHtwYXllckRhdGF9IGZyb20gXCIuLi9IZWxwZXIvUGF5ZXJEYXRhXCI7XG5cbmNsYXNzIENoZWNrb3V0QWN0aW9uSGFuZGxlciB7XG5cbiAgICBjb25zdHJ1Y3Rvcihjb25maWcsIGVycm9ySGFuZGxlciwgc3Bpbm5lcikge1xuICAgICAgICB0aGlzLmNvbmZpZyA9IGNvbmZpZztcbiAgICAgICAgdGhpcy5lcnJvckhhbmRsZXIgPSBlcnJvckhhbmRsZXI7XG4gICAgICAgIHRoaXMuc3Bpbm5lciA9IHNwaW5uZXI7XG4gICAgfVxuXG4gICAgY29uZmlndXJhdGlvbigpIHtcbiAgICAgICAgY29uc3Qgc3Bpbm5lciA9IHRoaXMuc3Bpbm5lcjtcbiAgICAgICAgY29uc3QgY3JlYXRlT3JkZXIgPSAoZGF0YSwgYWN0aW9ucykgPT4ge1xuICAgICAgICAgICAgY29uc3QgcGF5ZXIgPSBwYXllckRhdGEoKTtcbiAgICAgICAgICAgIGNvbnN0IGJuQ29kZSA9IHR5cGVvZiB0aGlzLmNvbmZpZy5ibl9jb2Rlc1t0aGlzLmNvbmZpZy5jb250ZXh0XSAhPT0gJ3VuZGVmaW5lZCcgP1xuICAgICAgICAgICAgICAgIHRoaXMuY29uZmlnLmJuX2NvZGVzW3RoaXMuY29uZmlnLmNvbnRleHRdIDogJyc7XG5cbiAgICAgICAgICAgIGNvbnN0IGVycm9ySGFuZGxlciA9IHRoaXMuZXJyb3JIYW5kbGVyO1xuXG4gICAgICAgICAgICBjb25zdCBmb3JtU2VsZWN0b3IgPSB0aGlzLmNvbmZpZy5jb250ZXh0ID09PSAnY2hlY2tvdXQnID8gJ2Zvcm0uY2hlY2tvdXQnIDogJ2Zvcm0jb3JkZXJfcmV2aWV3JztcbiAgICAgICAgICAgIGNvbnN0IGZvcm1WYWx1ZXMgPSBqUXVlcnkoZm9ybVNlbGVjdG9yKS5zZXJpYWxpemUoKTtcblxuICAgICAgICAgICAgY29uc3QgY3JlYXRlYWNjb3VudCA9IGpRdWVyeSgnI2NyZWF0ZWFjY291bnQnKS5pcyhcIjpjaGVja2VkXCIpID8gdHJ1ZSA6IGZhbHNlO1xuXG4gICAgICAgICAgICByZXR1cm4gZmV0Y2godGhpcy5jb25maWcuYWpheC5jcmVhdGVfb3JkZXIuZW5kcG9pbnQsIHtcbiAgICAgICAgICAgICAgICBtZXRob2Q6ICdQT1NUJyxcbiAgICAgICAgICAgICAgICBib2R5OiBKU09OLnN0cmluZ2lmeSh7XG4gICAgICAgICAgICAgICAgICAgIG5vbmNlOiB0aGlzLmNvbmZpZy5hamF4LmNyZWF0ZV9vcmRlci5ub25jZSxcbiAgICAgICAgICAgICAgICAgICAgcGF5ZXIsXG4gICAgICAgICAgICAgICAgICAgIGJuX2NvZGU6Ym5Db2RlLFxuICAgICAgICAgICAgICAgICAgICBjb250ZXh0OnRoaXMuY29uZmlnLmNvbnRleHQsXG4gICAgICAgICAgICAgICAgICAgIG9yZGVyX2lkOnRoaXMuY29uZmlnLm9yZGVyX2lkLFxuICAgICAgICAgICAgICAgICAgICBmb3JtOmZvcm1WYWx1ZXMsXG4gICAgICAgICAgICAgICAgICAgIGNyZWF0ZWFjY291bnQ6IGNyZWF0ZWFjY291bnRcbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgfSkudGhlbihmdW5jdGlvbiAocmVzKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHJlcy5qc29uKCk7XG4gICAgICAgICAgICB9KS50aGVuKGZ1bmN0aW9uIChkYXRhKSB7XG4gICAgICAgICAgICAgICAgaWYgKCFkYXRhLnN1Y2Nlc3MpIHtcbiAgICAgICAgICAgICAgICAgICAgc3Bpbm5lci51bmJsb2NrKCk7XG4gICAgICAgICAgICAgICAgICAgIC8vaGFuZGxlIGJvdGggbWVzc2FnZXMgc2VudCBmcm9tIFdvb2NvbW1lcmNlIChkYXRhLm1lc3NhZ2VzKSBhbmQgdGhpcyBwbHVnaW4gKGRhdGEuZGF0YS5tZXNzYWdlKVxuICAgICAgICAgICAgICAgICAgICBpZiAodHlwZW9mKGRhdGEubWVzc2FnZXMpICE9PSAndW5kZWZpbmVkJyApXG4gICAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGRvbVBhcnNlciA9IG5ldyBET01QYXJzZXIoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGVycm9ySGFuZGxlci5hcHBlbmRQcmVwYXJlZEVycm9yTWVzc2FnZUVsZW1lbnQoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZG9tUGFyc2VyLnBhcnNlRnJvbVN0cmluZyhkYXRhLm1lc3NhZ2VzLCAndGV4dC9odG1sJylcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLnF1ZXJ5U2VsZWN0b3IoJ3VsJylcbiAgICAgICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBlcnJvckhhbmRsZXIubWVzc2FnZShkYXRhLmRhdGEubWVzc2FnZSwgdHJ1ZSk7XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGNvbnN0IGlucHV0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnaW5wdXQnKTtcbiAgICAgICAgICAgICAgICBpbnB1dC5zZXRBdHRyaWJ1dGUoJ3R5cGUnLCAnaGlkZGVuJyk7XG4gICAgICAgICAgICAgICAgaW5wdXQuc2V0QXR0cmlidXRlKCduYW1lJywgJ3BwY3AtcmVzdW1lLW9yZGVyJyk7XG4gICAgICAgICAgICAgICAgaW5wdXQuc2V0QXR0cmlidXRlKCd2YWx1ZScsIGRhdGEuZGF0YS5wdXJjaGFzZV91bml0c1swXS5jdXN0b21faWQpO1xuICAgICAgICAgICAgICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoZm9ybVNlbGVjdG9yKS5hcHBlbmQoaW5wdXQpO1xuICAgICAgICAgICAgICAgIHJldHVybiBkYXRhLmRhdGEuaWQ7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgY3JlYXRlT3JkZXIsXG4gICAgICAgICAgICBvbkFwcHJvdmU6b25BcHByb3ZlKHRoaXMsIHRoaXMuZXJyb3JIYW5kbGVyLCB0aGlzLnNwaW5uZXIpLFxuICAgICAgICAgICAgb25DYW5jZWw6ICgpID0+IHtcbiAgICAgICAgICAgICAgICBzcGlubmVyLnVuYmxvY2soKTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBvbkVycm9yOiAoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5lcnJvckhhbmRsZXIuZ2VuZXJpY0Vycm9yKCk7XG4gICAgICAgICAgICAgICAgc3Bpbm5lci51bmJsb2NrKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IENoZWNrb3V0QWN0aW9uSGFuZGxlcjtcbiIsImltcG9ydCBFcnJvckhhbmRsZXIgZnJvbSAnLi4vRXJyb3JIYW5kbGVyJztcbmltcG9ydCBDaGVja291dEFjdGlvbkhhbmRsZXIgZnJvbSAnLi4vQWN0aW9uSGFuZGxlci9DaGVja291dEFjdGlvbkhhbmRsZXInO1xuXG5jbGFzcyBDaGVja291dEJvb3RzdGFwIHtcbiAgICBjb25zdHJ1Y3RvcihnYXRld2F5LCByZW5kZXJlciwgbWVzc2FnZXMsIHNwaW5uZXIpIHtcbiAgICAgICAgdGhpcy5nYXRld2F5ID0gZ2F0ZXdheTtcbiAgICAgICAgdGhpcy5yZW5kZXJlciA9IHJlbmRlcmVyO1xuICAgICAgICB0aGlzLm1lc3NhZ2VzID0gbWVzc2FnZXM7XG4gICAgICAgIHRoaXMuc3Bpbm5lciA9IHNwaW5uZXI7XG4gICAgfVxuXG4gICAgaW5pdCgpIHtcblxuICAgICAgICB0aGlzLnJlbmRlcigpO1xuXG4gICAgICAgIGpRdWVyeShkb2N1bWVudC5ib2R5KS5vbigndXBkYXRlZF9jaGVja291dCcsICgpID0+IHtcbiAgICAgICAgICAgIHRoaXMucmVuZGVyKClcbiAgICAgICAgfSk7XG5cbiAgICAgICAgalF1ZXJ5KGRvY3VtZW50LmJvZHkpLlxuICAgICAgICAgIG9uKCd1cGRhdGVkX2NoZWNrb3V0IHBheW1lbnRfbWV0aG9kX3NlbGVjdGVkJywgKCkgPT4ge1xuICAgICAgICAgICAgICB0aGlzLnN3aXRjaEJldHdlZW5QYXlQYWxhbmRPcmRlckJ1dHRvbigpXG4gICAgICAgICAgICAgIHRoaXMuZGlzcGxheVBsYWNlT3JkZXJCdXR0b25Gb3JTYXZlZENyZWRpdENhcmRzKClcblxuICAgICAgICAgIH0pXG5cbiAgICAgICAgalF1ZXJ5KGRvY3VtZW50KS5vbignaG9zdGVkX2ZpZWxkc19sb2FkZWQnLCAoKSA9PiB7XG4gICAgICAgICAgICBqUXVlcnkoJyNzYXZlZC1jcmVkaXQtY2FyZCcpLm9uKCdjaGFuZ2UnLCAoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5kaXNwbGF5UGxhY2VPcmRlckJ1dHRvbkZvclNhdmVkQ3JlZGl0Q2FyZHMoKVxuICAgICAgICAgICAgfSlcbiAgICAgICAgfSk7XG5cbiAgICAgICAgdGhpcy5zd2l0Y2hCZXR3ZWVuUGF5UGFsYW5kT3JkZXJCdXR0b24oKVxuICAgICAgICB0aGlzLmRpc3BsYXlQbGFjZU9yZGVyQnV0dG9uRm9yU2F2ZWRDcmVkaXRDYXJkcygpXG4gICAgfVxuXG4gICAgc2hvdWxkUmVuZGVyKCkge1xuICAgICAgICBpZiAoZG9jdW1lbnQucXVlcnlTZWxlY3Rvcih0aGlzLmdhdGV3YXkuYnV0dG9uLmNhbmNlbF93cmFwcGVyKSkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IodGhpcy5nYXRld2F5LmJ1dHRvbi53cmFwcGVyKSAhPT0gbnVsbCB8fCBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKHRoaXMuZ2F0ZXdheS5ob3N0ZWRfZmllbGRzLndyYXBwZXIpICE9PSBudWxsO1xuICAgIH1cblxuICAgIHJlbmRlcigpIHtcbiAgICAgICAgaWYgKCF0aGlzLnNob3VsZFJlbmRlcigpKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IodGhpcy5nYXRld2F5Lmhvc3RlZF9maWVsZHMud3JhcHBlciArICc+ZGl2JykpIHtcbiAgICAgICAgICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IodGhpcy5nYXRld2F5Lmhvc3RlZF9maWVsZHMud3JhcHBlciArICc+ZGl2Jykuc2V0QXR0cmlidXRlKCdzdHlsZScsICcnKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBhY3Rpb25IYW5kbGVyID0gbmV3IENoZWNrb3V0QWN0aW9uSGFuZGxlcihcbiAgICAgICAgICAgIFBheVBhbENvbW1lcmNlR2F0ZXdheSxcbiAgICAgICAgICAgIG5ldyBFcnJvckhhbmRsZXIodGhpcy5nYXRld2F5LmxhYmVscy5lcnJvci5nZW5lcmljKSxcbiAgICAgICAgICAgIHRoaXMuc3Bpbm5lclxuICAgICAgICApO1xuXG4gICAgICAgIHRoaXMucmVuZGVyZXIucmVuZGVyKFxuICAgICAgICAgICAgdGhpcy5nYXRld2F5LmJ1dHRvbi53cmFwcGVyLFxuICAgICAgICAgICAgdGhpcy5nYXRld2F5Lmhvc3RlZF9maWVsZHMud3JhcHBlcixcbiAgICAgICAgICAgIGFjdGlvbkhhbmRsZXIuY29uZmlndXJhdGlvbigpLFxuICAgICAgICApO1xuICAgIH1cblxuICAgIHN3aXRjaEJldHdlZW5QYXlQYWxhbmRPcmRlckJ1dHRvbigpIHtcbiAgICAgICAgalF1ZXJ5KCcjc2F2ZWQtY3JlZGl0LWNhcmQnKS52YWwoalF1ZXJ5KCcjc2F2ZWQtY3JlZGl0LWNhcmQgb3B0aW9uOmZpcnN0JykudmFsKCkpO1xuXG4gICAgICAgIGNvbnN0IGN1cnJlbnRQYXltZW50TWV0aG9kID0galF1ZXJ5KFxuICAgICAgICAgICAgJ2lucHV0W25hbWU9XCJwYXltZW50X21ldGhvZFwiXTpjaGVja2VkJykudmFsKCk7XG5cbiAgICAgICAgaWYgKGN1cnJlbnRQYXltZW50TWV0aG9kICE9PSAncHBjcC1nYXRld2F5JyAmJiBjdXJyZW50UGF5bWVudE1ldGhvZCAhPT0gJ3BwY3AtY3JlZGl0LWNhcmQtZ2F0ZXdheScpIHtcbiAgICAgICAgICAgIHRoaXMucmVuZGVyZXIuaGlkZUJ1dHRvbnModGhpcy5nYXRld2F5LmJ1dHRvbi53cmFwcGVyKTtcbiAgICAgICAgICAgIHRoaXMucmVuZGVyZXIuaGlkZUJ1dHRvbnModGhpcy5nYXRld2F5Lm1lc3NhZ2VzLndyYXBwZXIpO1xuICAgICAgICAgICAgdGhpcy5yZW5kZXJlci5oaWRlQnV0dG9ucyh0aGlzLmdhdGV3YXkuaG9zdGVkX2ZpZWxkcy53cmFwcGVyKTtcbiAgICAgICAgICAgIGpRdWVyeSgnI3BsYWNlX29yZGVyJykuc2hvdygpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgalF1ZXJ5KCcjcGxhY2Vfb3JkZXInKS5oaWRlKCk7XG4gICAgICAgICAgICBpZiAoY3VycmVudFBheW1lbnRNZXRob2QgPT09ICdwcGNwLWdhdGV3YXknKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5yZW5kZXJlci5zaG93QnV0dG9ucyh0aGlzLmdhdGV3YXkuYnV0dG9uLndyYXBwZXIpO1xuICAgICAgICAgICAgICAgIHRoaXMucmVuZGVyZXIuc2hvd0J1dHRvbnModGhpcy5nYXRld2F5Lm1lc3NhZ2VzLndyYXBwZXIpO1xuICAgICAgICAgICAgICAgIHRoaXMubWVzc2FnZXMucmVuZGVyKClcbiAgICAgICAgICAgICAgICB0aGlzLnJlbmRlcmVyLmhpZGVCdXR0b25zKHRoaXMuZ2F0ZXdheS5ob3N0ZWRfZmllbGRzLndyYXBwZXIpXG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoY3VycmVudFBheW1lbnRNZXRob2QgPT09ICdwcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXknKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5yZW5kZXJlci5oaWRlQnV0dG9ucyh0aGlzLmdhdGV3YXkuYnV0dG9uLndyYXBwZXIpXG4gICAgICAgICAgICAgICAgdGhpcy5yZW5kZXJlci5oaWRlQnV0dG9ucyh0aGlzLmdhdGV3YXkubWVzc2FnZXMud3JhcHBlcilcbiAgICAgICAgICAgICAgICB0aGlzLnJlbmRlcmVyLnNob3dCdXR0b25zKHRoaXMuZ2F0ZXdheS5ob3N0ZWRfZmllbGRzLndyYXBwZXIpXG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBkaXNwbGF5UGxhY2VPcmRlckJ1dHRvbkZvclNhdmVkQ3JlZGl0Q2FyZHMoKSB7XG4gICAgICAgIGNvbnN0IGN1cnJlbnRQYXltZW50TWV0aG9kID0galF1ZXJ5KFxuICAgICAgICAgICdpbnB1dFtuYW1lPVwicGF5bWVudF9tZXRob2RcIl06Y2hlY2tlZCcpLnZhbCgpO1xuICAgICAgICBpZiAoY3VycmVudFBheW1lbnRNZXRob2QgIT09ICdwcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXknKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoalF1ZXJ5KCcjc2F2ZWQtY3JlZGl0LWNhcmQnKS5sZW5ndGggJiYgalF1ZXJ5KCcjc2F2ZWQtY3JlZGl0LWNhcmQnKS52YWwoKSAhPT0gJycpIHtcbiAgICAgICAgICAgIHRoaXMucmVuZGVyZXIuaGlkZUJ1dHRvbnModGhpcy5nYXRld2F5LmJ1dHRvbi53cmFwcGVyKVxuICAgICAgICAgICAgdGhpcy5yZW5kZXJlci5oaWRlQnV0dG9ucyh0aGlzLmdhdGV3YXkubWVzc2FnZXMud3JhcHBlcilcbiAgICAgICAgICAgIHRoaXMucmVuZGVyZXIuaGlkZUJ1dHRvbnModGhpcy5nYXRld2F5Lmhvc3RlZF9maWVsZHMud3JhcHBlcilcbiAgICAgICAgICAgIGpRdWVyeSgnI3BsYWNlX29yZGVyJykuc2hvdygpXG4gICAgICAgICAgICB0aGlzLmRpc2FibGVDcmVkaXRDYXJkRmllbGRzKClcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGpRdWVyeSgnI3BsYWNlX29yZGVyJykuaGlkZSgpXG4gICAgICAgICAgICB0aGlzLnJlbmRlcmVyLmhpZGVCdXR0b25zKHRoaXMuZ2F0ZXdheS5idXR0b24ud3JhcHBlcilcbiAgICAgICAgICAgIHRoaXMucmVuZGVyZXIuaGlkZUJ1dHRvbnModGhpcy5nYXRld2F5Lm1lc3NhZ2VzLndyYXBwZXIpXG4gICAgICAgICAgICB0aGlzLnJlbmRlcmVyLnNob3dCdXR0b25zKHRoaXMuZ2F0ZXdheS5ob3N0ZWRfZmllbGRzLndyYXBwZXIpXG4gICAgICAgICAgICB0aGlzLmVuYWJsZUNyZWRpdENhcmRGaWVsZHMoKVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgZGlzYWJsZUNyZWRpdENhcmRGaWVsZHMoKSB7XG4gICAgICAgIGpRdWVyeSgnbGFiZWxbZm9yPVwicHBjcC1jcmVkaXQtY2FyZC1nYXRld2F5LWNhcmQtbnVtYmVyXCJdJykuYWRkQ2xhc3MoJ3BwY3AtY3JlZGl0LWNhcmQtZ2F0ZXdheS1mb3JtLWZpZWxkLWRpc2FibGVkJylcbiAgICAgICAgalF1ZXJ5KCcjcHBjcC1jcmVkaXQtY2FyZC1nYXRld2F5LWNhcmQtbnVtYmVyJykuYWRkQ2xhc3MoJ3BwY3AtY3JlZGl0LWNhcmQtZ2F0ZXdheS1mb3JtLWZpZWxkLWRpc2FibGVkJylcbiAgICAgICAgalF1ZXJ5KCdsYWJlbFtmb3I9XCJwcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXktY2FyZC1leHBpcnlcIl0nKS5hZGRDbGFzcygncHBjcC1jcmVkaXQtY2FyZC1nYXRld2F5LWZvcm0tZmllbGQtZGlzYWJsZWQnKVxuICAgICAgICBqUXVlcnkoJyNwcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXktY2FyZC1leHBpcnknKS5hZGRDbGFzcygncHBjcC1jcmVkaXQtY2FyZC1nYXRld2F5LWZvcm0tZmllbGQtZGlzYWJsZWQnKVxuICAgICAgICBqUXVlcnkoJ2xhYmVsW2Zvcj1cInBwY3AtY3JlZGl0LWNhcmQtZ2F0ZXdheS1jYXJkLWN2Y1wiXScpLmFkZENsYXNzKCdwcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXktZm9ybS1maWVsZC1kaXNhYmxlZCcpXG4gICAgICAgIGpRdWVyeSgnI3BwY3AtY3JlZGl0LWNhcmQtZ2F0ZXdheS1jYXJkLWN2YycpLmFkZENsYXNzKCdwcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXktZm9ybS1maWVsZC1kaXNhYmxlZCcpXG4gICAgICAgIGpRdWVyeSgnbGFiZWxbZm9yPVwidmF1bHRcIl0nKS5hZGRDbGFzcygncHBjcC1jcmVkaXQtY2FyZC1nYXRld2F5LWZvcm0tZmllbGQtZGlzYWJsZWQnKVxuICAgICAgICBqUXVlcnkoJyNwcGNwLWNyZWRpdC1jYXJkLXZhdWx0JykuYWRkQ2xhc3MoJ3BwY3AtY3JlZGl0LWNhcmQtZ2F0ZXdheS1mb3JtLWZpZWxkLWRpc2FibGVkJylcbiAgICAgICAgalF1ZXJ5KCcjcHBjcC1jcmVkaXQtY2FyZC12YXVsdCcpLmF0dHIoXCJkaXNhYmxlZFwiLCB0cnVlKVxuICAgICAgICB0aGlzLnJlbmRlcmVyLmRpc2FibGVDcmVkaXRDYXJkRmllbGRzKClcbiAgICB9XG5cbiAgICBlbmFibGVDcmVkaXRDYXJkRmllbGRzKCkge1xuICAgICAgICBqUXVlcnkoJ2xhYmVsW2Zvcj1cInBwY3AtY3JlZGl0LWNhcmQtZ2F0ZXdheS1jYXJkLW51bWJlclwiXScpLnJlbW92ZUNsYXNzKCdwcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXktZm9ybS1maWVsZC1kaXNhYmxlZCcpXG4gICAgICAgIGpRdWVyeSgnI3BwY3AtY3JlZGl0LWNhcmQtZ2F0ZXdheS1jYXJkLW51bWJlcicpLnJlbW92ZUNsYXNzKCdwcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXktZm9ybS1maWVsZC1kaXNhYmxlZCcpXG4gICAgICAgIGpRdWVyeSgnbGFiZWxbZm9yPVwicHBjcC1jcmVkaXQtY2FyZC1nYXRld2F5LWNhcmQtZXhwaXJ5XCJdJykucmVtb3ZlQ2xhc3MoJ3BwY3AtY3JlZGl0LWNhcmQtZ2F0ZXdheS1mb3JtLWZpZWxkLWRpc2FibGVkJylcbiAgICAgICAgalF1ZXJ5KCcjcHBjcC1jcmVkaXQtY2FyZC1nYXRld2F5LWNhcmQtZXhwaXJ5JykucmVtb3ZlQ2xhc3MoJ3BwY3AtY3JlZGl0LWNhcmQtZ2F0ZXdheS1mb3JtLWZpZWxkLWRpc2FibGVkJylcbiAgICAgICAgalF1ZXJ5KCdsYWJlbFtmb3I9XCJwcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXktY2FyZC1jdmNcIl0nKS5yZW1vdmVDbGFzcygncHBjcC1jcmVkaXQtY2FyZC1nYXRld2F5LWZvcm0tZmllbGQtZGlzYWJsZWQnKVxuICAgICAgICBqUXVlcnkoJyNwcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXktY2FyZC1jdmMnKS5yZW1vdmVDbGFzcygncHBjcC1jcmVkaXQtY2FyZC1nYXRld2F5LWZvcm0tZmllbGQtZGlzYWJsZWQnKVxuICAgICAgICBqUXVlcnkoJ2xhYmVsW2Zvcj1cInZhdWx0XCJdJykucmVtb3ZlQ2xhc3MoJ3BwY3AtY3JlZGl0LWNhcmQtZ2F0ZXdheS1mb3JtLWZpZWxkLWRpc2FibGVkJylcbiAgICAgICAgalF1ZXJ5KCcjcHBjcC1jcmVkaXQtY2FyZC12YXVsdCcpLnJlbW92ZUNsYXNzKCdwcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXktZm9ybS1maWVsZC1kaXNhYmxlZCcpXG4gICAgICAgIGpRdWVyeSgnI3BwY3AtY3JlZGl0LWNhcmQtdmF1bHQnKS5hdHRyKFwiZGlzYWJsZWRcIiwgZmFsc2UpXG4gICAgICAgIHRoaXMucmVuZGVyZXIuZW5hYmxlQ3JlZGl0Q2FyZEZpZWxkcygpXG4gICAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBDaGVja291dEJvb3RzdGFwXG4iLCJpbXBvcnQgRXJyb3JIYW5kbGVyIGZyb20gJy4uL0Vycm9ySGFuZGxlcic7XG5pbXBvcnQgQ2hlY2tvdXRBY3Rpb25IYW5kbGVyIGZyb20gJy4uL0FjdGlvbkhhbmRsZXIvQ2hlY2tvdXRBY3Rpb25IYW5kbGVyJztcblxuY2xhc3MgUGF5Tm93Qm9vdHN0cmFwIHtcbiAgICBjb25zdHJ1Y3RvcihnYXRld2F5LCByZW5kZXJlciwgbWVzc2FnZXMsIHNwaW5uZXIpIHtcbiAgICAgICAgdGhpcy5nYXRld2F5ID0gZ2F0ZXdheTtcbiAgICAgICAgdGhpcy5yZW5kZXJlciA9IHJlbmRlcmVyO1xuICAgICAgICB0aGlzLm1lc3NhZ2VzID0gbWVzc2FnZXM7XG4gICAgICAgIHRoaXMuc3Bpbm5lciA9IHNwaW5uZXI7XG4gICAgfVxuXG4gICAgaW5pdCgpIHtcblxuICAgICAgICB0aGlzLnJlbmRlcigpO1xuXG4gICAgICAgIGpRdWVyeShkb2N1bWVudC5ib2R5KS5vbigndXBkYXRlZF9jaGVja291dCcsICgpID0+IHtcbiAgICAgICAgICAgIHRoaXMucmVuZGVyKCk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGpRdWVyeShkb2N1bWVudC5ib2R5KS5cbiAgICAgICAgb24oJ3VwZGF0ZWRfY2hlY2tvdXQgcGF5bWVudF9tZXRob2Rfc2VsZWN0ZWQnLCAoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLnN3aXRjaEJldHdlZW5QYXlQYWxhbmRPcmRlckJ1dHRvbigpO1xuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5zd2l0Y2hCZXR3ZWVuUGF5UGFsYW5kT3JkZXJCdXR0b24oKTtcbiAgICB9XG5cbiAgICBzaG91bGRSZW5kZXIoKSB7XG4gICAgICAgIGlmIChkb2N1bWVudC5xdWVyeVNlbGVjdG9yKHRoaXMuZ2F0ZXdheS5idXR0b24uY2FuY2VsX3dyYXBwZXIpKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gZG9jdW1lbnQucXVlcnlTZWxlY3Rvcih0aGlzLmdhdGV3YXkuYnV0dG9uLndyYXBwZXIpICE9PSBudWxsIHx8IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IodGhpcy5nYXRld2F5Lmhvc3RlZF9maWVsZHMud3JhcHBlcikgIT09IG51bGw7XG4gICAgfVxuXG4gICAgcmVuZGVyKCkge1xuICAgICAgICBpZiAoIXRoaXMuc2hvdWxkUmVuZGVyKCkpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBpZiAoZG9jdW1lbnQucXVlcnlTZWxlY3Rvcih0aGlzLmdhdGV3YXkuaG9zdGVkX2ZpZWxkcy53cmFwcGVyICsgJz5kaXYnKSkge1xuICAgICAgICAgICAgZG9jdW1lbnQucXVlcnlTZWxlY3Rvcih0aGlzLmdhdGV3YXkuaG9zdGVkX2ZpZWxkcy53cmFwcGVyICsgJz5kaXYnKS5zZXRBdHRyaWJ1dGUoJ3N0eWxlJywgJycpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGFjdGlvbkhhbmRsZXIgPSBuZXcgQ2hlY2tvdXRBY3Rpb25IYW5kbGVyKFxuICAgICAgICAgICAgUGF5UGFsQ29tbWVyY2VHYXRld2F5LFxuICAgICAgICAgICAgbmV3IEVycm9ySGFuZGxlcih0aGlzLmdhdGV3YXkubGFiZWxzLmVycm9yLmdlbmVyaWMpLFxuICAgICAgICAgICAgdGhpcy5zcGlubmVyXG4gICAgICAgICk7XG5cbiAgICAgICAgdGhpcy5yZW5kZXJlci5yZW5kZXIoXG4gICAgICAgICAgICB0aGlzLmdhdGV3YXkuYnV0dG9uLndyYXBwZXIsXG4gICAgICAgICAgICB0aGlzLmdhdGV3YXkuaG9zdGVkX2ZpZWxkcy53cmFwcGVyLFxuICAgICAgICAgICAgYWN0aW9uSGFuZGxlci5jb25maWd1cmF0aW9uKCksXG4gICAgICAgICk7XG4gICAgfVxuXG4gICAgc3dpdGNoQmV0d2VlblBheVBhbGFuZE9yZGVyQnV0dG9uKCkge1xuICAgICAgICBjb25zdCB1cmxQYXJhbXMgPSBuZXcgVVJMU2VhcmNoUGFyYW1zKHdpbmRvdy5sb2NhdGlvbi5zZWFyY2gpXG4gICAgICAgIGlmICh1cmxQYXJhbXMuaGFzKCdjaGFuZ2VfcGF5bWVudF9tZXRob2QnKSkge1xuICAgICAgICAgICAgcmV0dXJuXG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBjdXJyZW50UGF5bWVudE1ldGhvZCA9IGpRdWVyeShcbiAgICAgICAgICAgICdpbnB1dFtuYW1lPVwicGF5bWVudF9tZXRob2RcIl06Y2hlY2tlZCcpLnZhbCgpO1xuXG4gICAgICAgIGlmIChjdXJyZW50UGF5bWVudE1ldGhvZCAhPT0gJ3BwY3AtZ2F0ZXdheScgJiYgY3VycmVudFBheW1lbnRNZXRob2QgIT09ICdwcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXknKSB7XG4gICAgICAgICAgICB0aGlzLnJlbmRlcmVyLmhpZGVCdXR0b25zKHRoaXMuZ2F0ZXdheS5idXR0b24ud3JhcHBlcik7XG4gICAgICAgICAgICB0aGlzLnJlbmRlcmVyLmhpZGVCdXR0b25zKHRoaXMuZ2F0ZXdheS5tZXNzYWdlcy53cmFwcGVyKTtcbiAgICAgICAgICAgIHRoaXMucmVuZGVyZXIuaGlkZUJ1dHRvbnModGhpcy5nYXRld2F5Lmhvc3RlZF9maWVsZHMud3JhcHBlcik7XG4gICAgICAgICAgICBqUXVlcnkoJyNwbGFjZV9vcmRlcicpLnNob3coKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGpRdWVyeSgnI3BsYWNlX29yZGVyJykuaGlkZSgpO1xuICAgICAgICAgICAgaWYgKGN1cnJlbnRQYXltZW50TWV0aG9kID09PSAncHBjcC1nYXRld2F5Jykge1xuICAgICAgICAgICAgICAgIHRoaXMucmVuZGVyZXIuc2hvd0J1dHRvbnModGhpcy5nYXRld2F5LmJ1dHRvbi53cmFwcGVyKTtcbiAgICAgICAgICAgICAgICB0aGlzLnJlbmRlcmVyLnNob3dCdXR0b25zKHRoaXMuZ2F0ZXdheS5tZXNzYWdlcy53cmFwcGVyKTtcbiAgICAgICAgICAgICAgICB0aGlzLm1lc3NhZ2VzLnJlbmRlcigpO1xuICAgICAgICAgICAgICAgIHRoaXMucmVuZGVyZXIuaGlkZUJ1dHRvbnModGhpcy5nYXRld2F5Lmhvc3RlZF9maWVsZHMud3JhcHBlcik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoY3VycmVudFBheW1lbnRNZXRob2QgPT09ICdwcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXknKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5yZW5kZXJlci5oaWRlQnV0dG9ucyh0aGlzLmdhdGV3YXkuYnV0dG9uLndyYXBwZXIpO1xuICAgICAgICAgICAgICAgIHRoaXMucmVuZGVyZXIuaGlkZUJ1dHRvbnModGhpcy5nYXRld2F5Lm1lc3NhZ2VzLndyYXBwZXIpO1xuICAgICAgICAgICAgICAgIHRoaXMucmVuZGVyZXIuc2hvd0J1dHRvbnModGhpcy5nYXRld2F5Lmhvc3RlZF9maWVsZHMud3JhcHBlcik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IFBheU5vd0Jvb3RzdHJhcDtcbiIsImNsYXNzIFJlbmRlcmVyIHtcbiAgICBjb25zdHJ1Y3RvcihjcmVkaXRDYXJkUmVuZGVyZXIsIGRlZmF1bHRDb25maWcpIHtcbiAgICAgICAgdGhpcy5kZWZhdWx0Q29uZmlnID0gZGVmYXVsdENvbmZpZztcbiAgICAgICAgdGhpcy5jcmVkaXRDYXJkUmVuZGVyZXIgPSBjcmVkaXRDYXJkUmVuZGVyZXI7XG4gICAgfVxuXG4gICAgcmVuZGVyKHdyYXBwZXIsIGhvc3RlZEZpZWxkc1dyYXBwZXIsIGNvbnRleHRDb25maWcpIHtcblxuICAgICAgICB0aGlzLnJlbmRlckJ1dHRvbnMod3JhcHBlciwgY29udGV4dENvbmZpZyk7XG4gICAgICAgIHRoaXMuY3JlZGl0Q2FyZFJlbmRlcmVyLnJlbmRlcihob3N0ZWRGaWVsZHNXcmFwcGVyLCBjb250ZXh0Q29uZmlnKTtcbiAgICB9XG5cbiAgICByZW5kZXJCdXR0b25zKHdyYXBwZXIsIGNvbnRleHRDb25maWcpIHtcbiAgICAgICAgaWYgKCEgZG9jdW1lbnQucXVlcnlTZWxlY3Rvcih3cmFwcGVyKSB8fCB0aGlzLmlzQWxyZWFkeVJlbmRlcmVkKHdyYXBwZXIpIHx8ICd1bmRlZmluZWQnID09PSB0eXBlb2YgcGF5cGFsLkJ1dHRvbnMgKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBzdHlsZSA9IHdyYXBwZXIgPT09IHRoaXMuZGVmYXVsdENvbmZpZy5idXR0b24ud3JhcHBlciA/IHRoaXMuZGVmYXVsdENvbmZpZy5idXR0b24uc3R5bGUgOiB0aGlzLmRlZmF1bHRDb25maWcuYnV0dG9uLm1pbmlfY2FydF9zdHlsZTtcbiAgICAgICAgcGF5cGFsLkJ1dHRvbnMoe1xuICAgICAgICAgICAgc3R5bGUsXG4gICAgICAgICAgICAuLi5jb250ZXh0Q29uZmlnLFxuICAgICAgICB9KS5yZW5kZXIod3JhcHBlcik7XG4gICAgfVxuXG4gICAgaXNBbHJlYWR5UmVuZGVyZWQod3JhcHBlcikge1xuICAgICAgICByZXR1cm4gZG9jdW1lbnQucXVlcnlTZWxlY3Rvcih3cmFwcGVyKS5oYXNDaGlsZE5vZGVzKCk7XG4gICAgfVxuXG4gICAgaGlkZUJ1dHRvbnMoZWxlbWVudCkge1xuICAgICAgICBjb25zdCBkb21FbGVtZW50ID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcihlbGVtZW50KTtcbiAgICAgICAgaWYgKCEgZG9tRWxlbWVudCApIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICBkb21FbGVtZW50LnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIHNob3dCdXR0b25zKGVsZW1lbnQpIHtcbiAgICAgICAgY29uc3QgZG9tRWxlbWVudCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoZWxlbWVudCk7XG4gICAgICAgIGlmICghIGRvbUVsZW1lbnQgKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgZG9tRWxlbWVudC5zdHlsZS5kaXNwbGF5ID0gJ2Jsb2NrJztcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuXG4gICAgZGlzYWJsZUNyZWRpdENhcmRGaWVsZHMoKSB7XG4gICAgICAgIHRoaXMuY3JlZGl0Q2FyZFJlbmRlcmVyLmRpc2FibGVGaWVsZHMoKTtcbiAgICB9XG5cbiAgICBlbmFibGVDcmVkaXRDYXJkRmllbGRzKCkge1xuICAgICAgICB0aGlzLmNyZWRpdENhcmRSZW5kZXJlci5lbmFibGVGaWVsZHMoKTtcbiAgICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IFJlbmRlcmVyO1xuIiwiY29uc3QgZGNjSW5wdXRGYWN0b3J5ID0gKG9yaWdpbmFsKSA9PiB7XG4gICAgY29uc3Qgc3R5bGVzID0gd2luZG93LmdldENvbXB1dGVkU3R5bGUob3JpZ2luYWwpO1xuICAgIGNvbnN0IG5ld0VsZW1lbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdzcGFuJyk7XG4gICAgbmV3RWxlbWVudC5zZXRBdHRyaWJ1dGUoJ2lkJywgb3JpZ2luYWwuaWQpO1xuICAgIE9iamVjdC52YWx1ZXMoc3R5bGVzKS5mb3JFYWNoKCAocHJvcCkgPT4ge1xuICAgICAgICBpZiAoISBzdHlsZXNbcHJvcF0gfHwgISBpc05hTihwcm9wKSApIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBuZXdFbGVtZW50LnN0eWxlLnNldFByb3BlcnR5KHByb3AsJycgKyBzdHlsZXNbcHJvcF0pO1xuICAgIH0pO1xuICAgIHJldHVybiBuZXdFbGVtZW50O1xufVxuXG5leHBvcnQgZGVmYXVsdCBkY2NJbnB1dEZhY3Rvcnk7IiwiaW1wb3J0IGRjY0lucHV0RmFjdG9yeSBmcm9tIFwiLi4vSGVscGVyL0RjY0lucHV0RmFjdG9yeVwiO1xuXG5jbGFzcyBDcmVkaXRDYXJkUmVuZGVyZXIge1xuXG4gICAgY29uc3RydWN0b3IoZGVmYXVsdENvbmZpZywgZXJyb3JIYW5kbGVyLCBzcGlubmVyKSB7XG4gICAgICAgIHRoaXMuZGVmYXVsdENvbmZpZyA9IGRlZmF1bHRDb25maWc7XG4gICAgICAgIHRoaXMuZXJyb3JIYW5kbGVyID0gZXJyb3JIYW5kbGVyO1xuICAgICAgICB0aGlzLnNwaW5uZXIgPSBzcGlubmVyO1xuICAgICAgICB0aGlzLmNhcmRWYWxpZCA9IGZhbHNlO1xuICAgICAgICB0aGlzLmZvcm1WYWxpZCA9IGZhbHNlO1xuICAgICAgICB0aGlzLmN1cnJlbnRIb3N0ZWRGaWVsZHNJbnN0YW5jZSA9IG51bGw7XG4gICAgICAgIHRoaXMuZm9ybVN1Ym1pc3Npb25TdWJzY3JpYmVkID0gZmFsc2U7XG4gICAgfVxuXG4gICAgcmVuZGVyKHdyYXBwZXIsIGNvbnRleHRDb25maWcpIHtcblxuICAgICAgICBpZiAoXG4gICAgICAgICAgICAoXG4gICAgICAgICAgICAgICAgdGhpcy5kZWZhdWx0Q29uZmlnLmNvbnRleHQgIT09ICdjaGVja291dCdcbiAgICAgICAgICAgICAgICAmJiB0aGlzLmRlZmF1bHRDb25maWcuY29udGV4dCAhPT0gJ3BheS1ub3cnXG4gICAgICAgICAgICApXG4gICAgICAgICAgICB8fCB3cmFwcGVyID09PSBudWxsXG4gICAgICAgICAgICB8fCBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKHdyYXBwZXIpID09PSBudWxsXG4gICAgICAgICkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGlmIChcbiAgICAgICAgICAgIHR5cGVvZiBwYXlwYWwuSG9zdGVkRmllbGRzID09PSAndW5kZWZpbmVkJ1xuICAgICAgICAgICAgfHwgISBwYXlwYWwuSG9zdGVkRmllbGRzLmlzRWxpZ2libGUoKVxuICAgICAgICApIHtcbiAgICAgICAgICAgIGNvbnN0IHdyYXBwZXJFbGVtZW50ID0gZG9jdW1lbnQucXVlcnlTZWxlY3Rvcih3cmFwcGVyKTtcbiAgICAgICAgICAgIHdyYXBwZXJFbGVtZW50LnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQod3JhcHBlckVsZW1lbnQpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRoaXMuY3VycmVudEhvc3RlZEZpZWxkc0luc3RhbmNlKSB7XG4gICAgICAgICAgICB0aGlzLmN1cnJlbnRIb3N0ZWRGaWVsZHNJbnN0YW5jZS50ZWFyZG93bigpXG4gICAgICAgICAgICAgICAgLmNhdGNoKGVyciA9PiBjb25zb2xlLmVycm9yKGBIb3N0ZWQgZmllbGRzIHRlYXJkb3duIGVycm9yOiAke2Vycn1gKSk7XG4gICAgICAgICAgICB0aGlzLmN1cnJlbnRIb3N0ZWRGaWVsZHNJbnN0YW5jZSA9IG51bGw7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBnYXRlV2F5Qm94ID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignLnBheW1lbnRfYm94LnBheW1lbnRfbWV0aG9kX3BwY3AtY3JlZGl0LWNhcmQtZ2F0ZXdheScpO1xuICAgICAgICBjb25zdCBvbGREaXNwbGF5U3R5bGUgPSBnYXRlV2F5Qm94LnN0eWxlLmRpc3BsYXk7XG4gICAgICAgIGdhdGVXYXlCb3guc3R5bGUuZGlzcGxheSA9ICdibG9jayc7XG5cbiAgICAgICAgY29uc3QgaGlkZURjY0dhdGV3YXkgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjcHBjcC1oaWRlLWRjYycpO1xuICAgICAgICBpZiAoaGlkZURjY0dhdGV3YXkpIHtcbiAgICAgICAgICAgIGhpZGVEY2NHYXRld2F5LnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQoaGlkZURjY0dhdGV3YXkpO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgY2FyZE51bWJlckZpZWxkID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI3BwY3AtY3JlZGl0LWNhcmQtZ2F0ZXdheS1jYXJkLW51bWJlcicpO1xuXG4gICAgICAgIGNvbnN0IHN0eWxlc1JhdyA9IHdpbmRvdy5nZXRDb21wdXRlZFN0eWxlKGNhcmROdW1iZXJGaWVsZCk7XG4gICAgICAgIGxldCBzdHlsZXMgPSB7fTtcbiAgICAgICAgT2JqZWN0LnZhbHVlcyhzdHlsZXNSYXcpLmZvckVhY2goIChwcm9wKSA9PiB7XG4gICAgICAgICAgICBpZiAoISBzdHlsZXNSYXdbcHJvcF0pIHtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBzdHlsZXNbcHJvcF0gPSAnJyArIHN0eWxlc1Jhd1twcm9wXTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgY29uc3QgY2FyZE51bWJlciA9IGRjY0lucHV0RmFjdG9yeShjYXJkTnVtYmVyRmllbGQpO1xuICAgICAgICBjYXJkTnVtYmVyRmllbGQucGFyZW50Tm9kZS5yZXBsYWNlQ2hpbGQoY2FyZE51bWJlciwgY2FyZE51bWJlckZpZWxkKTtcblxuICAgICAgICBjb25zdCBjYXJkRXhwaXJ5RmllbGQgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjcHBjcC1jcmVkaXQtY2FyZC1nYXRld2F5LWNhcmQtZXhwaXJ5Jyk7XG4gICAgICAgIGNvbnN0IGNhcmRFeHBpcnkgPSBkY2NJbnB1dEZhY3RvcnkoY2FyZEV4cGlyeUZpZWxkKTtcbiAgICAgICAgY2FyZEV4cGlyeUZpZWxkLnBhcmVudE5vZGUucmVwbGFjZUNoaWxkKGNhcmRFeHBpcnksIGNhcmRFeHBpcnlGaWVsZCk7XG5cbiAgICAgICAgY29uc3QgY2FyZENvZGVGaWVsZCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNwcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXktY2FyZC1jdmMnKTtcbiAgICAgICAgY29uc3QgY2FyZENvZGUgPSBkY2NJbnB1dEZhY3RvcnkoY2FyZENvZGVGaWVsZCk7XG4gICAgICAgIGNhcmRDb2RlRmllbGQucGFyZW50Tm9kZS5yZXBsYWNlQ2hpbGQoY2FyZENvZGUsIGNhcmRDb2RlRmllbGQpO1xuXG4gICAgICAgIGdhdGVXYXlCb3guc3R5bGUuZGlzcGxheSA9IG9sZERpc3BsYXlTdHlsZTtcblxuICAgICAgICBjb25zdCBmb3JtV3JhcHBlciA9ICcucGF5bWVudF9ib3ggcGF5bWVudF9tZXRob2RfcHBjcC1jcmVkaXQtY2FyZC1nYXRld2F5JztcbiAgICAgICAgaWYgKFxuICAgICAgICAgICAgdGhpcy5kZWZhdWx0Q29uZmlnLmVuZm9yY2VfdmF1bHRcbiAgICAgICAgICAgICYmIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoZm9ybVdyYXBwZXIgKyAnIC5wcGNwLWNyZWRpdC1jYXJkLXZhdWx0JylcbiAgICAgICAgKSB7XG4gICAgICAgICAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKGZvcm1XcmFwcGVyICsgJyAucHBjcC1jcmVkaXQtY2FyZC12YXVsdCcpLmNoZWNrZWQgPSB0cnVlO1xuICAgICAgICAgICAgZG9jdW1lbnQucXVlcnlTZWxlY3Rvcihmb3JtV3JhcHBlciArICcgLnBwY3AtY3JlZGl0LWNhcmQtdmF1bHQnKS5zZXRBdHRyaWJ1dGUoJ2Rpc2FibGVkJywgdHJ1ZSk7XG4gICAgICAgIH1cbiAgICAgICAgcGF5cGFsLkhvc3RlZEZpZWxkcy5yZW5kZXIoe1xuICAgICAgICAgICAgY3JlYXRlT3JkZXI6IGNvbnRleHRDb25maWcuY3JlYXRlT3JkZXIsXG4gICAgICAgICAgICBzdHlsZXM6IHtcbiAgICAgICAgICAgICAgICAnaW5wdXQnOiBzdHlsZXNcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBmaWVsZHM6IHtcbiAgICAgICAgICAgICAgICBudW1iZXI6IHtcbiAgICAgICAgICAgICAgICAgICAgc2VsZWN0b3I6ICcjcHBjcC1jcmVkaXQtY2FyZC1nYXRld2F5LWNhcmQtbnVtYmVyJyxcbiAgICAgICAgICAgICAgICAgICAgcGxhY2Vob2xkZXI6IHRoaXMuZGVmYXVsdENvbmZpZy5ob3N0ZWRfZmllbGRzLmxhYmVscy5jcmVkaXRfY2FyZF9udW1iZXIsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBjdnY6IHtcbiAgICAgICAgICAgICAgICAgICAgc2VsZWN0b3I6ICcjcHBjcC1jcmVkaXQtY2FyZC1nYXRld2F5LWNhcmQtY3ZjJyxcbiAgICAgICAgICAgICAgICAgICAgcGxhY2Vob2xkZXI6IHRoaXMuZGVmYXVsdENvbmZpZy5ob3N0ZWRfZmllbGRzLmxhYmVscy5jdnYsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBleHBpcmF0aW9uRGF0ZToge1xuICAgICAgICAgICAgICAgICAgICBzZWxlY3RvcjogJyNwcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXktY2FyZC1leHBpcnknLFxuICAgICAgICAgICAgICAgICAgICBwbGFjZWhvbGRlcjogdGhpcy5kZWZhdWx0Q29uZmlnLmhvc3RlZF9maWVsZHMubGFiZWxzLm1tX3l5LFxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfSkudGhlbihob3N0ZWRGaWVsZHMgPT4ge1xuICAgICAgICAgICAgZG9jdW1lbnQuZGlzcGF0Y2hFdmVudChuZXcgQ3VzdG9tRXZlbnQoXCJob3N0ZWRfZmllbGRzX2xvYWRlZFwiKSk7XG4gICAgICAgICAgICB0aGlzLmN1cnJlbnRIb3N0ZWRGaWVsZHNJbnN0YW5jZSA9IGhvc3RlZEZpZWxkcztcblxuICAgICAgICAgICAgaG9zdGVkRmllbGRzLm9uKCdpbnB1dFN1Ym1pdFJlcXVlc3QnLCAoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5fc3VibWl0KGNvbnRleHRDb25maWcpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBob3N0ZWRGaWVsZHMub24oJ2NhcmRUeXBlQ2hhbmdlJywgKGV2ZW50KSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKCAhIGV2ZW50LmNhcmRzLmxlbmd0aCApIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5jYXJkVmFsaWQgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjb25zdCB2YWxpZENhcmRzID0gdGhpcy5kZWZhdWx0Q29uZmlnLmhvc3RlZF9maWVsZHMudmFsaWRfY2FyZHM7XG4gICAgICAgICAgICAgICAgdGhpcy5jYXJkVmFsaWQgPSB2YWxpZENhcmRzLmluZGV4T2YoZXZlbnQuY2FyZHNbMF0udHlwZSkgIT09IC0xO1xuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIGhvc3RlZEZpZWxkcy5vbigndmFsaWRpdHlDaGFuZ2UnLCAoZXZlbnQpID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCBmb3JtVmFsaWQgPSBPYmplY3Qua2V5cyhldmVudC5maWVsZHMpLmV2ZXJ5KGZ1bmN0aW9uIChrZXkpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGV2ZW50LmZpZWxkc1trZXldLmlzVmFsaWQ7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICB0aGlzLmZvcm1WYWxpZCA9IGZvcm1WYWxpZDtcblxuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIGlmICghdGhpcy5mb3JtU3VibWlzc2lvblN1YnNjcmliZWQpIHtcbiAgICAgICAgICAgICAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKHdyYXBwZXIgKyAnIGJ1dHRvbicpLmFkZEV2ZW50TGlzdGVuZXIoXG4gICAgICAgICAgICAgICAgICAgICdjbGljaycsXG4gICAgICAgICAgICAgICAgICAgIGV2ZW50ID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9zdWJtaXQoY29udGV4dENvbmZpZyk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgIHRoaXMuZm9ybVN1Ym1pc3Npb25TdWJzY3JpYmVkID0gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG5cbiAgICAgICAgZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI3BheW1lbnRfbWV0aG9kX3BwY3AtY3JlZGl0LWNhcmQtZ2F0ZXdheScpLmFkZEV2ZW50TGlzdGVuZXIoXG4gICAgICAgICAgICAnY2xpY2snLFxuICAgICAgICAgICAgKCkgPT4ge1xuICAgICAgICAgICAgICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJ2xhYmVsW2Zvcj1wcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXktY2FyZC1udW1iZXJdJykuY2xpY2soKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgKVxuICAgIH1cblxuICAgIGRpc2FibGVGaWVsZHMoKSB7XG4gICAgICAgIGlmKCB0aGlzLmN1cnJlbnRIb3N0ZWRGaWVsZHNJbnN0YW5jZSkge1xuICAgICAgICAgICAgdGhpcy5jdXJyZW50SG9zdGVkRmllbGRzSW5zdGFuY2Uuc2V0QXR0cmlidXRlKHtcbiAgICAgICAgICAgICAgICBmaWVsZDogJ251bWJlcicsXG4gICAgICAgICAgICAgICAgYXR0cmlidXRlOiAnZGlzYWJsZWQnXG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgdGhpcy5jdXJyZW50SG9zdGVkRmllbGRzSW5zdGFuY2Uuc2V0QXR0cmlidXRlKHtcbiAgICAgICAgICAgICAgICBmaWVsZDogJ2N2dicsXG4gICAgICAgICAgICAgICAgYXR0cmlidXRlOiAnZGlzYWJsZWQnXG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgdGhpcy5jdXJyZW50SG9zdGVkRmllbGRzSW5zdGFuY2Uuc2V0QXR0cmlidXRlKHtcbiAgICAgICAgICAgICAgICBmaWVsZDogJ2V4cGlyYXRpb25EYXRlJyxcbiAgICAgICAgICAgICAgICBhdHRyaWJ1dGU6ICdkaXNhYmxlZCdcbiAgICAgICAgICAgIH0pXG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBlbmFibGVGaWVsZHMoKSB7XG4gICAgICAgIGlmKCB0aGlzLmN1cnJlbnRIb3N0ZWRGaWVsZHNJbnN0YW5jZSkge1xuICAgICAgICAgICAgdGhpcy5jdXJyZW50SG9zdGVkRmllbGRzSW5zdGFuY2UucmVtb3ZlQXR0cmlidXRlKHtcbiAgICAgICAgICAgICAgICBmaWVsZDogJ251bWJlcicsXG4gICAgICAgICAgICAgICAgYXR0cmlidXRlOiAnZGlzYWJsZWQnXG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgdGhpcy5jdXJyZW50SG9zdGVkRmllbGRzSW5zdGFuY2UucmVtb3ZlQXR0cmlidXRlKHtcbiAgICAgICAgICAgICAgICBmaWVsZDogJ2N2dicsXG4gICAgICAgICAgICAgICAgYXR0cmlidXRlOiAnZGlzYWJsZWQnXG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgdGhpcy5jdXJyZW50SG9zdGVkRmllbGRzSW5zdGFuY2UucmVtb3ZlQXR0cmlidXRlKHtcbiAgICAgICAgICAgICAgICBmaWVsZDogJ2V4cGlyYXRpb25EYXRlJyxcbiAgICAgICAgICAgICAgICBhdHRyaWJ1dGU6ICdkaXNhYmxlZCdcbiAgICAgICAgICAgIH0pXG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBfc3VibWl0KGNvbnRleHRDb25maWcpIHtcbiAgICAgICAgdGhpcy5zcGlubmVyLmJsb2NrKCk7XG4gICAgICAgIHRoaXMuZXJyb3JIYW5kbGVyLmNsZWFyKCk7XG5cbiAgICAgICAgaWYgKHRoaXMuZm9ybVZhbGlkICYmIHRoaXMuY2FyZFZhbGlkKSB7XG4gICAgICAgICAgICBjb25zdCBzYXZlX2NhcmQgPSB0aGlzLmRlZmF1bHRDb25maWcuc2F2ZV9jYXJkID8gdHJ1ZSA6IGZhbHNlO1xuICAgICAgICAgICAgY29uc3QgdmF1bHQgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgncHBjcC1jcmVkaXQtY2FyZC12YXVsdCcpID9cbiAgICAgICAgICAgICAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgncHBjcC1jcmVkaXQtY2FyZC12YXVsdCcpLmNoZWNrZWQgOiBzYXZlX2NhcmQ7XG4gICAgICAgICAgICBjb25zdCBjb250aW5nZW5jeSA9IHRoaXMuZGVmYXVsdENvbmZpZy5ob3N0ZWRfZmllbGRzLmNvbnRpbmdlbmN5O1xuICAgICAgICAgICAgY29uc3QgaG9zdGVkRmllbGRzRGF0YSA9IHtcbiAgICAgICAgICAgICAgICB2YXVsdDogdmF1bHRcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBpZiAoY29udGluZ2VuY3kgIT09ICdOT18zRF9TRUNVUkUnKSB7XG4gICAgICAgICAgICAgICAgaG9zdGVkRmllbGRzRGF0YS5jb250aW5nZW5jaWVzID0gW2NvbnRpbmdlbmN5XTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMuY3VycmVudEhvc3RlZEZpZWxkc0luc3RhbmNlLnN1Ym1pdChob3N0ZWRGaWVsZHNEYXRhKS50aGVuKChwYXlsb2FkKSA9PiB7XG4gICAgICAgICAgICAgICAgcGF5bG9hZC5vcmRlcklEID0gcGF5bG9hZC5vcmRlcklkO1xuICAgICAgICAgICAgICAgIHRoaXMuc3Bpbm5lci51bmJsb2NrKCk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGNvbnRleHRDb25maWcub25BcHByb3ZlKHBheWxvYWQpO1xuICAgICAgICAgICAgfSkuY2F0Y2goZXJyID0+IHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKGVycik7XG4gICAgICAgICAgICAgICAgdGhpcy5zcGlubmVyLnVuYmxvY2soKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5zcGlubmVyLnVuYmxvY2soKTtcbiAgICAgICAgICAgIGNvbnN0IG1lc3NhZ2UgPSAhIHRoaXMuY2FyZFZhbGlkID8gdGhpcy5kZWZhdWx0Q29uZmlnLmhvc3RlZF9maWVsZHMubGFiZWxzLmNhcmRfbm90X3N1cHBvcnRlZCA6IHRoaXMuZGVmYXVsdENvbmZpZy5ob3N0ZWRfZmllbGRzLmxhYmVscy5maWVsZHNfbm90X3ZhbGlkO1xuICAgICAgICAgICAgdGhpcy5lcnJvckhhbmRsZXIubWVzc2FnZShtZXNzYWdlKTtcbiAgICAgICAgfVxuICAgIH1cbn1cbmV4cG9ydCBkZWZhdWx0IENyZWRpdENhcmRSZW5kZXJlcjtcbiIsImNvbnN0IHN0b3JhZ2VLZXkgPSAncHBjcC1kYXRhLWNsaWVudC1pZCc7XG5cbmNvbnN0IHZhbGlkYXRlVG9rZW4gPSAodG9rZW4sIHVzZXIpID0+IHtcbiAgICBpZiAoISB0b2tlbikge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGlmICh0b2tlbi51c2VyICE9PSB1c2VyKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgY29uc3QgY3VycmVudFRpbWUgPSBuZXcgRGF0ZSgpLmdldFRpbWUoKTtcbiAgICBjb25zdCBpc0V4cGlyZWQgPSBjdXJyZW50VGltZSA+PSB0b2tlbi5leHBpcmF0aW9uICogMTAwMDtcbiAgICByZXR1cm4gISBpc0V4cGlyZWQ7XG59XG5cbmNvbnN0IHN0b3JlZFRva2VuRm9yVXNlciA9ICh1c2VyKSA9PiB7XG4gICAgY29uc3QgdG9rZW4gPSBKU09OLnBhcnNlKHNlc3Npb25TdG9yYWdlLmdldEl0ZW0oc3RvcmFnZUtleSkpO1xuICAgIGlmICh2YWxpZGF0ZVRva2VuKHRva2VuLCB1c2VyKSkge1xuICAgICAgICByZXR1cm4gdG9rZW4udG9rZW47XG4gICAgfVxuICAgIHJldHVybiBudWxsO1xufVxuXG5jb25zdCBzdG9yZVRva2VuID0gKHRva2VuKSA9PiB7XG4gICAgc2Vzc2lvblN0b3JhZ2Uuc2V0SXRlbShzdG9yYWdlS2V5LCBKU09OLnN0cmluZ2lmeSh0b2tlbikpO1xufVxuXG5jb25zdCBkYXRhQ2xpZW50SWRBdHRyaWJ1dGVIYW5kbGVyID0gKHNjcmlwdCwgY29uZmlnKSA9PiB7XG4gICAgZmV0Y2goY29uZmlnLmVuZHBvaW50LCB7XG4gICAgICAgIG1ldGhvZDogJ1BPU1QnLFxuICAgICAgICBib2R5OiBKU09OLnN0cmluZ2lmeSh7XG4gICAgICAgICAgICBub25jZTogY29uZmlnLm5vbmNlXG4gICAgICAgIH0pXG4gICAgfSkudGhlbigocmVzKT0+e1xuICAgICAgICByZXR1cm4gcmVzLmpzb24oKTtcbiAgICB9KS50aGVuKChkYXRhKT0+e1xuICAgICAgICBjb25zdCBpc1ZhbGlkID0gdmFsaWRhdGVUb2tlbihkYXRhLCBjb25maWcudXNlcik7XG4gICAgICAgIGlmICghaXNWYWxpZCkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIHN0b3JlVG9rZW4oZGF0YSk7XG4gICAgICAgIHNjcmlwdC5zZXRBdHRyaWJ1dGUoJ2RhdGEtY2xpZW50LXRva2VuJywgZGF0YS50b2tlbik7XG4gICAgICAgIGRvY3VtZW50LmJvZHkuYXBwZW5kKHNjcmlwdCk7XG4gICAgfSk7XG59XG5cbmV4cG9ydCBkZWZhdWx0IGRhdGFDbGllbnRJZEF0dHJpYnV0ZUhhbmRsZXI7XG4iLCJjbGFzcyBNZXNzYWdlUmVuZGVyZXIge1xuXG4gICAgY29uc3RydWN0b3IoY29uZmlnKSB7XG4gICAgICAgIHRoaXMuY29uZmlnID0gY29uZmlnO1xuICAgIH1cblxuICAgIHJlbmRlcigpIHtcbiAgICAgICAgaWYgKCEgdGhpcy5zaG91bGRSZW5kZXIoKSkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgcGF5cGFsLk1lc3NhZ2VzKHtcbiAgICAgICAgICAgIGFtb3VudDogdGhpcy5jb25maWcuYW1vdW50LFxuICAgICAgICAgICAgcGxhY2VtZW50OiB0aGlzLmNvbmZpZy5wbGFjZW1lbnQsXG4gICAgICAgICAgICBzdHlsZTogdGhpcy5jb25maWcuc3R5bGVcbiAgICAgICAgfSkucmVuZGVyKHRoaXMuY29uZmlnLndyYXBwZXIpO1xuICAgIH1cblxuICAgIHJlbmRlcldpdGhBbW91bnQoYW1vdW50KSB7XG5cbiAgICAgICAgaWYgKCEgdGhpcy5zaG91bGRSZW5kZXIoKSkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgbmV3V3JhcHBlciA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgICAgICBuZXdXcmFwcGVyLnNldEF0dHJpYnV0ZSgnaWQnLCB0aGlzLmNvbmZpZy53cmFwcGVyLnJlcGxhY2UoJyMnLCAnJykpO1xuXG4gICAgICAgIGNvbnN0IHNpYmxpbmcgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKHRoaXMuY29uZmlnLndyYXBwZXIpLm5leHRTaWJsaW5nO1xuICAgICAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKHRoaXMuY29uZmlnLndyYXBwZXIpLnBhcmVudEVsZW1lbnQucmVtb3ZlQ2hpbGQoZG9jdW1lbnQucXVlcnlTZWxlY3Rvcih0aGlzLmNvbmZpZy53cmFwcGVyKSk7XG4gICAgICAgIHNpYmxpbmcucGFyZW50RWxlbWVudC5pbnNlcnRCZWZvcmUobmV3V3JhcHBlciwgc2libGluZyk7XG4gICAgICAgIHBheXBhbC5NZXNzYWdlcyh7XG4gICAgICAgICAgICBhbW91bnQsXG4gICAgICAgICAgICBwbGFjZW1lbnQ6IHRoaXMuY29uZmlnLnBsYWNlbWVudCxcbiAgICAgICAgICAgIHN0eWxlOiB0aGlzLmNvbmZpZy5zdHlsZVxuICAgICAgICB9KS5yZW5kZXIodGhpcy5jb25maWcud3JhcHBlcik7XG4gICAgfVxuXG4gICAgc2hvdWxkUmVuZGVyKCkge1xuXG4gICAgICAgIGlmICh0eXBlb2YgcGF5cGFsLk1lc3NhZ2VzID09PSAndW5kZWZpbmVkJyB8fCB0eXBlb2YgdGhpcy5jb25maWcud3JhcHBlciA9PT0gJ3VuZGVmaW5lZCcgKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCEgZG9jdW1lbnQucXVlcnlTZWxlY3Rvcih0aGlzLmNvbmZpZy53cmFwcGVyKSkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbn1cbmV4cG9ydCBkZWZhdWx0IE1lc3NhZ2VSZW5kZXJlcjsiLCJjbGFzcyBTcGlubmVyIHtcblxuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICB0aGlzLnRhcmdldCA9ICdmb3JtLndvb2NvbW1lcmNlLWNoZWNrb3V0JztcbiAgICB9XG5cbiAgICBzZXRUYXJnZXQodGFyZ2V0KSB7XG4gICAgICAgIHRoaXMudGFyZ2V0ID0gdGFyZ2V0O1xuICAgIH1cblxuICAgIGJsb2NrKCkge1xuXG4gICAgICAgIGpRdWVyeSggdGhpcy50YXJnZXQgKS5ibG9jayh7XG4gICAgICAgICAgICBtZXNzYWdlOiBudWxsLFxuICAgICAgICAgICAgb3ZlcmxheUNTUzoge1xuICAgICAgICAgICAgICAgIGJhY2tncm91bmQ6ICcjZmZmJyxcbiAgICAgICAgICAgICAgICBvcGFjaXR5OiAwLjZcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgdW5ibG9jaygpIHtcblxuICAgICAgICBqUXVlcnkoIHRoaXMudGFyZ2V0ICkudW5ibG9jaygpO1xuICAgIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgU3Bpbm5lcjtcbiIsImltcG9ydCBNaW5pQ2FydEJvb3RzdGFwIGZyb20gJy4vbW9kdWxlcy9Db250ZXh0Qm9vdHN0cmFwL01pbmlDYXJ0Qm9vdHN0YXAnO1xuaW1wb3J0IFNpbmdsZVByb2R1Y3RCb290c3RhcCBmcm9tICcuL21vZHVsZXMvQ29udGV4dEJvb3RzdHJhcC9TaW5nbGVQcm9kdWN0Qm9vdHN0YXAnO1xuaW1wb3J0IENhcnRCb290c3RyYXAgZnJvbSAnLi9tb2R1bGVzL0NvbnRleHRCb290c3RyYXAvQ2FydEJvb3RzdGFwJztcbmltcG9ydCBDaGVja291dEJvb3RzdGFwIGZyb20gJy4vbW9kdWxlcy9Db250ZXh0Qm9vdHN0cmFwL0NoZWNrb3V0Qm9vdHN0YXAnO1xuaW1wb3J0IFBheU5vd0Jvb3RzdHJhcCBmcm9tIFwiLi9tb2R1bGVzL0NvbnRleHRCb290c3RyYXAvUGF5Tm93Qm9vdHN0cmFwXCI7XG5pbXBvcnQgUmVuZGVyZXIgZnJvbSAnLi9tb2R1bGVzL1JlbmRlcmVyL1JlbmRlcmVyJztcbmltcG9ydCBFcnJvckhhbmRsZXIgZnJvbSAnLi9tb2R1bGVzL0Vycm9ySGFuZGxlcic7XG5pbXBvcnQgQ3JlZGl0Q2FyZFJlbmRlcmVyIGZyb20gXCIuL21vZHVsZXMvUmVuZGVyZXIvQ3JlZGl0Q2FyZFJlbmRlcmVyXCI7XG5pbXBvcnQgZGF0YUNsaWVudElkQXR0cmlidXRlSGFuZGxlciBmcm9tIFwiLi9tb2R1bGVzL0RhdGFDbGllbnRJZEF0dHJpYnV0ZUhhbmRsZXJcIjtcbmltcG9ydCBNZXNzYWdlUmVuZGVyZXIgZnJvbSBcIi4vbW9kdWxlcy9SZW5kZXJlci9NZXNzYWdlUmVuZGVyZXJcIjtcbmltcG9ydCBTcGlubmVyIGZyb20gXCIuL21vZHVsZXMvSGVscGVyL1NwaW5uZXJcIjtcblxuY29uc3QgYm9vdHN0cmFwID0gKCkgPT4ge1xuICAgIGNvbnN0IGVycm9ySGFuZGxlciA9IG5ldyBFcnJvckhhbmRsZXIoUGF5UGFsQ29tbWVyY2VHYXRld2F5LmxhYmVscy5lcnJvci5nZW5lcmljKTtcbiAgICBjb25zdCBzcGlubmVyID0gbmV3IFNwaW5uZXIoKTtcbiAgICBjb25zdCBjcmVkaXRDYXJkUmVuZGVyZXIgPSBuZXcgQ3JlZGl0Q2FyZFJlbmRlcmVyKFBheVBhbENvbW1lcmNlR2F0ZXdheSwgZXJyb3JIYW5kbGVyLCBzcGlubmVyKTtcbiAgICBjb25zdCByZW5kZXJlciA9IG5ldyBSZW5kZXJlcihjcmVkaXRDYXJkUmVuZGVyZXIsIFBheVBhbENvbW1lcmNlR2F0ZXdheSk7XG4gICAgY29uc3QgbWVzc2FnZVJlbmRlcmVyID0gbmV3IE1lc3NhZ2VSZW5kZXJlcihQYXlQYWxDb21tZXJjZUdhdGV3YXkubWVzc2FnZXMpO1xuICAgIGNvbnN0IGNvbnRleHQgPSBQYXlQYWxDb21tZXJjZUdhdGV3YXkuY29udGV4dDtcbiAgICBpZiAoY29udGV4dCA9PT0gJ21pbmktY2FydCcgfHwgY29udGV4dCA9PT0gJ3Byb2R1Y3QnKSB7XG4gICAgICAgIGlmIChQYXlQYWxDb21tZXJjZUdhdGV3YXkubWluaV9jYXJ0X2J1dHRvbnNfZW5hYmxlZCA9PT0gJzEnKSB7XG4gICAgICAgICAgICBjb25zdCBtaW5pQ2FydEJvb3RzdHJhcCA9IG5ldyBNaW5pQ2FydEJvb3RzdGFwKFxuICAgICAgICAgICAgICAgIFBheVBhbENvbW1lcmNlR2F0ZXdheSxcbiAgICAgICAgICAgICAgICByZW5kZXJlclxuICAgICAgICAgICAgKTtcblxuICAgICAgICAgICAgbWluaUNhcnRCb290c3RyYXAuaW5pdCgpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgaWYgKGNvbnRleHQgPT09ICdwcm9kdWN0JyAmJiBQYXlQYWxDb21tZXJjZUdhdGV3YXkuc2luZ2xlX3Byb2R1Y3RfYnV0dG9uc19lbmFibGVkID09PSAnMScpIHtcbiAgICAgICAgY29uc3Qgc2luZ2xlUHJvZHVjdEJvb3RzdHJhcCA9IG5ldyBTaW5nbGVQcm9kdWN0Qm9vdHN0YXAoXG4gICAgICAgICAgICBQYXlQYWxDb21tZXJjZUdhdGV3YXksXG4gICAgICAgICAgICByZW5kZXJlcixcbiAgICAgICAgICAgIG1lc3NhZ2VSZW5kZXJlcixcbiAgICAgICAgKTtcblxuICAgICAgICBzaW5nbGVQcm9kdWN0Qm9vdHN0cmFwLmluaXQoKTtcbiAgICB9XG5cbiAgICBpZiAoY29udGV4dCA9PT0gJ2NhcnQnKSB7XG4gICAgICAgIGNvbnN0IGNhcnRCb290c3RyYXAgPSBuZXcgQ2FydEJvb3RzdHJhcChcbiAgICAgICAgICAgIFBheVBhbENvbW1lcmNlR2F0ZXdheSxcbiAgICAgICAgICAgIHJlbmRlcmVyLFxuICAgICAgICApO1xuXG4gICAgICAgIGNhcnRCb290c3RyYXAuaW5pdCgpO1xuICAgIH1cblxuICAgIGlmIChjb250ZXh0ID09PSAnY2hlY2tvdXQnKSB7XG4gICAgICAgIGNvbnN0IGNoZWNrb3V0Qm9vdHN0YXAgPSBuZXcgQ2hlY2tvdXRCb290c3RhcChcbiAgICAgICAgICAgIFBheVBhbENvbW1lcmNlR2F0ZXdheSxcbiAgICAgICAgICAgIHJlbmRlcmVyLFxuICAgICAgICAgICAgbWVzc2FnZVJlbmRlcmVyLFxuICAgICAgICAgICAgc3Bpbm5lclxuICAgICAgICApO1xuXG4gICAgICAgIGNoZWNrb3V0Qm9vdHN0YXAuaW5pdCgpO1xuICAgIH1cblxuICAgIGlmIChjb250ZXh0ID09PSAncGF5LW5vdycgKSB7XG4gICAgICAgIGNvbnN0IHBheU5vd0Jvb3RzdHJhcCA9IG5ldyBQYXlOb3dCb290c3RyYXAoXG4gICAgICAgICAgICBQYXlQYWxDb21tZXJjZUdhdGV3YXksXG4gICAgICAgICAgICByZW5kZXJlcixcbiAgICAgICAgICAgIG1lc3NhZ2VSZW5kZXJlcixcbiAgICAgICAgICAgIHNwaW5uZXJcbiAgICAgICAgKTtcbiAgICAgICAgcGF5Tm93Qm9vdHN0cmFwLmluaXQoKTtcbiAgICB9XG5cbiAgICBpZiAoY29udGV4dCAhPT0gJ2NoZWNrb3V0Jykge1xuICAgICAgICBtZXNzYWdlUmVuZGVyZXIucmVuZGVyKCk7XG4gICAgfVxufTtcbmRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoXG4gICAgJ0RPTUNvbnRlbnRMb2FkZWQnLFxuICAgICgpID0+IHtcbiAgICAgICAgaWYgKCF0eXBlb2YgKFBheVBhbENvbW1lcmNlR2F0ZXdheSkpIHtcbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ1BheVBhbCBidXR0b24gY291bGQgbm90IGJlIGNvbmZpZ3VyZWQuJyk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgY29uc3Qgc2NyaXB0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnc2NyaXB0Jyk7XG5cbiAgICAgICAgc2NyaXB0LmFkZEV2ZW50TGlzdGVuZXIoJ2xvYWQnLCAoZXZlbnQpID0+IHtcbiAgICAgICAgICAgIGJvb3RzdHJhcCgpO1xuICAgICAgICB9KTtcbiAgICAgICAgc2NyaXB0LnNldEF0dHJpYnV0ZSgnc3JjJywgUGF5UGFsQ29tbWVyY2VHYXRld2F5LmJ1dHRvbi51cmwpO1xuICAgICAgICBPYmplY3QuZW50cmllcyhQYXlQYWxDb21tZXJjZUdhdGV3YXkuc2NyaXB0X2F0dHJpYnV0ZXMpLmZvckVhY2goXG4gICAgICAgICAgICAoa2V5VmFsdWUpID0+IHtcbiAgICAgICAgICAgICAgICBzY3JpcHQuc2V0QXR0cmlidXRlKGtleVZhbHVlWzBdLCBrZXlWYWx1ZVsxXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICk7XG5cbiAgICAgICAgaWYgKFBheVBhbENvbW1lcmNlR2F0ZXdheS5kYXRhX2NsaWVudF9pZC5zZXRfYXR0cmlidXRlKSB7XG4gICAgICAgICAgICBkYXRhQ2xpZW50SWRBdHRyaWJ1dGVIYW5kbGVyKHNjcmlwdCwgUGF5UGFsQ29tbWVyY2VHYXRld2F5LmRhdGFfY2xpZW50X2lkKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGRvY3VtZW50LmJvZHkuYXBwZW5kKHNjcmlwdCk7XG4gICAgfSxcbik7XG4iXSwibmFtZXMiOlsiRXJyb3JIYW5kbGVyIiwiY29uc3RydWN0b3IiLCJnZW5lcmljRXJyb3JUZXh0Iiwid3JhcHBlciIsImRvY3VtZW50IiwicXVlcnlTZWxlY3RvciIsIm1lc3NhZ2VzTGlzdCIsImdlbmVyaWNFcnJvciIsImNsYXNzTGlzdCIsImNvbnRhaW5zIiwiY2xlYXIiLCJtZXNzYWdlIiwiYXBwZW5kUHJlcGFyZWRFcnJvck1lc3NhZ2VFbGVtZW50IiwiZXJyb3JNZXNzYWdlRWxlbWVudCIsInByZXBhcmVNZXNzYWdlc0xpc3QiLCJyZXBsYWNlV2l0aCIsInRleHQiLCJwZXJzaXN0IiwiU3RyaW5nIiwibGVuZ3RoIiwiRXJyb3IiLCJhZGQiLCJyZW1vdmUiLCJtZXNzYWdlTm9kZSIsInByZXBhcmVNZXNzYWdlc0xpc3RJdGVtIiwiYXBwZW5kQ2hpbGQiLCJqUXVlcnkiLCJzY3JvbGxfdG9fbm90aWNlcyIsImNyZWF0ZUVsZW1lbnQiLCJzZXRBdHRyaWJ1dGUiLCJsaSIsImlubmVySFRNTCIsInNhbml0aXplIiwidGV4dGFyZWEiLCJ2YWx1ZSIsInJlcGxhY2UiLCJpbm5lclRleHQiLCJvbkFwcHJvdmUiLCJjb250ZXh0IiwiZXJyb3JIYW5kbGVyIiwiZGF0YSIsImFjdGlvbnMiLCJmZXRjaCIsImNvbmZpZyIsImFqYXgiLCJhcHByb3ZlX29yZGVyIiwiZW5kcG9pbnQiLCJtZXRob2QiLCJib2R5IiwiSlNPTiIsInN0cmluZ2lmeSIsIm5vbmNlIiwib3JkZXJfaWQiLCJvcmRlcklEIiwidGhlbiIsInJlcyIsImpzb24iLCJzdWNjZXNzIiwicmVzdGFydCIsImNhdGNoIiwiZXJyIiwibG9jYXRpb24iLCJocmVmIiwicmVkaXJlY3QiLCJwYXllckRhdGEiLCJwYXllciIsIlBheVBhbENvbW1lcmNlR2F0ZXdheSIsInBob25lIiwicGhvbmVfdHlwZSIsInBob25lX251bWJlciIsIm5hdGlvbmFsX251bWJlciIsImVtYWlsX2FkZHJlc3MiLCJuYW1lIiwic3VybmFtZSIsImdpdmVuX25hbWUiLCJhZGRyZXNzIiwiY291bnRyeV9jb2RlIiwiYWRkcmVzc19saW5lXzEiLCJhZGRyZXNzX2xpbmVfMiIsImFkbWluX2FyZWFfMSIsImFkbWluX2FyZWFfMiIsInBvc3RhbF9jb2RlIiwiQ2FydEFjdGlvbkhhbmRsZXIiLCJjb25maWd1cmF0aW9uIiwiY3JlYXRlT3JkZXIiLCJibkNvZGUiLCJibl9jb2RlcyIsImNyZWF0ZV9vcmRlciIsInB1cmNoYXNlX3VuaXRzIiwiYm5fY29kZSIsImNvbnNvbGUiLCJlcnJvciIsImlkIiwib25FcnJvciIsIk1pbmlDYXJ0Qm9vdHN0YXAiLCJnYXRld2F5IiwicmVuZGVyZXIiLCJhY3Rpb25IYW5kbGVyIiwiaW5pdCIsImxhYmVscyIsImdlbmVyaWMiLCJyZW5kZXIiLCJvbiIsInNob3VsZFJlbmRlciIsImJ1dHRvbiIsIm1pbmlfY2FydF93cmFwcGVyIiwiaG9zdGVkX2ZpZWxkcyIsIlByb2R1Y3QiLCJVcGRhdGVDYXJ0IiwidXBkYXRlIiwib25SZXNvbHZlIiwicHJvZHVjdHMiLCJQcm9taXNlIiwicmVzb2x2ZSIsInJlamVjdCIsInJlc3VsdCIsInJlc29sdmVkIiwiQnV0dG9uc1RvZ2dsZUxpc3RlbmVyIiwiZWxlbWVudCIsInNob3dDYWxsYmFjayIsImhpZGVDYWxsYmFjayIsIm9ic2VydmVyIiwiYXR0cmlidXRlcyIsImNhbGxiYWNrIiwiTXV0YXRpb25PYnNlcnZlciIsIm9ic2VydmUiLCJkaXNjb25uZWN0IiwicXVhbnRpdHkiLCJ2YXJpYXRpb25zIiwiU2luZ2xlUHJvZHVjdEFjdGlvbkhhbmRsZXIiLCJ1cGRhdGVDYXJ0Iiwic2hvd0J1dHRvbkNhbGxiYWNrIiwiaGlkZUJ1dHRvbkNhbGxiYWNrIiwiZm9ybUVsZW1lbnQiLCJoYXNWYXJpYXRpb25zIiwiZ2V0UHJvZHVjdHMiLCJpc0dyb3VwZWRQcm9kdWN0IiwicXR5IiwicXVlcnlTZWxlY3RvckFsbCIsImZvckVhY2giLCJlbGVtZW50TmFtZSIsImdldEF0dHJpYnV0ZSIsIm1hdGNoIiwicGFyc2VJbnQiLCJwdXNoIiwicHJvbWlzZSIsIm1hcCIsIlNpbmdsZVByb2R1Y3RCb290c3RhcCIsIm1lc3NhZ2VzIiwiaGlkZUJ1dHRvbnMiLCJjaGFuZ2VfY2FydCIsInNob3dCdXR0b25zIiwicHJpY2VUZXh0IiwiYW1vdW50IiwicmVuZGVyV2l0aEFtb3VudCIsIkNhcnRCb290c3RyYXAiLCJzcGlubmVyIiwiYmxvY2siLCJ1bmJsb2NrIiwiY29kZSIsImNsaWNrIiwiQ2hlY2tvdXRBY3Rpb25IYW5kbGVyIiwiZm9ybVNlbGVjdG9yIiwiZm9ybVZhbHVlcyIsInNlcmlhbGl6ZSIsImNyZWF0ZWFjY291bnQiLCJpcyIsImZvcm0iLCJkb21QYXJzZXIiLCJET01QYXJzZXIiLCJwYXJzZUZyb21TdHJpbmciLCJpbnB1dCIsImN1c3RvbV9pZCIsImFwcGVuZCIsIm9uQ2FuY2VsIiwiQ2hlY2tvdXRCb290c3RhcCIsInN3aXRjaEJldHdlZW5QYXlQYWxhbmRPcmRlckJ1dHRvbiIsImRpc3BsYXlQbGFjZU9yZGVyQnV0dG9uRm9yU2F2ZWRDcmVkaXRDYXJkcyIsImNhbmNlbF93cmFwcGVyIiwidmFsIiwiY3VycmVudFBheW1lbnRNZXRob2QiLCJzaG93IiwiaGlkZSIsImRpc2FibGVDcmVkaXRDYXJkRmllbGRzIiwiZW5hYmxlQ3JlZGl0Q2FyZEZpZWxkcyIsImFkZENsYXNzIiwiYXR0ciIsInJlbW92ZUNsYXNzIiwiUGF5Tm93Qm9vdHN0cmFwIiwidXJsUGFyYW1zIiwiVVJMU2VhcmNoUGFyYW1zIiwid2luZG93Iiwic2VhcmNoIiwiaGFzIiwiUmVuZGVyZXIiLCJjcmVkaXRDYXJkUmVuZGVyZXIiLCJkZWZhdWx0Q29uZmlnIiwiaG9zdGVkRmllbGRzV3JhcHBlciIsImNvbnRleHRDb25maWciLCJyZW5kZXJCdXR0b25zIiwiaXNBbHJlYWR5UmVuZGVyZWQiLCJwYXlwYWwiLCJCdXR0b25zIiwic3R5bGUiLCJtaW5pX2NhcnRfc3R5bGUiLCJoYXNDaGlsZE5vZGVzIiwiZG9tRWxlbWVudCIsImRpc3BsYXkiLCJkaXNhYmxlRmllbGRzIiwiZW5hYmxlRmllbGRzIiwiZGNjSW5wdXRGYWN0b3J5Iiwib3JpZ2luYWwiLCJzdHlsZXMiLCJnZXRDb21wdXRlZFN0eWxlIiwibmV3RWxlbWVudCIsIk9iamVjdCIsInZhbHVlcyIsInByb3AiLCJpc05hTiIsInNldFByb3BlcnR5IiwiQ3JlZGl0Q2FyZFJlbmRlcmVyIiwiY2FyZFZhbGlkIiwiZm9ybVZhbGlkIiwiY3VycmVudEhvc3RlZEZpZWxkc0luc3RhbmNlIiwiZm9ybVN1Ym1pc3Npb25TdWJzY3JpYmVkIiwiSG9zdGVkRmllbGRzIiwiaXNFbGlnaWJsZSIsIndyYXBwZXJFbGVtZW50IiwicGFyZW50Tm9kZSIsInJlbW92ZUNoaWxkIiwidGVhcmRvd24iLCJnYXRlV2F5Qm94Iiwib2xkRGlzcGxheVN0eWxlIiwiaGlkZURjY0dhdGV3YXkiLCJjYXJkTnVtYmVyRmllbGQiLCJzdHlsZXNSYXciLCJjYXJkTnVtYmVyIiwicmVwbGFjZUNoaWxkIiwiY2FyZEV4cGlyeUZpZWxkIiwiY2FyZEV4cGlyeSIsImNhcmRDb2RlRmllbGQiLCJjYXJkQ29kZSIsImZvcm1XcmFwcGVyIiwiZW5mb3JjZV92YXVsdCIsImNoZWNrZWQiLCJmaWVsZHMiLCJudW1iZXIiLCJzZWxlY3RvciIsInBsYWNlaG9sZGVyIiwiY3JlZGl0X2NhcmRfbnVtYmVyIiwiY3Z2IiwiZXhwaXJhdGlvbkRhdGUiLCJtbV95eSIsImhvc3RlZEZpZWxkcyIsImRpc3BhdGNoRXZlbnQiLCJDdXN0b21FdmVudCIsIl9zdWJtaXQiLCJldmVudCIsImNhcmRzIiwidmFsaWRDYXJkcyIsInZhbGlkX2NhcmRzIiwiaW5kZXhPZiIsInR5cGUiLCJrZXlzIiwiZXZlcnkiLCJrZXkiLCJpc1ZhbGlkIiwiYWRkRXZlbnRMaXN0ZW5lciIsInByZXZlbnREZWZhdWx0IiwiZmllbGQiLCJhdHRyaWJ1dGUiLCJyZW1vdmVBdHRyaWJ1dGUiLCJzYXZlX2NhcmQiLCJ2YXVsdCIsImdldEVsZW1lbnRCeUlkIiwiY29udGluZ2VuY3kiLCJob3N0ZWRGaWVsZHNEYXRhIiwiY29udGluZ2VuY2llcyIsInN1Ym1pdCIsInBheWxvYWQiLCJvcmRlcklkIiwiY2FyZF9ub3Rfc3VwcG9ydGVkIiwiZmllbGRzX25vdF92YWxpZCIsInN0b3JhZ2VLZXkiLCJ2YWxpZGF0ZVRva2VuIiwidG9rZW4iLCJ1c2VyIiwiY3VycmVudFRpbWUiLCJEYXRlIiwiZ2V0VGltZSIsImlzRXhwaXJlZCIsImV4cGlyYXRpb24iLCJzdG9yZWRUb2tlbkZvclVzZXIiLCJwYXJzZSIsInNlc3Npb25TdG9yYWdlIiwiZ2V0SXRlbSIsInN0b3JlVG9rZW4iLCJzZXRJdGVtIiwiZGF0YUNsaWVudElkQXR0cmlidXRlSGFuZGxlciIsInNjcmlwdCIsIk1lc3NhZ2VSZW5kZXJlciIsIk1lc3NhZ2VzIiwicGxhY2VtZW50IiwibmV3V3JhcHBlciIsInNpYmxpbmciLCJuZXh0U2libGluZyIsInBhcmVudEVsZW1lbnQiLCJpbnNlcnRCZWZvcmUiLCJTcGlubmVyIiwidGFyZ2V0Iiwic2V0VGFyZ2V0Iiwib3ZlcmxheUNTUyIsImJhY2tncm91bmQiLCJvcGFjaXR5IiwiYm9vdHN0cmFwIiwibWVzc2FnZVJlbmRlcmVyIiwibWluaV9jYXJ0X2J1dHRvbnNfZW5hYmxlZCIsIm1pbmlDYXJ0Qm9vdHN0cmFwIiwic2luZ2xlX3Byb2R1Y3RfYnV0dG9uc19lbmFibGVkIiwic2luZ2xlUHJvZHVjdEJvb3RzdHJhcCIsImNhcnRCb290c3RyYXAiLCJjaGVja291dEJvb3RzdGFwIiwicGF5Tm93Qm9vdHN0cmFwIiwidXJsIiwiZW50cmllcyIsInNjcmlwdF9hdHRyaWJ1dGVzIiwia2V5VmFsdWUiLCJkYXRhX2NsaWVudF9pZCIsInNldF9hdHRyaWJ1dGUiXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///94\n")}},__webpack_exports__={};__webpack_modules__[94]()})();
1
+ (()=>{"use strict";var __webpack_modules__={94:()=>{eval("\n;// CONCATENATED MODULE: ./resources/js/modules/ErrorHandler.js\nclass ErrorHandler {\n constructor(genericErrorText) {\n this.genericErrorText = genericErrorText;\n this.wrapper = document.querySelector('.woocommerce-notices-wrapper');\n this.messagesList = document.querySelector('ul.woocommerce-error');\n }\n\n genericError() {\n if (this.wrapper.classList.contains('ppcp-persist')) {\n return;\n }\n\n this.clear();\n this.message(this.genericErrorText);\n }\n\n appendPreparedErrorMessageElement(errorMessageElement) {\n if (this.messagesList === null) {\n this.prepareMessagesList();\n }\n\n this.messagesList.replaceWith(errorMessageElement);\n }\n\n message(text, persist = false) {\n if (!typeof String || text.length === 0) {\n throw new Error('A new message text must be a non-empty string.');\n }\n\n if (this.messagesList === null) {\n this.prepareMessagesList();\n }\n\n if (persist) {\n this.wrapper.classList.add('ppcp-persist');\n } else {\n this.wrapper.classList.remove('ppcp-persist');\n }\n\n let messageNode = this.prepareMessagesListItem(text);\n this.messagesList.appendChild(messageNode);\n jQuery.scroll_to_notices(jQuery('.woocommerce-notices-wrapper'));\n }\n\n prepareMessagesList() {\n if (this.messagesList === null) {\n this.messagesList = document.createElement('ul');\n this.messagesList.setAttribute('class', 'woocommerce-error');\n this.messagesList.setAttribute('role', 'alert');\n this.wrapper.appendChild(this.messagesList);\n }\n }\n\n prepareMessagesListItem(message) {\n const li = document.createElement('li');\n li.innerHTML = message;\n return li;\n }\n\n sanitize(text) {\n const textarea = document.createElement('textarea');\n textarea.innerHTML = text;\n return textarea.value.replace('Error: ', '');\n }\n\n clear() {\n if (!this.wrapper.classList.contains('woocommerce-error')) {\n return;\n }\n\n this.wrapper.classList.remove('woocommerce-error');\n this.wrapper.innerText = '';\n }\n\n}\n\n/* harmony default export */ const modules_ErrorHandler = (ErrorHandler);\n;// CONCATENATED MODULE: ./resources/js/modules/OnApproveHandler/onApproveForContinue.js\nconst onApprove = (context, errorHandler) => {\n return (data, actions) => {\n return fetch(context.config.ajax.approve_order.endpoint, {\n method: 'POST',\n body: JSON.stringify({\n nonce: context.config.ajax.approve_order.nonce,\n order_id: data.orderID\n })\n }).then(res => {\n return res.json();\n }).then(data => {\n if (!data.success) {\n errorHandler.genericError();\n return actions.restart().catch(err => {\n errorHandler.genericError();\n });\n ;\n }\n\n location.href = context.config.redirect;\n });\n };\n};\n\n/* harmony default export */ const onApproveForContinue = (onApprove);\n;// CONCATENATED MODULE: ./resources/js/modules/Helper/PayerData.js\nconst payerData = () => {\n const payer = PayPalCommerceGateway.payer;\n\n if (!payer) {\n return null;\n }\n\n const phone = document.querySelector('#billing_phone') || typeof payer.phone !== 'undefined' ? {\n phone_type: \"HOME\",\n phone_number: {\n national_number: document.querySelector('#billing_phone') ? document.querySelector('#billing_phone').value : payer.phone.phone_number.national_number\n }\n } : null;\n const payerData = {\n email_address: document.querySelector('#billing_email') ? document.querySelector('#billing_email').value : payer.email_address,\n name: {\n surname: document.querySelector('#billing_last_name') ? document.querySelector('#billing_last_name').value : payer.name.surname,\n given_name: document.querySelector('#billing_first_name') ? document.querySelector('#billing_first_name').value : payer.name.given_name\n },\n address: {\n country_code: document.querySelector('#billing_country') ? document.querySelector('#billing_country').value : payer.address.country_code,\n address_line_1: document.querySelector('#billing_address_1') ? document.querySelector('#billing_address_1').value : payer.address.address_line_1,\n address_line_2: document.querySelector('#billing_address_2') ? document.querySelector('#billing_address_2').value : payer.address.address_line_2,\n admin_area_1: document.querySelector('#billing_state') ? document.querySelector('#billing_state').value : payer.address.admin_area_1,\n admin_area_2: document.querySelector('#billing_city') ? document.querySelector('#billing_city').value : payer.address.admin_area_2,\n postal_code: document.querySelector('#billing_postcode') ? document.querySelector('#billing_postcode').value : payer.address.postal_code\n }\n };\n\n if (phone) {\n payerData.phone = phone;\n }\n\n return payerData;\n};\n;// CONCATENATED MODULE: ./resources/js/modules/ActionHandler/CartActionHandler.js\n\n\n\nclass CartActionHandler {\n constructor(config, errorHandler) {\n this.config = config;\n this.errorHandler = errorHandler;\n }\n\n configuration() {\n const createOrder = (data, actions) => {\n const payer = payerData();\n const bnCode = typeof this.config.bn_codes[this.config.context] !== 'undefined' ? this.config.bn_codes[this.config.context] : '';\n return fetch(this.config.ajax.create_order.endpoint, {\n method: 'POST',\n body: JSON.stringify({\n nonce: this.config.ajax.create_order.nonce,\n purchase_units: [],\n bn_code: bnCode,\n payer,\n context: this.config.context\n })\n }).then(function (res) {\n return res.json();\n }).then(function (data) {\n if (!data.success) {\n console.error(data);\n throw Error(data.data.message);\n }\n\n return data.data.id;\n });\n };\n\n return {\n createOrder,\n onApprove: onApproveForContinue(this, this.errorHandler),\n onError: error => {\n this.errorHandler.genericError();\n }\n };\n }\n\n}\n\n/* harmony default export */ const ActionHandler_CartActionHandler = (CartActionHandler);\n;// CONCATENATED MODULE: ./resources/js/modules/ContextBootstrap/MiniCartBootstap.js\n\n\n\nclass MiniCartBootstap {\n constructor(gateway, renderer) {\n this.gateway = gateway;\n this.renderer = renderer;\n this.actionHandler = null;\n }\n\n init() {\n this.actionHandler = new ActionHandler_CartActionHandler(PayPalCommerceGateway, new modules_ErrorHandler(this.gateway.labels.error.generic));\n this.render();\n jQuery(document.body).on('wc_fragments_loaded wc_fragments_refreshed', () => {\n this.render();\n });\n }\n\n shouldRender() {\n return document.querySelector(this.gateway.button.mini_cart_wrapper) !== null || document.querySelector(this.gateway.hosted_fields.mini_cart_wrapper) !== null;\n }\n\n render() {\n if (!this.shouldRender()) {\n return;\n }\n\n this.renderer.render(this.gateway.button.mini_cart_wrapper, this.gateway.hosted_fields.mini_cart_wrapper, this.actionHandler.configuration());\n }\n\n}\n\n/* harmony default export */ const ContextBootstrap_MiniCartBootstap = (MiniCartBootstap);\n;// CONCATENATED MODULE: ./resources/js/modules/Helper/UpdateCart.js\n\n\nclass UpdateCart {\n constructor(endpoint, nonce) {\n this.endpoint = endpoint;\n this.nonce = nonce;\n }\n /**\n *\n * @param onResolve\n * @param {Product[]} products\n * @returns {Promise<unknown>}\n */\n\n\n update(onResolve, products) {\n return new Promise((resolve, reject) => {\n fetch(this.endpoint, {\n method: 'POST',\n body: JSON.stringify({\n nonce: this.nonce,\n products\n })\n }).then(result => {\n return result.json();\n }).then(result => {\n if (!result.success) {\n reject(result.data);\n return;\n }\n\n const resolved = onResolve(result.data);\n resolve(resolved);\n });\n });\n }\n\n}\n\n/* harmony default export */ const Helper_UpdateCart = (UpdateCart);\n;// CONCATENATED MODULE: ./resources/js/modules/Helper/ButtonsToggleListener.js\n/**\n * When you can't add something to the cart, the PayPal buttons should not show.\n * Therefore we listen for changes on the add to cart button and show/hide the buttons accordingly.\n */\nclass ButtonsToggleListener {\n constructor(element, showCallback, hideCallback) {\n this.element = element;\n this.showCallback = showCallback;\n this.hideCallback = hideCallback;\n this.observer = null;\n }\n\n init() {\n const config = {\n attributes: true\n };\n\n const callback = () => {\n if (this.element.classList.contains('disabled')) {\n this.hideCallback();\n return;\n }\n\n this.showCallback();\n };\n\n this.observer = new MutationObserver(callback);\n this.observer.observe(this.element, config);\n callback();\n }\n\n disconnect() {\n this.observer.disconnect();\n }\n\n}\n\n/* harmony default export */ const Helper_ButtonsToggleListener = (ButtonsToggleListener);\n;// CONCATENATED MODULE: ./resources/js/modules/Entity/Product.js\nclass Product {\n constructor(id, quantity, variations) {\n this.id = id;\n this.quantity = quantity;\n this.variations = variations;\n }\n\n data() {\n return {\n id: this.id,\n quantity: this.quantity,\n variations: this.variations\n };\n }\n\n}\n\n/* harmony default export */ const Entity_Product = (Product);\n;// CONCATENATED MODULE: ./resources/js/modules/ActionHandler/SingleProductActionHandler.js\n\n\n\n\n\nclass SingleProductActionHandler {\n constructor(config, updateCart, showButtonCallback, hideButtonCallback, formElement, errorHandler) {\n this.config = config;\n this.updateCart = updateCart;\n this.showButtonCallback = showButtonCallback;\n this.hideButtonCallback = hideButtonCallback;\n this.formElement = formElement;\n this.errorHandler = errorHandler;\n }\n\n configuration() {\n if (this.hasVariations()) {\n const observer = new Helper_ButtonsToggleListener(this.formElement.querySelector('.single_add_to_cart_button'), this.showButtonCallback, this.hideButtonCallback);\n observer.init();\n }\n\n return {\n createOrder: this.createOrder(),\n onApprove: onApproveForContinue(this, this.errorHandler),\n onError: error => {\n this.errorHandler.genericError();\n }\n };\n }\n\n createOrder() {\n var getProducts = null;\n\n if (!this.isGroupedProduct()) {\n getProducts = () => {\n const id = document.querySelector('[name=\"add-to-cart\"]').value;\n const qty = document.querySelector('[name=\"quantity\"]').value;\n const variations = this.variations();\n return [new Entity_Product(id, qty, variations)];\n };\n } else {\n getProducts = () => {\n const products = [];\n this.formElement.querySelectorAll('input[type=\"number\"]').forEach(element => {\n if (!element.value) {\n return;\n }\n\n const elementName = element.getAttribute('name').match(/quantity\\[([\\d]*)\\]/);\n\n if (elementName.length !== 2) {\n return;\n }\n\n const id = parseInt(elementName[1]);\n const quantity = parseInt(element.value);\n products.push(new Entity_Product(id, quantity, null));\n });\n return products;\n };\n }\n\n const createOrder = (data, actions) => {\n this.errorHandler.clear();\n\n const onResolve = purchase_units => {\n const payer = payerData();\n const bnCode = typeof this.config.bn_codes[this.config.context] !== 'undefined' ? this.config.bn_codes[this.config.context] : '';\n return fetch(this.config.ajax.create_order.endpoint, {\n method: 'POST',\n body: JSON.stringify({\n nonce: this.config.ajax.create_order.nonce,\n purchase_units,\n payer,\n bn_code: bnCode,\n context: this.config.context\n })\n }).then(function (res) {\n return res.json();\n }).then(function (data) {\n if (!data.success) {\n console.error(data);\n throw Error(data.data.message);\n }\n\n return data.data.id;\n });\n };\n\n const promise = this.updateCart.update(onResolve, getProducts());\n return promise;\n };\n\n return createOrder;\n }\n\n variations() {\n if (!this.hasVariations()) {\n return null;\n }\n\n const attributes = [...this.formElement.querySelectorAll(\"[name^='attribute_']\")].map(element => {\n return {\n value: element.value,\n name: element.name\n };\n });\n return attributes;\n }\n\n hasVariations() {\n return this.formElement.classList.contains('variations_form');\n }\n\n isGroupedProduct() {\n return this.formElement.classList.contains('grouped_form');\n }\n\n}\n\n/* harmony default export */ const ActionHandler_SingleProductActionHandler = (SingleProductActionHandler);\n;// CONCATENATED MODULE: ./resources/js/modules/ContextBootstrap/SingleProductBootstap.js\n\n\n\n\nclass SingleProductBootstap {\n constructor(gateway, renderer, messages) {\n this.gateway = gateway;\n this.renderer = renderer;\n this.messages = messages;\n }\n\n init() {\n if (!this.shouldRender()) {\n this.renderer.hideButtons(this.gateway.hosted_fields.wrapper);\n return;\n }\n\n this.render();\n }\n\n shouldRender() {\n if (document.querySelector('form.cart') === null) {\n return false;\n }\n\n return true;\n }\n\n render() {\n const actionHandler = new ActionHandler_SingleProductActionHandler(this.gateway, new Helper_UpdateCart(this.gateway.ajax.change_cart.endpoint, this.gateway.ajax.change_cart.nonce), () => {\n this.renderer.showButtons(this.gateway.button.wrapper);\n this.renderer.showButtons(this.gateway.hosted_fields.wrapper);\n let priceText = \"0\";\n\n if (document.querySelector('form.cart ins .woocommerce-Price-amount')) {\n priceText = document.querySelector('form.cart ins .woocommerce-Price-amount').innerText;\n } else if (document.querySelector('form.cart .woocommerce-Price-amount')) {\n priceText = document.querySelector('form.cart .woocommerce-Price-amount').innerText;\n }\n\n const amount = parseInt(priceText.replace(/([^\\d,\\.\\s]*)/g, ''));\n this.messages.renderWithAmount(amount);\n }, () => {\n this.renderer.hideButtons(this.gateway.button.wrapper);\n this.renderer.hideButtons(this.gateway.hosted_fields.wrapper);\n }, document.querySelector('form.cart'), new modules_ErrorHandler(this.gateway.labels.error.generic));\n this.renderer.render(this.gateway.button.wrapper, this.gateway.hosted_fields.wrapper, actionHandler.configuration());\n }\n\n}\n\n/* harmony default export */ const ContextBootstrap_SingleProductBootstap = (SingleProductBootstap);\n;// CONCATENATED MODULE: ./resources/js/modules/ContextBootstrap/CartBootstap.js\n\n\n\nclass CartBootstrap {\n constructor(gateway, renderer) {\n this.gateway = gateway;\n this.renderer = renderer;\n }\n\n init() {\n if (!this.shouldRender()) {\n return;\n }\n\n this.render();\n jQuery(document.body).on('updated_cart_totals updated_checkout', () => {\n this.render();\n });\n }\n\n shouldRender() {\n return document.querySelector(this.gateway.button.wrapper) !== null || document.querySelector(this.gateway.hosted_fields.wrapper) !== null;\n }\n\n render() {\n const actionHandler = new ActionHandler_CartActionHandler(PayPalCommerceGateway, new modules_ErrorHandler(this.gateway.labels.error.generic));\n this.renderer.render(this.gateway.button.wrapper, this.gateway.hosted_fields.wrapper, actionHandler.configuration());\n }\n\n}\n\n/* harmony default export */ const CartBootstap = (CartBootstrap);\n;// CONCATENATED MODULE: ./resources/js/modules/OnApproveHandler/onApproveForPayNow.js\nconst onApproveForPayNow_onApprove = (context, errorHandler, spinner) => {\n return (data, actions) => {\n spinner.block();\n return fetch(context.config.ajax.approve_order.endpoint, {\n method: 'POST',\n body: JSON.stringify({\n nonce: context.config.ajax.approve_order.nonce,\n order_id: data.orderID\n })\n }).then(res => {\n return res.json();\n }).then(data => {\n spinner.unblock();\n\n if (!data.success) {\n if (data.data.code === 100) {\n errorHandler.message(data.data.message);\n } else {\n errorHandler.genericError();\n }\n\n if (typeof actions !== 'undefined' && typeof actions.restart !== 'undefined') {\n return actions.restart();\n }\n\n throw new Error(data.data.message);\n }\n\n document.querySelector('#place_order').click();\n });\n };\n};\n\n/* harmony default export */ const onApproveForPayNow = (onApproveForPayNow_onApprove);\n;// CONCATENATED MODULE: ./resources/js/modules/ActionHandler/CheckoutActionHandler.js\n\n\n\nclass CheckoutActionHandler {\n constructor(config, errorHandler, spinner) {\n this.config = config;\n this.errorHandler = errorHandler;\n this.spinner = spinner;\n }\n\n configuration() {\n const spinner = this.spinner;\n\n const createOrder = (data, actions) => {\n const payer = payerData();\n const bnCode = typeof this.config.bn_codes[this.config.context] !== 'undefined' ? this.config.bn_codes[this.config.context] : '';\n const errorHandler = this.errorHandler;\n const formSelector = this.config.context === 'checkout' ? 'form.checkout' : 'form#order_review';\n const formValues = jQuery(formSelector).serialize();\n const createaccount = jQuery('#createaccount').is(\":checked\") ? true : false;\n return fetch(this.config.ajax.create_order.endpoint, {\n method: 'POST',\n body: JSON.stringify({\n nonce: this.config.ajax.create_order.nonce,\n payer,\n bn_code: bnCode,\n context: this.config.context,\n order_id: this.config.order_id,\n form: formValues,\n createaccount: createaccount\n })\n }).then(function (res) {\n return res.json();\n }).then(function (data) {\n if (!data.success) {\n spinner.unblock(); //handle both messages sent from Woocommerce (data.messages) and this plugin (data.data.message)\n\n if (typeof data.messages !== 'undefined') {\n const domParser = new DOMParser();\n errorHandler.appendPreparedErrorMessageElement(domParser.parseFromString(data.messages, 'text/html').querySelector('ul'));\n } else {\n errorHandler.message(data.data.message, true);\n }\n\n return;\n }\n\n const input = document.createElement('input');\n input.setAttribute('type', 'hidden');\n input.setAttribute('name', 'ppcp-resume-order');\n input.setAttribute('value', data.data.purchase_units[0].custom_id);\n document.querySelector(formSelector).append(input);\n return data.data.id;\n });\n };\n\n return {\n createOrder,\n onApprove: onApproveForPayNow(this, this.errorHandler, this.spinner),\n onCancel: () => {\n spinner.unblock();\n },\n onError: () => {\n this.errorHandler.genericError();\n spinner.unblock();\n }\n };\n }\n\n}\n\n/* harmony default export */ const ActionHandler_CheckoutActionHandler = (CheckoutActionHandler);\n;// CONCATENATED MODULE: ./resources/js/modules/ContextBootstrap/CheckoutBootstap.js\n\n\n\nclass CheckoutBootstap {\n constructor(gateway, renderer, messages, spinner) {\n this.gateway = gateway;\n this.renderer = renderer;\n this.messages = messages;\n this.spinner = spinner;\n }\n\n init() {\n this.render();\n jQuery(document.body).on('updated_checkout', () => {\n this.render();\n });\n jQuery(document.body).on('updated_checkout payment_method_selected', () => {\n this.switchBetweenPayPalandOrderButton();\n this.displayPlaceOrderButtonForSavedCreditCards();\n });\n jQuery(document).on('hosted_fields_loaded', () => {\n jQuery('#saved-credit-card').on('change', () => {\n this.displayPlaceOrderButtonForSavedCreditCards();\n });\n });\n this.switchBetweenPayPalandOrderButton();\n this.displayPlaceOrderButtonForSavedCreditCards();\n }\n\n shouldRender() {\n if (document.querySelector(this.gateway.button.cancel_wrapper)) {\n return false;\n }\n\n return document.querySelector(this.gateway.button.wrapper) !== null || document.querySelector(this.gateway.hosted_fields.wrapper) !== null;\n }\n\n render() {\n if (!this.shouldRender()) {\n return;\n }\n\n if (document.querySelector(this.gateway.hosted_fields.wrapper + '>div')) {\n document.querySelector(this.gateway.hosted_fields.wrapper + '>div').setAttribute('style', '');\n }\n\n const actionHandler = new ActionHandler_CheckoutActionHandler(PayPalCommerceGateway, new modules_ErrorHandler(this.gateway.labels.error.generic), this.spinner);\n this.renderer.render(this.gateway.button.wrapper, this.gateway.hosted_fields.wrapper, actionHandler.configuration());\n }\n\n switchBetweenPayPalandOrderButton() {\n jQuery('#saved-credit-card').val(jQuery('#saved-credit-card option:first').val());\n const currentPaymentMethod = jQuery('input[name=\"payment_method\"]:checked').val();\n\n if (currentPaymentMethod !== 'ppcp-gateway' && currentPaymentMethod !== 'ppcp-credit-card-gateway') {\n this.renderer.hideButtons(this.gateway.button.wrapper);\n this.renderer.hideButtons(this.gateway.messages.wrapper);\n this.renderer.hideButtons(this.gateway.hosted_fields.wrapper);\n jQuery('#place_order').show();\n } else {\n jQuery('#place_order').hide();\n\n if (currentPaymentMethod === 'ppcp-gateway') {\n this.renderer.showButtons(this.gateway.button.wrapper);\n this.renderer.showButtons(this.gateway.messages.wrapper);\n this.messages.render();\n this.renderer.hideButtons(this.gateway.hosted_fields.wrapper);\n }\n\n if (currentPaymentMethod === 'ppcp-credit-card-gateway') {\n this.renderer.hideButtons(this.gateway.button.wrapper);\n this.renderer.hideButtons(this.gateway.messages.wrapper);\n this.renderer.showButtons(this.gateway.hosted_fields.wrapper);\n }\n }\n }\n\n displayPlaceOrderButtonForSavedCreditCards() {\n const currentPaymentMethod = jQuery('input[name=\"payment_method\"]:checked').val();\n\n if (currentPaymentMethod !== 'ppcp-credit-card-gateway') {\n return;\n }\n\n if (jQuery('#saved-credit-card').length && jQuery('#saved-credit-card').val() !== '') {\n this.renderer.hideButtons(this.gateway.button.wrapper);\n this.renderer.hideButtons(this.gateway.messages.wrapper);\n this.renderer.hideButtons(this.gateway.hosted_fields.wrapper);\n jQuery('#place_order').show();\n this.disableCreditCardFields();\n } else {\n jQuery('#place_order').hide();\n this.renderer.hideButtons(this.gateway.button.wrapper);\n this.renderer.hideButtons(this.gateway.messages.wrapper);\n this.renderer.showButtons(this.gateway.hosted_fields.wrapper);\n this.enableCreditCardFields();\n }\n }\n\n disableCreditCardFields() {\n jQuery('label[for=\"ppcp-credit-card-gateway-card-number\"]').addClass('ppcp-credit-card-gateway-form-field-disabled');\n jQuery('#ppcp-credit-card-gateway-card-number').addClass('ppcp-credit-card-gateway-form-field-disabled');\n jQuery('label[for=\"ppcp-credit-card-gateway-card-expiry\"]').addClass('ppcp-credit-card-gateway-form-field-disabled');\n jQuery('#ppcp-credit-card-gateway-card-expiry').addClass('ppcp-credit-card-gateway-form-field-disabled');\n jQuery('label[for=\"ppcp-credit-card-gateway-card-cvc\"]').addClass('ppcp-credit-card-gateway-form-field-disabled');\n jQuery('#ppcp-credit-card-gateway-card-cvc').addClass('ppcp-credit-card-gateway-form-field-disabled');\n jQuery('label[for=\"vault\"]').addClass('ppcp-credit-card-gateway-form-field-disabled');\n jQuery('#ppcp-credit-card-vault').addClass('ppcp-credit-card-gateway-form-field-disabled');\n jQuery('#ppcp-credit-card-vault').attr(\"disabled\", true);\n this.renderer.disableCreditCardFields();\n }\n\n enableCreditCardFields() {\n jQuery('label[for=\"ppcp-credit-card-gateway-card-number\"]').removeClass('ppcp-credit-card-gateway-form-field-disabled');\n jQuery('#ppcp-credit-card-gateway-card-number').removeClass('ppcp-credit-card-gateway-form-field-disabled');\n jQuery('label[for=\"ppcp-credit-card-gateway-card-expiry\"]').removeClass('ppcp-credit-card-gateway-form-field-disabled');\n jQuery('#ppcp-credit-card-gateway-card-expiry').removeClass('ppcp-credit-card-gateway-form-field-disabled');\n jQuery('label[for=\"ppcp-credit-card-gateway-card-cvc\"]').removeClass('ppcp-credit-card-gateway-form-field-disabled');\n jQuery('#ppcp-credit-card-gateway-card-cvc').removeClass('ppcp-credit-card-gateway-form-field-disabled');\n jQuery('label[for=\"vault\"]').removeClass('ppcp-credit-card-gateway-form-field-disabled');\n jQuery('#ppcp-credit-card-vault').removeClass('ppcp-credit-card-gateway-form-field-disabled');\n jQuery('#ppcp-credit-card-vault').attr(\"disabled\", false);\n this.renderer.enableCreditCardFields();\n }\n\n}\n\n/* harmony default export */ const ContextBootstrap_CheckoutBootstap = (CheckoutBootstap);\n;// CONCATENATED MODULE: ./resources/js/modules/ContextBootstrap/PayNowBootstrap.js\n\n\n\nclass PayNowBootstrap {\n constructor(gateway, renderer, messages, spinner) {\n this.gateway = gateway;\n this.renderer = renderer;\n this.messages = messages;\n this.spinner = spinner;\n }\n\n init() {\n this.render();\n jQuery(document.body).on('updated_checkout', () => {\n this.render();\n });\n jQuery(document.body).on('updated_checkout payment_method_selected', () => {\n this.switchBetweenPayPalandOrderButton();\n });\n this.switchBetweenPayPalandOrderButton();\n }\n\n shouldRender() {\n if (document.querySelector(this.gateway.button.cancel_wrapper)) {\n return false;\n }\n\n return document.querySelector(this.gateway.button.wrapper) !== null || document.querySelector(this.gateway.hosted_fields.wrapper) !== null;\n }\n\n render() {\n if (!this.shouldRender()) {\n return;\n }\n\n if (document.querySelector(this.gateway.hosted_fields.wrapper + '>div')) {\n document.querySelector(this.gateway.hosted_fields.wrapper + '>div').setAttribute('style', '');\n }\n\n const actionHandler = new ActionHandler_CheckoutActionHandler(PayPalCommerceGateway, new modules_ErrorHandler(this.gateway.labels.error.generic), this.spinner);\n this.renderer.render(this.gateway.button.wrapper, this.gateway.hosted_fields.wrapper, actionHandler.configuration());\n }\n\n switchBetweenPayPalandOrderButton() {\n const urlParams = new URLSearchParams(window.location.search);\n\n if (urlParams.has('change_payment_method')) {\n return;\n }\n\n const currentPaymentMethod = jQuery('input[name=\"payment_method\"]:checked').val();\n\n if (currentPaymentMethod !== 'ppcp-gateway' && currentPaymentMethod !== 'ppcp-credit-card-gateway') {\n this.renderer.hideButtons(this.gateway.button.wrapper);\n this.renderer.hideButtons(this.gateway.messages.wrapper);\n this.renderer.hideButtons(this.gateway.hosted_fields.wrapper);\n jQuery('#place_order').show();\n } else {\n jQuery('#place_order').hide();\n\n if (currentPaymentMethod === 'ppcp-gateway') {\n this.renderer.showButtons(this.gateway.button.wrapper);\n this.renderer.showButtons(this.gateway.messages.wrapper);\n this.messages.render();\n this.renderer.hideButtons(this.gateway.hosted_fields.wrapper);\n }\n\n if (currentPaymentMethod === 'ppcp-credit-card-gateway') {\n this.renderer.hideButtons(this.gateway.button.wrapper);\n this.renderer.hideButtons(this.gateway.messages.wrapper);\n this.renderer.showButtons(this.gateway.hosted_fields.wrapper);\n }\n }\n }\n\n}\n\n/* harmony default export */ const ContextBootstrap_PayNowBootstrap = (PayNowBootstrap);\n;// CONCATENATED MODULE: ./resources/js/modules/Renderer/Renderer.js\nclass Renderer {\n constructor(creditCardRenderer, defaultConfig) {\n this.defaultConfig = defaultConfig;\n this.creditCardRenderer = creditCardRenderer;\n }\n\n render(wrapper, hostedFieldsWrapper, contextConfig) {\n this.renderButtons(wrapper, contextConfig);\n this.creditCardRenderer.render(hostedFieldsWrapper, contextConfig);\n }\n\n renderButtons(wrapper, contextConfig) {\n if (!document.querySelector(wrapper) || this.isAlreadyRendered(wrapper) || 'undefined' === typeof paypal.Buttons) {\n return;\n }\n\n const style = wrapper === this.defaultConfig.button.wrapper ? this.defaultConfig.button.style : this.defaultConfig.button.mini_cart_style;\n paypal.Buttons({\n style,\n ...contextConfig\n }).render(wrapper);\n }\n\n isAlreadyRendered(wrapper) {\n return document.querySelector(wrapper).hasChildNodes();\n }\n\n hideButtons(element) {\n const domElement = document.querySelector(element);\n\n if (!domElement) {\n return false;\n }\n\n domElement.style.display = 'none';\n return true;\n }\n\n showButtons(element) {\n const domElement = document.querySelector(element);\n\n if (!domElement) {\n return false;\n }\n\n domElement.style.display = 'block';\n return true;\n }\n\n disableCreditCardFields() {\n this.creditCardRenderer.disableFields();\n }\n\n enableCreditCardFields() {\n this.creditCardRenderer.enableFields();\n }\n\n}\n\n/* harmony default export */ const Renderer_Renderer = (Renderer);\n;// CONCATENATED MODULE: ./resources/js/modules/Helper/DccInputFactory.js\nconst dccInputFactory = original => {\n const styles = window.getComputedStyle(original);\n const newElement = document.createElement('span');\n newElement.setAttribute('id', original.id);\n Object.values(styles).forEach(prop => {\n if (!styles[prop] || !isNaN(prop)) {\n return;\n }\n\n newElement.style.setProperty(prop, '' + styles[prop]);\n });\n return newElement;\n};\n\n/* harmony default export */ const DccInputFactory = (dccInputFactory);\n;// CONCATENATED MODULE: ./resources/js/modules/Renderer/CreditCardRenderer.js\n\n\nclass CreditCardRenderer {\n constructor(defaultConfig, errorHandler, spinner) {\n this.defaultConfig = defaultConfig;\n this.errorHandler = errorHandler;\n this.spinner = spinner;\n this.cardValid = false;\n this.formValid = false;\n this.currentHostedFieldsInstance = null;\n this.formSubmissionSubscribed = false;\n }\n\n render(wrapper, contextConfig) {\n if (this.defaultConfig.context !== 'checkout' && this.defaultConfig.context !== 'pay-now' || wrapper === null || document.querySelector(wrapper) === null) {\n return;\n }\n\n if (typeof paypal.HostedFields === 'undefined' || !paypal.HostedFields.isEligible()) {\n const wrapperElement = document.querySelector(wrapper);\n wrapperElement.parentNode.removeChild(wrapperElement);\n return;\n }\n\n if (this.currentHostedFieldsInstance) {\n this.currentHostedFieldsInstance.teardown().catch(err => console.error(`Hosted fields teardown error: ${err}`));\n this.currentHostedFieldsInstance = null;\n }\n\n const gateWayBox = document.querySelector('.payment_box.payment_method_ppcp-credit-card-gateway');\n const oldDisplayStyle = gateWayBox.style.display;\n gateWayBox.style.display = 'block';\n const hideDccGateway = document.querySelector('#ppcp-hide-dcc');\n\n if (hideDccGateway) {\n hideDccGateway.parentNode.removeChild(hideDccGateway);\n }\n\n const cardNumberField = document.querySelector('#ppcp-credit-card-gateway-card-number');\n const stylesRaw = window.getComputedStyle(cardNumberField);\n let styles = {};\n Object.values(stylesRaw).forEach(prop => {\n if (!stylesRaw[prop]) {\n return;\n }\n\n styles[prop] = '' + stylesRaw[prop];\n });\n const cardNumber = DccInputFactory(cardNumberField);\n cardNumberField.parentNode.replaceChild(cardNumber, cardNumberField);\n const cardExpiryField = document.querySelector('#ppcp-credit-card-gateway-card-expiry');\n const cardExpiry = DccInputFactory(cardExpiryField);\n cardExpiryField.parentNode.replaceChild(cardExpiry, cardExpiryField);\n const cardCodeField = document.querySelector('#ppcp-credit-card-gateway-card-cvc');\n const cardCode = DccInputFactory(cardCodeField);\n cardCodeField.parentNode.replaceChild(cardCode, cardCodeField);\n gateWayBox.style.display = oldDisplayStyle;\n const formWrapper = '.payment_box payment_method_ppcp-credit-card-gateway';\n\n if (this.defaultConfig.enforce_vault && document.querySelector(formWrapper + ' .ppcp-credit-card-vault')) {\n document.querySelector(formWrapper + ' .ppcp-credit-card-vault').checked = true;\n document.querySelector(formWrapper + ' .ppcp-credit-card-vault').setAttribute('disabled', true);\n }\n\n paypal.HostedFields.render({\n createOrder: contextConfig.createOrder,\n styles: {\n 'input': styles\n },\n fields: {\n number: {\n selector: '#ppcp-credit-card-gateway-card-number',\n placeholder: this.defaultConfig.hosted_fields.labels.credit_card_number\n },\n cvv: {\n selector: '#ppcp-credit-card-gateway-card-cvc',\n placeholder: this.defaultConfig.hosted_fields.labels.cvv\n },\n expirationDate: {\n selector: '#ppcp-credit-card-gateway-card-expiry',\n placeholder: this.defaultConfig.hosted_fields.labels.mm_yy\n }\n }\n }).then(hostedFields => {\n document.dispatchEvent(new CustomEvent(\"hosted_fields_loaded\"));\n this.currentHostedFieldsInstance = hostedFields;\n hostedFields.on('inputSubmitRequest', () => {\n this._submit(contextConfig);\n });\n hostedFields.on('cardTypeChange', event => {\n if (!event.cards.length) {\n this.cardValid = false;\n return;\n }\n\n const validCards = this.defaultConfig.hosted_fields.valid_cards;\n this.cardValid = validCards.indexOf(event.cards[0].type) !== -1;\n });\n hostedFields.on('validityChange', event => {\n const formValid = Object.keys(event.fields).every(function (key) {\n return event.fields[key].isValid;\n });\n this.formValid = formValid;\n });\n\n if (!this.formSubmissionSubscribed) {\n document.querySelector(wrapper + ' button').addEventListener('click', event => {\n event.preventDefault();\n\n this._submit(contextConfig);\n });\n this.formSubmissionSubscribed = true;\n }\n });\n document.querySelector('#payment_method_ppcp-credit-card-gateway').addEventListener('click', () => {\n document.querySelector('label[for=ppcp-credit-card-gateway-card-number]').click();\n });\n }\n\n disableFields() {\n if (this.currentHostedFieldsInstance) {\n this.currentHostedFieldsInstance.setAttribute({\n field: 'number',\n attribute: 'disabled'\n });\n this.currentHostedFieldsInstance.setAttribute({\n field: 'cvv',\n attribute: 'disabled'\n });\n this.currentHostedFieldsInstance.setAttribute({\n field: 'expirationDate',\n attribute: 'disabled'\n });\n }\n }\n\n enableFields() {\n if (this.currentHostedFieldsInstance) {\n this.currentHostedFieldsInstance.removeAttribute({\n field: 'number',\n attribute: 'disabled'\n });\n this.currentHostedFieldsInstance.removeAttribute({\n field: 'cvv',\n attribute: 'disabled'\n });\n this.currentHostedFieldsInstance.removeAttribute({\n field: 'expirationDate',\n attribute: 'disabled'\n });\n }\n }\n\n _submit(contextConfig) {\n this.spinner.block();\n this.errorHandler.clear();\n\n if (this.formValid && this.cardValid) {\n const save_card = this.defaultConfig.save_card ? true : false;\n let vault = document.getElementById('ppcp-credit-card-vault') ? document.getElementById('ppcp-credit-card-vault').checked : save_card;\n\n if (this.defaultConfig.enforce_vault) {\n vault = true;\n }\n\n const contingency = this.defaultConfig.hosted_fields.contingency;\n const hostedFieldsData = {\n vault: vault\n };\n\n if (contingency !== 'NO_3D_SECURE') {\n hostedFieldsData.contingencies = [contingency];\n }\n\n this.currentHostedFieldsInstance.submit(hostedFieldsData).then(payload => {\n payload.orderID = payload.orderId;\n this.spinner.unblock();\n return contextConfig.onApprove(payload);\n }).catch(err => {\n console.error(err);\n this.spinner.unblock();\n });\n } else {\n this.spinner.unblock();\n const message = !this.cardValid ? this.defaultConfig.hosted_fields.labels.card_not_supported : this.defaultConfig.hosted_fields.labels.fields_not_valid;\n this.errorHandler.message(message);\n }\n }\n\n}\n\n/* harmony default export */ const Renderer_CreditCardRenderer = (CreditCardRenderer);\n;// CONCATENATED MODULE: ./resources/js/modules/DataClientIdAttributeHandler.js\nconst storageKey = 'ppcp-data-client-id';\n\nconst validateToken = (token, user) => {\n if (!token) {\n return false;\n }\n\n if (token.user !== user) {\n return false;\n }\n\n const currentTime = new Date().getTime();\n const isExpired = currentTime >= token.expiration * 1000;\n return !isExpired;\n};\n\nconst storedTokenForUser = user => {\n const token = JSON.parse(sessionStorage.getItem(storageKey));\n\n if (validateToken(token, user)) {\n return token.token;\n }\n\n return null;\n};\n\nconst storeToken = token => {\n sessionStorage.setItem(storageKey, JSON.stringify(token));\n};\n\nconst dataClientIdAttributeHandler = (script, config) => {\n fetch(config.endpoint, {\n method: 'POST',\n body: JSON.stringify({\n nonce: config.nonce\n })\n }).then(res => {\n return res.json();\n }).then(data => {\n const isValid = validateToken(data, config.user);\n\n if (!isValid) {\n return;\n }\n\n storeToken(data);\n script.setAttribute('data-client-token', data.token);\n document.body.append(script);\n });\n};\n\n/* harmony default export */ const DataClientIdAttributeHandler = (dataClientIdAttributeHandler);\n;// CONCATENATED MODULE: ./resources/js/modules/Renderer/MessageRenderer.js\nclass MessageRenderer {\n constructor(config) {\n this.config = config;\n }\n\n render() {\n if (!this.shouldRender()) {\n return;\n }\n\n paypal.Messages({\n amount: this.config.amount,\n placement: this.config.placement,\n style: this.config.style\n }).render(this.config.wrapper);\n }\n\n renderWithAmount(amount) {\n if (!this.shouldRender()) {\n return;\n }\n\n const newWrapper = document.createElement('div');\n newWrapper.setAttribute('id', this.config.wrapper.replace('#', ''));\n const sibling = document.querySelector(this.config.wrapper).nextSibling;\n document.querySelector(this.config.wrapper).parentElement.removeChild(document.querySelector(this.config.wrapper));\n sibling.parentElement.insertBefore(newWrapper, sibling);\n paypal.Messages({\n amount,\n placement: this.config.placement,\n style: this.config.style\n }).render(this.config.wrapper);\n }\n\n shouldRender() {\n if (typeof paypal.Messages === 'undefined' || typeof this.config.wrapper === 'undefined') {\n return false;\n }\n\n if (!document.querySelector(this.config.wrapper)) {\n return false;\n }\n\n return true;\n }\n\n}\n\n/* harmony default export */ const Renderer_MessageRenderer = (MessageRenderer);\n;// CONCATENATED MODULE: ./resources/js/modules/Helper/Spinner.js\nclass Spinner {\n constructor() {\n this.target = 'form.woocommerce-checkout';\n }\n\n setTarget(target) {\n this.target = target;\n }\n\n block() {\n jQuery(this.target).block({\n message: null,\n overlayCSS: {\n background: '#fff',\n opacity: 0.6\n }\n });\n }\n\n unblock() {\n jQuery(this.target).unblock();\n }\n\n}\n\n/* harmony default export */ const Helper_Spinner = (Spinner);\n;// CONCATENATED MODULE: ./resources/js/button.js\n\n\n\n\n\n\n\n\n\n\n\n\nconst bootstrap = () => {\n const errorHandler = new modules_ErrorHandler(PayPalCommerceGateway.labels.error.generic);\n const spinner = new Helper_Spinner();\n const creditCardRenderer = new Renderer_CreditCardRenderer(PayPalCommerceGateway, errorHandler, spinner);\n const renderer = new Renderer_Renderer(creditCardRenderer, PayPalCommerceGateway);\n const messageRenderer = new Renderer_MessageRenderer(PayPalCommerceGateway.messages);\n const context = PayPalCommerceGateway.context;\n\n if (context === 'mini-cart' || context === 'product') {\n if (PayPalCommerceGateway.mini_cart_buttons_enabled === '1') {\n const miniCartBootstrap = new ContextBootstrap_MiniCartBootstap(PayPalCommerceGateway, renderer);\n miniCartBootstrap.init();\n }\n }\n\n if (context === 'product' && PayPalCommerceGateway.single_product_buttons_enabled === '1') {\n const singleProductBootstrap = new ContextBootstrap_SingleProductBootstap(PayPalCommerceGateway, renderer, messageRenderer);\n singleProductBootstrap.init();\n }\n\n if (context === 'cart') {\n const cartBootstrap = new CartBootstap(PayPalCommerceGateway, renderer);\n cartBootstrap.init();\n }\n\n if (context === 'checkout') {\n const checkoutBootstap = new ContextBootstrap_CheckoutBootstap(PayPalCommerceGateway, renderer, messageRenderer, spinner);\n checkoutBootstap.init();\n }\n\n if (context === 'pay-now') {\n const payNowBootstrap = new ContextBootstrap_PayNowBootstrap(PayPalCommerceGateway, renderer, messageRenderer, spinner);\n payNowBootstrap.init();\n }\n\n if (context !== 'checkout') {\n messageRenderer.render();\n }\n};\n\ndocument.addEventListener('DOMContentLoaded', () => {\n if (!typeof PayPalCommerceGateway) {\n console.error('PayPal button could not be configured.');\n return;\n }\n\n const script = document.createElement('script');\n script.addEventListener('load', event => {\n bootstrap();\n });\n script.setAttribute('src', PayPalCommerceGateway.button.url);\n Object.entries(PayPalCommerceGateway.script_attributes).forEach(keyValue => {\n script.setAttribute(keyValue[0], keyValue[1]);\n });\n\n if (PayPalCommerceGateway.data_client_id.set_attribute) {\n DataClientIdAttributeHandler(script, PayPalCommerceGateway.data_client_id);\n return;\n }\n\n document.body.append(script);\n});//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,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LENBQUN1USxnQkFBVCxDQUNJLGtCQURKLEVBRUksTUFBTTtBQUNGLE1BQUksQ0FBQyxPQUFRek0scUJBQWIsRUFBcUM7QUFDakN3QixJQUFBQSxPQUFPLENBQUNDLEtBQVIsQ0FBYyx3Q0FBZDtBQUNBO0FBQ0g7O0FBQ0QsUUFBTWdOLE1BQU0sR0FBR3ZTLFFBQVEsQ0FBQ3dCLGFBQVQsQ0FBdUIsUUFBdkIsQ0FBZjtBQUVBK1EsRUFBQUEsTUFBTSxDQUFDaEMsZ0JBQVAsQ0FBd0IsTUFBeEIsRUFBaUNWLEtBQUQsSUFBVztBQUN2Q3lELElBQUFBLFNBQVM7QUFDWixHQUZEO0FBR0FmLEVBQUFBLE1BQU0sQ0FBQzlRLFlBQVAsQ0FBb0IsS0FBcEIsRUFBMkJxQyxxQkFBcUIsQ0FBQ3NDLE1BQXRCLENBQTZCMk4sR0FBeEQ7QUFDQTVHLEVBQUFBLE1BQU0sQ0FBQzZHLE9BQVAsQ0FBZWxRLHFCQUFxQixDQUFDbVEsaUJBQXJDLEVBQXdEMUwsT0FBeEQsQ0FDSzJMLFFBQUQsSUFBYztBQUNWM0IsSUFBQUEsTUFBTSxDQUFDOVEsWUFBUCxDQUFvQnlTLFFBQVEsQ0FBQyxDQUFELENBQTVCLEVBQWlDQSxRQUFRLENBQUMsQ0FBRCxDQUF6QztBQUNILEdBSEw7O0FBTUEsTUFBSXBRLHFCQUFxQixDQUFDcVEsY0FBdEIsQ0FBcUNDLGFBQXpDLEVBQXdEO0FBQ3BEOUIsSUFBQUEsNEJBQTRCLENBQUNDLE1BQUQsRUFBU3pPLHFCQUFxQixDQUFDcVEsY0FBL0IsQ0FBNUI7QUFDQTtBQUNIOztBQUVEblUsRUFBQUEsUUFBUSxDQUFDNEMsSUFBVCxDQUFjNkgsTUFBZCxDQUFxQjhILE1BQXJCO0FBQ0gsQ0F6QkwiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9wcGMtYnV0dG9uLy4vcmVzb3VyY2VzL2pzL21vZHVsZXMvRXJyb3JIYW5kbGVyLmpzP2U2NWEiLCJ3ZWJwYWNrOi8vcHBjLWJ1dHRvbi8uL3Jlc291cmNlcy9qcy9tb2R1bGVzL09uQXBwcm92ZUhhbmRsZXIvb25BcHByb3ZlRm9yQ29udGludWUuanM/YzQ1NCIsIndlYnBhY2s6Ly9wcGMtYnV0dG9uLy4vcmVzb3VyY2VzL2pzL21vZHVsZXMvSGVscGVyL1BheWVyRGF0YS5qcz8yYWYxIiwid2VicGFjazovL3BwYy1idXR0b24vLi9yZXNvdXJjZXMvanMvbW9kdWxlcy9BY3Rpb25IYW5kbGVyL0NhcnRBY3Rpb25IYW5kbGVyLmpzPzgyY2YiLCJ3ZWJwYWNrOi8vcHBjLWJ1dHRvbi8uL3Jlc291cmNlcy9qcy9tb2R1bGVzL0NvbnRleHRCb290c3RyYXAvTWluaUNhcnRCb290c3RhcC5qcz9kNTUyIiwid2VicGFjazovL3BwYy1idXR0b24vLi9yZXNvdXJjZXMvanMvbW9kdWxlcy9IZWxwZXIvVXBkYXRlQ2FydC5qcz9lNDIyIiwid2VicGFjazovL3BwYy1idXR0b24vLi9yZXNvdXJjZXMvanMvbW9kdWxlcy9IZWxwZXIvQnV0dG9uc1RvZ2dsZUxpc3RlbmVyLmpzP2UxOTMiLCJ3ZWJwYWNrOi8vcHBjLWJ1dHRvbi8uL3Jlc291cmNlcy9qcy9tb2R1bGVzL0VudGl0eS9Qcm9kdWN0LmpzPzlmZmYiLCJ3ZWJwYWNrOi8vcHBjLWJ1dHRvbi8uL3Jlc291cmNlcy9qcy9tb2R1bGVzL0FjdGlvbkhhbmRsZXIvU2luZ2xlUHJvZHVjdEFjdGlvbkhhbmRsZXIuanM/ZDliNyIsIndlYnBhY2s6Ly9wcGMtYnV0dG9uLy4vcmVzb3VyY2VzL2pzL21vZHVsZXMvQ29udGV4dEJvb3RzdHJhcC9TaW5nbGVQcm9kdWN0Qm9vdHN0YXAuanM/N2MxOSIsIndlYnBhY2s6Ly9wcGMtYnV0dG9uLy4vcmVzb3VyY2VzL2pzL21vZHVsZXMvQ29udGV4dEJvb3RzdHJhcC9DYXJ0Qm9vdHN0YXAuanM/NWU5NCIsIndlYnBhY2s6Ly9wcGMtYnV0dG9uLy4vcmVzb3VyY2VzL2pzL21vZHVsZXMvT25BcHByb3ZlSGFuZGxlci9vbkFwcHJvdmVGb3JQYXlOb3cuanM/OTMwNSIsIndlYnBhY2s6Ly9wcGMtYnV0dG9uLy4vcmVzb3VyY2VzL2pzL21vZHVsZXMvQWN0aW9uSGFuZGxlci9DaGVja291dEFjdGlvbkhhbmRsZXIuanM/ODUxNSIsIndlYnBhY2s6Ly9wcGMtYnV0dG9uLy4vcmVzb3VyY2VzL2pzL21vZHVsZXMvQ29udGV4dEJvb3RzdHJhcC9DaGVja291dEJvb3RzdGFwLmpzP2M4NTUiLCJ3ZWJwYWNrOi8vcHBjLWJ1dHRvbi8uL3Jlc291cmNlcy9qcy9tb2R1bGVzL0NvbnRleHRCb290c3RyYXAvUGF5Tm93Qm9vdHN0cmFwLmpzP2Q5ZjUiLCJ3ZWJwYWNrOi8vcHBjLWJ1dHRvbi8uL3Jlc291cmNlcy9qcy9tb2R1bGVzL1JlbmRlcmVyL1JlbmRlcmVyLmpzP2ZhOTMiLCJ3ZWJwYWNrOi8vcHBjLWJ1dHRvbi8uL3Jlc291cmNlcy9qcy9tb2R1bGVzL0hlbHBlci9EY2NJbnB1dEZhY3RvcnkuanM/MmEyZiIsIndlYnBhY2s6Ly9wcGMtYnV0dG9uLy4vcmVzb3VyY2VzL2pzL21vZHVsZXMvUmVuZGVyZXIvQ3JlZGl0Q2FyZFJlbmRlcmVyLmpzPzM4N2EiLCJ3ZWJwYWNrOi8vcHBjLWJ1dHRvbi8uL3Jlc291cmNlcy9qcy9tb2R1bGVzL0RhdGFDbGllbnRJZEF0dHJpYnV0ZUhhbmRsZXIuanM/ZWUwYiIsIndlYnBhY2s6Ly9wcGMtYnV0dG9uLy4vcmVzb3VyY2VzL2pzL21vZHVsZXMvUmVuZGVyZXIvTWVzc2FnZVJlbmRlcmVyLmpzP2NkMDIiLCJ3ZWJwYWNrOi8vcHBjLWJ1dHRvbi8uL3Jlc291cmNlcy9qcy9tb2R1bGVzL0hlbHBlci9TcGlubmVyLmpzPzE3MDgiLCJ3ZWJwYWNrOi8vcHBjLWJ1dHRvbi8uL3Jlc291cmNlcy9qcy9idXR0b24uanM/MDYwZiJdLCJzb3VyY2VzQ29udGVudCI6WyJjbGFzcyBFcnJvckhhbmRsZXIge1xuXG4gICAgY29uc3RydWN0b3IoZ2VuZXJpY0Vycm9yVGV4dClcbiAgICB7XG4gICAgICAgIHRoaXMuZ2VuZXJpY0Vycm9yVGV4dCA9IGdlbmVyaWNFcnJvclRleHQ7XG4gICAgICAgIHRoaXMud3JhcHBlciA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJy53b29jb21tZXJjZS1ub3RpY2VzLXdyYXBwZXInKTtcbiAgICAgICAgdGhpcy5tZXNzYWdlc0xpc3QgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCd1bC53b29jb21tZXJjZS1lcnJvcicpO1xuICAgIH1cblxuICAgIGdlbmVyaWNFcnJvcigpIHtcbiAgICAgICAgaWYgKHRoaXMud3JhcHBlci5jbGFzc0xpc3QuY29udGFpbnMoJ3BwY3AtcGVyc2lzdCcpKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5jbGVhcigpO1xuICAgICAgICB0aGlzLm1lc3NhZ2UodGhpcy5nZW5lcmljRXJyb3JUZXh0KVxuICAgIH1cblxuICAgIGFwcGVuZFByZXBhcmVkRXJyb3JNZXNzYWdlRWxlbWVudChlcnJvck1lc3NhZ2VFbGVtZW50KVxuICAgIHtcbiAgICAgICAgaWYodGhpcy5tZXNzYWdlc0xpc3QgPT09IG51bGwpIHtcbiAgICAgICAgICAgIHRoaXMucHJlcGFyZU1lc3NhZ2VzTGlzdCgpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5tZXNzYWdlc0xpc3QucmVwbGFjZVdpdGgoZXJyb3JNZXNzYWdlRWxlbWVudCk7XG4gICAgfVxuXG4gICAgbWVzc2FnZSh0ZXh0LCBwZXJzaXN0ID0gZmFsc2UpXG4gICAge1xuICAgICAgICBpZighIHR5cGVvZiBTdHJpbmcgfHwgdGV4dC5sZW5ndGggPT09IDApe1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdBIG5ldyBtZXNzYWdlIHRleHQgbXVzdCBiZSBhIG5vbi1lbXB0eSBzdHJpbmcuJyk7XG4gICAgICAgIH1cblxuICAgICAgICBpZih0aGlzLm1lc3NhZ2VzTGlzdCA9PT0gbnVsbCl7XG4gICAgICAgICAgICB0aGlzLnByZXBhcmVNZXNzYWdlc0xpc3QoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChwZXJzaXN0KSB7XG4gICAgICAgICAgICB0aGlzLndyYXBwZXIuY2xhc3NMaXN0LmFkZCgncHBjcC1wZXJzaXN0Jyk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLndyYXBwZXIuY2xhc3NMaXN0LnJlbW92ZSgncHBjcC1wZXJzaXN0Jyk7XG4gICAgICAgIH1cblxuICAgICAgICBsZXQgbWVzc2FnZU5vZGUgPSB0aGlzLnByZXBhcmVNZXNzYWdlc0xpc3RJdGVtKHRleHQpO1xuICAgICAgICB0aGlzLm1lc3NhZ2VzTGlzdC5hcHBlbmRDaGlsZChtZXNzYWdlTm9kZSk7XG5cbiAgICAgICAgalF1ZXJ5LnNjcm9sbF90b19ub3RpY2VzKGpRdWVyeSgnLndvb2NvbW1lcmNlLW5vdGljZXMtd3JhcHBlcicpKVxuICAgIH1cblxuICAgIHByZXBhcmVNZXNzYWdlc0xpc3QoKVxuICAgIHtcbiAgICAgICAgaWYodGhpcy5tZXNzYWdlc0xpc3QgPT09IG51bGwpe1xuICAgICAgICAgICAgdGhpcy5tZXNzYWdlc0xpc3QgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCd1bCcpO1xuICAgICAgICAgICAgdGhpcy5tZXNzYWdlc0xpc3Quc2V0QXR0cmlidXRlKCdjbGFzcycsICd3b29jb21tZXJjZS1lcnJvcicpO1xuICAgICAgICAgICAgdGhpcy5tZXNzYWdlc0xpc3Quc2V0QXR0cmlidXRlKCdyb2xlJywgJ2FsZXJ0Jyk7XG4gICAgICAgICAgICB0aGlzLndyYXBwZXIuYXBwZW5kQ2hpbGQodGhpcy5tZXNzYWdlc0xpc3QpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJlcGFyZU1lc3NhZ2VzTGlzdEl0ZW0obWVzc2FnZSlcbiAgICB7XG4gICAgICAgIGNvbnN0IGxpID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnbGknKTtcbiAgICAgICAgbGkuaW5uZXJIVE1MID0gbWVzc2FnZTtcblxuICAgICAgICByZXR1cm4gbGk7XG4gICAgfVxuXG4gICAgc2FuaXRpemUodGV4dClcbiAgICB7XG4gICAgICAgIGNvbnN0IHRleHRhcmVhID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgndGV4dGFyZWEnKTtcbiAgICAgICAgdGV4dGFyZWEuaW5uZXJIVE1MID0gdGV4dDtcbiAgICAgICAgcmV0dXJuIHRleHRhcmVhLnZhbHVlLnJlcGxhY2UoJ0Vycm9yOiAnLCAnJyk7XG4gICAgfVxuXG4gICAgY2xlYXIoKVxuICAgIHtcbiAgICAgICAgaWYgKCEgdGhpcy53cmFwcGVyLmNsYXNzTGlzdC5jb250YWlucygnd29vY29tbWVyY2UtZXJyb3InKSkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMud3JhcHBlci5jbGFzc0xpc3QucmVtb3ZlKCd3b29jb21tZXJjZS1lcnJvcicpO1xuICAgICAgICB0aGlzLndyYXBwZXIuaW5uZXJUZXh0ID0gJyc7XG4gICAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBFcnJvckhhbmRsZXI7XG4iLCJjb25zdCBvbkFwcHJvdmUgPSAoY29udGV4dCwgZXJyb3JIYW5kbGVyKSA9PiB7XG4gICAgcmV0dXJuIChkYXRhLCBhY3Rpb25zKSA9PiB7XG4gICAgICAgIHJldHVybiBmZXRjaChjb250ZXh0LmNvbmZpZy5hamF4LmFwcHJvdmVfb3JkZXIuZW5kcG9pbnQsIHtcbiAgICAgICAgICAgIG1ldGhvZDogJ1BPU1QnLFxuICAgICAgICAgICAgYm9keTogSlNPTi5zdHJpbmdpZnkoe1xuICAgICAgICAgICAgICAgIG5vbmNlOiBjb250ZXh0LmNvbmZpZy5hamF4LmFwcHJvdmVfb3JkZXIubm9uY2UsXG4gICAgICAgICAgICAgICAgb3JkZXJfaWQ6ZGF0YS5vcmRlcklEXG4gICAgICAgICAgICB9KVxuICAgICAgICB9KS50aGVuKChyZXMpPT57XG4gICAgICAgICAgICByZXR1cm4gcmVzLmpzb24oKTtcbiAgICAgICAgfSkudGhlbigoZGF0YSk9PntcbiAgICAgICAgICAgIGlmICghZGF0YS5zdWNjZXNzKSB7XG4gICAgICAgICAgICAgICAgZXJyb3JIYW5kbGVyLmdlbmVyaWNFcnJvcigpO1xuICAgICAgICAgICAgICAgIHJldHVybiBhY3Rpb25zLnJlc3RhcnQoKS5jYXRjaChlcnIgPT4ge1xuICAgICAgICAgICAgICAgICAgICBlcnJvckhhbmRsZXIuZ2VuZXJpY0Vycm9yKCk7XG4gICAgICAgICAgICAgICAgfSk7O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgbG9jYXRpb24uaHJlZiA9IGNvbnRleHQuY29uZmlnLnJlZGlyZWN0O1xuICAgICAgICB9KTtcblxuICAgIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgb25BcHByb3ZlO1xuIiwiZXhwb3J0IGNvbnN0IHBheWVyRGF0YSA9ICgpID0+IHtcbiAgICBjb25zdCBwYXllciA9IFBheVBhbENvbW1lcmNlR2F0ZXdheS5wYXllcjtcbiAgICBpZiAoISBwYXllcikge1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG5cbiAgICBjb25zdCBwaG9uZSA9IChkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjYmlsbGluZ19waG9uZScpIHx8IHR5cGVvZiBwYXllci5waG9uZSAhPT0gJ3VuZGVmaW5lZCcpID9cbiAgICB7XG4gICAgICAgIHBob25lX3R5cGU6XCJIT01FXCIsXG4gICAgICAgICAgICBwaG9uZV9udW1iZXI6e1xuICAgICAgICAgICAgbmF0aW9uYWxfbnVtYmVyIDogKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNiaWxsaW5nX3Bob25lJykpID8gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI2JpbGxpbmdfcGhvbmUnKS52YWx1ZSA6IHBheWVyLnBob25lLnBob25lX251bWJlci5uYXRpb25hbF9udW1iZXJcbiAgICAgICAgfVxuICAgIH0gOiBudWxsO1xuICAgIGNvbnN0IHBheWVyRGF0YSA9IHtcbiAgICAgICAgZW1haWxfYWRkcmVzczooZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI2JpbGxpbmdfZW1haWwnKSkgPyBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjYmlsbGluZ19lbWFpbCcpLnZhbHVlIDogcGF5ZXIuZW1haWxfYWRkcmVzcyxcbiAgICAgICAgbmFtZSA6IHtcbiAgICAgICAgICAgIHN1cm5hbWU6IChkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjYmlsbGluZ19sYXN0X25hbWUnKSkgPyBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjYmlsbGluZ19sYXN0X25hbWUnKS52YWx1ZSA6IHBheWVyLm5hbWUuc3VybmFtZSxcbiAgICAgICAgICAgIGdpdmVuX25hbWU6IChkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjYmlsbGluZ19maXJzdF9uYW1lJykpID8gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI2JpbGxpbmdfZmlyc3RfbmFtZScpLnZhbHVlIDogcGF5ZXIubmFtZS5naXZlbl9uYW1lXG4gICAgICAgIH0sXG4gICAgICAgIGFkZHJlc3MgOiB7XG4gICAgICAgICAgICBjb3VudHJ5X2NvZGUgOiAoZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI2JpbGxpbmdfY291bnRyeScpKSA/IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNiaWxsaW5nX2NvdW50cnknKS52YWx1ZSA6IHBheWVyLmFkZHJlc3MuY291bnRyeV9jb2RlLFxuICAgICAgICAgICAgYWRkcmVzc19saW5lXzEgOiAoZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI2JpbGxpbmdfYWRkcmVzc18xJykpID8gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI2JpbGxpbmdfYWRkcmVzc18xJykudmFsdWUgOiBwYXllci5hZGRyZXNzLmFkZHJlc3NfbGluZV8xLFxuICAgICAgICAgICAgYWRkcmVzc19saW5lXzIgOiAoZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI2JpbGxpbmdfYWRkcmVzc18yJykpID8gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI2JpbGxpbmdfYWRkcmVzc18yJykudmFsdWUgOiBwYXllci5hZGRyZXNzLmFkZHJlc3NfbGluZV8yLFxuICAgICAgICAgICAgYWRtaW5fYXJlYV8xIDogKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNiaWxsaW5nX3N0YXRlJykpID8gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI2JpbGxpbmdfc3RhdGUnKS52YWx1ZSA6IHBheWVyLmFkZHJlc3MuYWRtaW5fYXJlYV8xLFxuICAgICAgICAgICAgYWRtaW5fYXJlYV8yIDogKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNiaWxsaW5nX2NpdHknKSkgPyBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjYmlsbGluZ19jaXR5JykudmFsdWUgOiBwYXllci5hZGRyZXNzLmFkbWluX2FyZWFfMixcbiAgICAgICAgICAgIHBvc3RhbF9jb2RlIDogKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNiaWxsaW5nX3Bvc3Rjb2RlJykpID8gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI2JpbGxpbmdfcG9zdGNvZGUnKS52YWx1ZSA6IHBheWVyLmFkZHJlc3MucG9zdGFsX2NvZGVcbiAgICAgICAgfVxuICAgIH07XG5cbiAgICBpZiAocGhvbmUpIHtcbiAgICAgICAgcGF5ZXJEYXRhLnBob25lID0gcGhvbmU7XG4gICAgfVxuICAgIHJldHVybiBwYXllckRhdGE7XG59XG4iLCJpbXBvcnQgb25BcHByb3ZlIGZyb20gJy4uL09uQXBwcm92ZUhhbmRsZXIvb25BcHByb3ZlRm9yQ29udGludWUuanMnO1xuaW1wb3J0IHtwYXllckRhdGF9IGZyb20gXCIuLi9IZWxwZXIvUGF5ZXJEYXRhXCI7XG5cbmNsYXNzIENhcnRBY3Rpb25IYW5kbGVyIHtcblxuICAgIGNvbnN0cnVjdG9yKGNvbmZpZywgZXJyb3JIYW5kbGVyKSB7XG4gICAgICAgIHRoaXMuY29uZmlnID0gY29uZmlnO1xuICAgICAgICB0aGlzLmVycm9ySGFuZGxlciA9IGVycm9ySGFuZGxlcjtcbiAgICB9XG5cbiAgICBjb25maWd1cmF0aW9uKCkge1xuICAgICAgICBjb25zdCBjcmVhdGVPcmRlciA9IChkYXRhLCBhY3Rpb25zKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBwYXllciA9IHBheWVyRGF0YSgpO1xuICAgICAgICAgICAgY29uc3QgYm5Db2RlID0gdHlwZW9mIHRoaXMuY29uZmlnLmJuX2NvZGVzW3RoaXMuY29uZmlnLmNvbnRleHRdICE9PSAndW5kZWZpbmVkJyA/XG4gICAgICAgICAgICAgICAgdGhpcy5jb25maWcuYm5fY29kZXNbdGhpcy5jb25maWcuY29udGV4dF0gOiAnJztcbiAgICAgICAgICAgIHJldHVybiBmZXRjaCh0aGlzLmNvbmZpZy5hamF4LmNyZWF0ZV9vcmRlci5lbmRwb2ludCwge1xuICAgICAgICAgICAgICAgIG1ldGhvZDogJ1BPU1QnLFxuICAgICAgICAgICAgICAgIGJvZHk6IEpTT04uc3RyaW5naWZ5KHtcbiAgICAgICAgICAgICAgICAgICAgbm9uY2U6IHRoaXMuY29uZmlnLmFqYXguY3JlYXRlX29yZGVyLm5vbmNlLFxuICAgICAgICAgICAgICAgICAgICBwdXJjaGFzZV91bml0czogW10sXG4gICAgICAgICAgICAgICAgICAgIGJuX2NvZGU6Ym5Db2RlLFxuICAgICAgICAgICAgICAgICAgICBwYXllcixcbiAgICAgICAgICAgICAgICAgICAgY29udGV4dDp0aGlzLmNvbmZpZy5jb250ZXh0XG4gICAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICB9KS50aGVuKGZ1bmN0aW9uKHJlcykge1xuICAgICAgICAgICAgICAgIHJldHVybiByZXMuanNvbigpO1xuICAgICAgICAgICAgfSkudGhlbihmdW5jdGlvbihkYXRhKSB7XG4gICAgICAgICAgICAgICAgaWYgKCFkYXRhLnN1Y2Nlc3MpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihkYXRhKTtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgRXJyb3IoZGF0YS5kYXRhLm1lc3NhZ2UpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gZGF0YS5kYXRhLmlkO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH07XG5cbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGNyZWF0ZU9yZGVyLFxuICAgICAgICAgICAgb25BcHByb3ZlOiBvbkFwcHJvdmUodGhpcywgdGhpcy5lcnJvckhhbmRsZXIpLFxuICAgICAgICAgICAgb25FcnJvcjogKGVycm9yKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5lcnJvckhhbmRsZXIuZ2VuZXJpY0Vycm9yKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBDYXJ0QWN0aW9uSGFuZGxlcjtcbiIsImltcG9ydCBFcnJvckhhbmRsZXIgZnJvbSAnLi4vRXJyb3JIYW5kbGVyJztcbmltcG9ydCBDYXJ0QWN0aW9uSGFuZGxlciBmcm9tICcuLi9BY3Rpb25IYW5kbGVyL0NhcnRBY3Rpb25IYW5kbGVyJztcblxuY2xhc3MgTWluaUNhcnRCb290c3RhcCB7XG4gICAgY29uc3RydWN0b3IoZ2F0ZXdheSwgcmVuZGVyZXIpIHtcbiAgICAgICAgdGhpcy5nYXRld2F5ID0gZ2F0ZXdheTtcbiAgICAgICAgdGhpcy5yZW5kZXJlciA9IHJlbmRlcmVyO1xuICAgICAgICB0aGlzLmFjdGlvbkhhbmRsZXIgPSBudWxsO1xuICAgIH1cblxuICAgIGluaXQoKSB7XG5cbiAgICAgICAgdGhpcy5hY3Rpb25IYW5kbGVyID0gbmV3IENhcnRBY3Rpb25IYW5kbGVyKFxuICAgICAgICAgICAgUGF5UGFsQ29tbWVyY2VHYXRld2F5LFxuICAgICAgICAgICAgbmV3IEVycm9ySGFuZGxlcih0aGlzLmdhdGV3YXkubGFiZWxzLmVycm9yLmdlbmVyaWMpLFxuICAgICAgICApO1xuICAgICAgICB0aGlzLnJlbmRlcigpO1xuXG4gICAgICAgIGpRdWVyeShkb2N1bWVudC5ib2R5KS5vbignd2NfZnJhZ21lbnRzX2xvYWRlZCB3Y19mcmFnbWVudHNfcmVmcmVzaGVkJywgKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5yZW5kZXIoKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgc2hvdWxkUmVuZGVyKCkge1xuICAgICAgICByZXR1cm4gZG9jdW1lbnQucXVlcnlTZWxlY3Rvcih0aGlzLmdhdGV3YXkuYnV0dG9uLm1pbmlfY2FydF93cmFwcGVyKSAhPT1cbiAgICAgICAgICAgIG51bGwgfHwgZG9jdW1lbnQucXVlcnlTZWxlY3Rvcih0aGlzLmdhdGV3YXkuaG9zdGVkX2ZpZWxkcy5taW5pX2NhcnRfd3JhcHBlcikgIT09XG4gICAgICAgIG51bGw7XG4gICAgfVxuXG4gICAgcmVuZGVyKCkge1xuICAgICAgICBpZiAoIXRoaXMuc2hvdWxkUmVuZGVyKCkpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMucmVuZGVyZXIucmVuZGVyKFxuICAgICAgICAgICAgdGhpcy5nYXRld2F5LmJ1dHRvbi5taW5pX2NhcnRfd3JhcHBlcixcbiAgICAgICAgICAgIHRoaXMuZ2F0ZXdheS5ob3N0ZWRfZmllbGRzLm1pbmlfY2FydF93cmFwcGVyLFxuICAgICAgICAgICAgdGhpcy5hY3Rpb25IYW5kbGVyLmNvbmZpZ3VyYXRpb24oKVxuICAgICAgICApO1xuICAgIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgTWluaUNhcnRCb290c3RhcDsiLCJpbXBvcnQgUHJvZHVjdCBmcm9tIFwiLi4vRW50aXR5L1Byb2R1Y3RcIjtcbmNsYXNzIFVwZGF0ZUNhcnQge1xuXG4gICAgY29uc3RydWN0b3IoZW5kcG9pbnQsIG5vbmNlKVxuICAgIHtcbiAgICAgICAgdGhpcy5lbmRwb2ludCA9IGVuZHBvaW50O1xuICAgICAgICB0aGlzLm5vbmNlID0gbm9uY2U7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICpcbiAgICAgKiBAcGFyYW0gb25SZXNvbHZlXG4gICAgICogQHBhcmFtIHtQcm9kdWN0W119IHByb2R1Y3RzXG4gICAgICogQHJldHVybnMge1Byb21pc2U8dW5rbm93bj59XG4gICAgICovXG4gICAgdXBkYXRlKG9uUmVzb2x2ZSwgcHJvZHVjdHMpXG4gICAge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgZmV0Y2goXG4gICAgICAgICAgICAgICAgdGhpcy5lbmRwb2ludCxcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIG1ldGhvZDogJ1BPU1QnLFxuICAgICAgICAgICAgICAgICAgICBib2R5OiBKU09OLnN0cmluZ2lmeSh7XG4gICAgICAgICAgICAgICAgICAgICAgICBub25jZTogdGhpcy5ub25jZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHByb2R1Y3RzLFxuICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICkudGhlbihcbiAgICAgICAgICAgICAgICAocmVzdWx0KSA9PiB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdC5qc29uKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgKS50aGVuKChyZXN1bHQpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoISByZXN1bHQuc3VjY2Vzcykge1xuICAgICAgICAgICAgICAgICAgICByZWplY3QocmVzdWx0LmRhdGEpO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHJlc29sdmVkID0gb25SZXNvbHZlKHJlc3VsdC5kYXRhKTtcbiAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZShyZXNvbHZlZCk7XG4gICAgICAgICAgICAgICAgfSlcbiAgICAgICAgfSk7XG4gICAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBVcGRhdGVDYXJ0OyIsIi8qKlxuICogV2hlbiB5b3UgY2FuJ3QgYWRkIHNvbWV0aGluZyB0byB0aGUgY2FydCwgdGhlIFBheVBhbCBidXR0b25zIHNob3VsZCBub3Qgc2hvdy5cbiAqIFRoZXJlZm9yZSB3ZSBsaXN0ZW4gZm9yIGNoYW5nZXMgb24gdGhlIGFkZCB0byBjYXJ0IGJ1dHRvbiBhbmQgc2hvdy9oaWRlIHRoZSBidXR0b25zIGFjY29yZGluZ2x5LlxuICovXG5cbmNsYXNzIEJ1dHRvbnNUb2dnbGVMaXN0ZW5lciB7XG4gICAgY29uc3RydWN0b3IoZWxlbWVudCwgc2hvd0NhbGxiYWNrLCBoaWRlQ2FsbGJhY2spXG4gICAge1xuICAgICAgICB0aGlzLmVsZW1lbnQgPSBlbGVtZW50O1xuICAgICAgICB0aGlzLnNob3dDYWxsYmFjayA9IHNob3dDYWxsYmFjaztcbiAgICAgICAgdGhpcy5oaWRlQ2FsbGJhY2sgPSBoaWRlQ2FsbGJhY2s7XG4gICAgICAgIHRoaXMub2JzZXJ2ZXIgPSBudWxsO1xuICAgIH1cblxuICAgIGluaXQoKVxuICAgIHtcbiAgICAgICAgY29uc3QgY29uZmlnID0geyBhdHRyaWJ1dGVzIDogdHJ1ZSB9O1xuICAgICAgICBjb25zdCBjYWxsYmFjayA9ICgpID0+IHtcbiAgICAgICAgICAgIGlmICh0aGlzLmVsZW1lbnQuY2xhc3NMaXN0LmNvbnRhaW5zKCdkaXNhYmxlZCcpKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5oaWRlQ2FsbGJhY2soKTtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLnNob3dDYWxsYmFjaygpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMub2JzZXJ2ZXIgPSBuZXcgTXV0YXRpb25PYnNlcnZlcihjYWxsYmFjayk7XG4gICAgICAgIHRoaXMub2JzZXJ2ZXIub2JzZXJ2ZSh0aGlzLmVsZW1lbnQsIGNvbmZpZyk7XG4gICAgICAgIGNhbGxiYWNrKCk7XG4gICAgfVxuXG4gICAgZGlzY29ubmVjdCgpXG4gICAge1xuICAgICAgICB0aGlzLm9ic2VydmVyLmRpc2Nvbm5lY3QoKTtcbiAgICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IEJ1dHRvbnNUb2dnbGVMaXN0ZW5lcjsiLCJjbGFzcyBQcm9kdWN0IHtcblxuICAgIGNvbnN0cnVjdG9yKGlkLCBxdWFudGl0eSwgdmFyaWF0aW9ucykge1xuICAgICAgICB0aGlzLmlkID0gaWQ7XG4gICAgICAgIHRoaXMucXVhbnRpdHkgPSBxdWFudGl0eTtcbiAgICAgICAgdGhpcy52YXJpYXRpb25zID0gdmFyaWF0aW9ucztcbiAgICB9XG5cbiAgICBkYXRhKCkge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgaWQ6dGhpcy5pZCxcbiAgICAgICAgICAgIHF1YW50aXR5OnRoaXMucXVhbnRpdHksXG4gICAgICAgICAgICB2YXJpYXRpb25zOnRoaXMudmFyaWF0aW9uc1xuICAgICAgICB9XG4gICAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBQcm9kdWN0OyIsImltcG9ydCBCdXR0b25zVG9nZ2xlTGlzdGVuZXIgZnJvbSAnLi4vSGVscGVyL0J1dHRvbnNUb2dnbGVMaXN0ZW5lcic7XG5pbXBvcnQgUHJvZHVjdCBmcm9tICcuLi9FbnRpdHkvUHJvZHVjdCc7XG5pbXBvcnQgb25BcHByb3ZlIGZyb20gJy4uL09uQXBwcm92ZUhhbmRsZXIvb25BcHByb3ZlRm9yQ29udGludWUnO1xuaW1wb3J0IHtwYXllckRhdGF9IGZyb20gXCIuLi9IZWxwZXIvUGF5ZXJEYXRhXCI7XG5cbmNsYXNzIFNpbmdsZVByb2R1Y3RBY3Rpb25IYW5kbGVyIHtcblxuICAgIGNvbnN0cnVjdG9yKFxuICAgICAgICBjb25maWcsXG4gICAgICAgIHVwZGF0ZUNhcnQsXG4gICAgICAgIHNob3dCdXR0b25DYWxsYmFjayxcbiAgICAgICAgaGlkZUJ1dHRvbkNhbGxiYWNrLFxuICAgICAgICBmb3JtRWxlbWVudCxcbiAgICAgICAgZXJyb3JIYW5kbGVyXG4gICAgKSB7XG4gICAgICAgIHRoaXMuY29uZmlnID0gY29uZmlnO1xuICAgICAgICB0aGlzLnVwZGF0ZUNhcnQgPSB1cGRhdGVDYXJ0O1xuICAgICAgICB0aGlzLnNob3dCdXR0b25DYWxsYmFjayA9IHNob3dCdXR0b25DYWxsYmFjaztcbiAgICAgICAgdGhpcy5oaWRlQnV0dG9uQ2FsbGJhY2sgPSBoaWRlQnV0dG9uQ2FsbGJhY2s7XG4gICAgICAgIHRoaXMuZm9ybUVsZW1lbnQgPSBmb3JtRWxlbWVudDtcbiAgICAgICAgdGhpcy5lcnJvckhhbmRsZXIgPSBlcnJvckhhbmRsZXI7XG4gICAgfVxuXG4gICAgY29uZmlndXJhdGlvbigpXG4gICAge1xuXG4gICAgICAgIGlmICggdGhpcy5oYXNWYXJpYXRpb25zKCkgKSB7XG4gICAgICAgICAgICBjb25zdCBvYnNlcnZlciA9IG5ldyBCdXR0b25zVG9nZ2xlTGlzdGVuZXIoXG4gICAgICAgICAgICAgICAgdGhpcy5mb3JtRWxlbWVudC5xdWVyeVNlbGVjdG9yKCcuc2luZ2xlX2FkZF90b19jYXJ0X2J1dHRvbicpLFxuICAgICAgICAgICAgICAgIHRoaXMuc2hvd0J1dHRvbkNhbGxiYWNrLFxuICAgICAgICAgICAgICAgIHRoaXMuaGlkZUJ1dHRvbkNhbGxiYWNrXG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgb2JzZXJ2ZXIuaW5pdCgpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGNyZWF0ZU9yZGVyOiB0aGlzLmNyZWF0ZU9yZGVyKCksXG4gICAgICAgICAgICBvbkFwcHJvdmU6IG9uQXBwcm92ZSh0aGlzLCB0aGlzLmVycm9ySGFuZGxlciksXG4gICAgICAgICAgICBvbkVycm9yOiAoZXJyb3IpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLmVycm9ySGFuZGxlci5nZW5lcmljRXJyb3IoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIGNyZWF0ZU9yZGVyKClcbiAgICB7XG4gICAgICAgIHZhciBnZXRQcm9kdWN0cyA9IG51bGw7XG4gICAgICAgIGlmICghIHRoaXMuaXNHcm91cGVkUHJvZHVjdCgpICkge1xuICAgICAgICAgICAgZ2V0UHJvZHVjdHMgPSAoKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgaWQgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCdbbmFtZT1cImFkZC10by1jYXJ0XCJdJykudmFsdWU7XG4gICAgICAgICAgICAgICAgY29uc3QgcXR5ID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignW25hbWU9XCJxdWFudGl0eVwiXScpLnZhbHVlO1xuICAgICAgICAgICAgICAgIGNvbnN0IHZhcmlhdGlvbnMgPSB0aGlzLnZhcmlhdGlvbnMoKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gW25ldyBQcm9kdWN0KGlkLCBxdHksIHZhcmlhdGlvbnMpXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGdldFByb2R1Y3RzID0gKCkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IHByb2R1Y3RzID0gW107XG4gICAgICAgICAgICAgICAgdGhpcy5mb3JtRWxlbWVudC5xdWVyeVNlbGVjdG9yQWxsKCdpbnB1dFt0eXBlPVwibnVtYmVyXCJdJykuZm9yRWFjaCgoZWxlbWVudCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAoISBlbGVtZW50LnZhbHVlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgY29uc3QgZWxlbWVudE5hbWUgPSBlbGVtZW50LmdldEF0dHJpYnV0ZSgnbmFtZScpLm1hdGNoKC9xdWFudGl0eVxcWyhbXFxkXSopXFxdLyk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChlbGVtZW50TmFtZS5sZW5ndGggIT09IDIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBjb25zdCBpZCA9IHBhcnNlSW50KGVsZW1lbnROYW1lWzFdKTtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgcXVhbnRpdHkgPSBwYXJzZUludChlbGVtZW50LnZhbHVlKTtcbiAgICAgICAgICAgICAgICAgICAgcHJvZHVjdHMucHVzaChuZXcgUHJvZHVjdChpZCwgcXVhbnRpdHksIG51bGwpKTtcbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgIHJldHVybiBwcm9kdWN0cztcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBjb25zdCBjcmVhdGVPcmRlciA9IChkYXRhLCBhY3Rpb25zKSA9PiB7XG4gICAgICAgICAgICB0aGlzLmVycm9ySGFuZGxlci5jbGVhcigpO1xuXG4gICAgICAgICAgICBjb25zdCBvblJlc29sdmUgPSAocHVyY2hhc2VfdW5pdHMpID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCBwYXllciA9IHBheWVyRGF0YSgpO1xuICAgICAgICAgICAgICAgIGNvbnN0IGJuQ29kZSA9IHR5cGVvZiB0aGlzLmNvbmZpZy5ibl9jb2Rlc1t0aGlzLmNvbmZpZy5jb250ZXh0XSAhPT0gJ3VuZGVmaW5lZCcgP1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmNvbmZpZy5ibl9jb2Rlc1t0aGlzLmNvbmZpZy5jb250ZXh0XSA6ICcnO1xuICAgICAgICAgICAgICAgIHJldHVybiBmZXRjaCh0aGlzLmNvbmZpZy5hamF4LmNyZWF0ZV9vcmRlci5lbmRwb2ludCwge1xuICAgICAgICAgICAgICAgICAgICBtZXRob2Q6ICdQT1NUJyxcbiAgICAgICAgICAgICAgICAgICAgYm9keTogSlNPTi5zdHJpbmdpZnkoe1xuICAgICAgICAgICAgICAgICAgICAgICAgbm9uY2U6IHRoaXMuY29uZmlnLmFqYXguY3JlYXRlX29yZGVyLm5vbmNlLFxuICAgICAgICAgICAgICAgICAgICAgICAgcHVyY2hhc2VfdW5pdHMsXG4gICAgICAgICAgICAgICAgICAgICAgICBwYXllcixcbiAgICAgICAgICAgICAgICAgICAgICAgIGJuX2NvZGU6Ym5Db2RlLFxuICAgICAgICAgICAgICAgICAgICAgICAgY29udGV4dDp0aGlzLmNvbmZpZy5jb250ZXh0XG4gICAgICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgfSkudGhlbihmdW5jdGlvbiAocmVzKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiByZXMuanNvbigpO1xuICAgICAgICAgICAgICAgIH0pLnRoZW4oZnVuY3Rpb24gKGRhdGEpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFkYXRhLnN1Y2Nlc3MpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZGF0YSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBFcnJvcihkYXRhLmRhdGEubWVzc2FnZSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGRhdGEuZGF0YS5pZDtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIGNvbnN0IHByb21pc2UgPSB0aGlzLnVwZGF0ZUNhcnQudXBkYXRlKG9uUmVzb2x2ZSwgZ2V0UHJvZHVjdHMoKSk7XG4gICAgICAgICAgICByZXR1cm4gcHJvbWlzZTtcbiAgICAgICAgfTtcbiAgICAgICAgcmV0dXJuIGNyZWF0ZU9yZGVyO1xuICAgIH1cblxuICAgIHZhcmlhdGlvbnMoKVxuICAgIHtcblxuICAgICAgICBpZiAoISB0aGlzLmhhc1ZhcmlhdGlvbnMoKSkge1xuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgYXR0cmlidXRlcyA9IFsuLi50aGlzLmZvcm1FbGVtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoXCJbbmFtZV49J2F0dHJpYnV0ZV8nXVwiKV0ubWFwKFxuICAgICAgICAgICAgKGVsZW1lbnQpID0+IHtcbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgICAgIHZhbHVlOmVsZW1lbnQudmFsdWUsXG4gICAgICAgICAgICAgICAgICAgIG5hbWU6ZWxlbWVudC5uYW1lXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICApO1xuICAgICAgICByZXR1cm4gYXR0cmlidXRlcztcbiAgICB9XG5cbiAgICBoYXNWYXJpYXRpb25zKClcbiAgICB7XG4gICAgICAgIHJldHVybiB0aGlzLmZvcm1FbGVtZW50LmNsYXNzTGlzdC5jb250YWlucygndmFyaWF0aW9uc19mb3JtJyk7XG4gICAgfVxuXG4gICAgaXNHcm91cGVkUHJvZHVjdCgpXG4gICAge1xuICAgICAgICByZXR1cm4gdGhpcy5mb3JtRWxlbWVudC5jbGFzc0xpc3QuY29udGFpbnMoJ2dyb3VwZWRfZm9ybScpO1xuICAgIH1cbn1cbmV4cG9ydCBkZWZhdWx0IFNpbmdsZVByb2R1Y3RBY3Rpb25IYW5kbGVyO1xuIiwiaW1wb3J0IEVycm9ySGFuZGxlciBmcm9tICcuLi9FcnJvckhhbmRsZXInO1xuaW1wb3J0IFVwZGF0ZUNhcnQgZnJvbSBcIi4uL0hlbHBlci9VcGRhdGVDYXJ0XCI7XG5pbXBvcnQgU2luZ2xlUHJvZHVjdEFjdGlvbkhhbmRsZXIgZnJvbSBcIi4uL0FjdGlvbkhhbmRsZXIvU2luZ2xlUHJvZHVjdEFjdGlvbkhhbmRsZXJcIjtcblxuY2xhc3MgU2luZ2xlUHJvZHVjdEJvb3RzdGFwIHtcbiAgICBjb25zdHJ1Y3RvcihnYXRld2F5LCByZW5kZXJlciwgbWVzc2FnZXMpIHtcbiAgICAgICAgdGhpcy5nYXRld2F5ID0gZ2F0ZXdheTtcbiAgICAgICAgdGhpcy5yZW5kZXJlciA9IHJlbmRlcmVyO1xuICAgICAgICB0aGlzLm1lc3NhZ2VzID0gbWVzc2FnZXM7XG4gICAgfVxuXG4gICAgaW5pdCgpIHtcbiAgICAgICAgaWYgKCF0aGlzLnNob3VsZFJlbmRlcigpKSB7XG4gICAgICAgICAgIHRoaXMucmVuZGVyZXIuaGlkZUJ1dHRvbnModGhpcy5nYXRld2F5Lmhvc3RlZF9maWVsZHMud3JhcHBlcik7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLnJlbmRlcigpO1xuICAgIH1cblxuICAgIHNob3VsZFJlbmRlcigpIHtcbiAgICAgICAgaWYgKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJ2Zvcm0uY2FydCcpID09PSBudWxsKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG5cbiAgICByZW5kZXIoKSB7XG4gICAgICAgIGNvbnN0IGFjdGlvbkhhbmRsZXIgPSBuZXcgU2luZ2xlUHJvZHVjdEFjdGlvbkhhbmRsZXIoXG4gICAgICAgICAgICB0aGlzLmdhdGV3YXksXG4gICAgICAgICAgICBuZXcgVXBkYXRlQ2FydChcbiAgICAgICAgICAgICAgICB0aGlzLmdhdGV3YXkuYWpheC5jaGFuZ2VfY2FydC5lbmRwb2ludCxcbiAgICAgICAgICAgICAgICB0aGlzLmdhdGV3YXkuYWpheC5jaGFuZ2VfY2FydC5ub25jZSxcbiAgICAgICAgICAgICksXG4gICAgICAgICAgICAoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5yZW5kZXJlci5zaG93QnV0dG9ucyh0aGlzLmdhdGV3YXkuYnV0dG9uLndyYXBwZXIpO1xuICAgICAgICAgICAgICAgIHRoaXMucmVuZGVyZXIuc2hvd0J1dHRvbnModGhpcy5nYXRld2F5Lmhvc3RlZF9maWVsZHMud3JhcHBlcik7XG4gICAgICAgICAgICAgICAgbGV0IHByaWNlVGV4dCA9IFwiMFwiO1xuICAgICAgICAgICAgICAgIGlmIChkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCdmb3JtLmNhcnQgaW5zIC53b29jb21tZXJjZS1QcmljZS1hbW91bnQnKSkge1xuICAgICAgICAgICAgICAgICAgICBwcmljZVRleHQgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCdmb3JtLmNhcnQgaW5zIC53b29jb21tZXJjZS1QcmljZS1hbW91bnQnKS5pbm5lclRleHQ7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2UgaWYgKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJ2Zvcm0uY2FydCAud29vY29tbWVyY2UtUHJpY2UtYW1vdW50JykpIHtcbiAgICAgICAgICAgICAgICAgICAgcHJpY2VUZXh0ID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignZm9ybS5jYXJ0IC53b29jb21tZXJjZS1QcmljZS1hbW91bnQnKS5pbm5lclRleHQ7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGNvbnN0IGFtb3VudCA9IHBhcnNlSW50KHByaWNlVGV4dC5yZXBsYWNlKC8oW15cXGQsXFwuXFxzXSopL2csICcnKSk7XG4gICAgICAgICAgICAgICAgdGhpcy5tZXNzYWdlcy5yZW5kZXJXaXRoQW1vdW50KGFtb3VudClcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5yZW5kZXJlci5oaWRlQnV0dG9ucyh0aGlzLmdhdGV3YXkuYnV0dG9uLndyYXBwZXIpO1xuICAgICAgICAgICAgICAgIHRoaXMucmVuZGVyZXIuaGlkZUJ1dHRvbnModGhpcy5nYXRld2F5Lmhvc3RlZF9maWVsZHMud3JhcHBlcik7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZG9jdW1lbnQucXVlcnlTZWxlY3RvcignZm9ybS5jYXJ0JyksXG4gICAgICAgICAgICBuZXcgRXJyb3JIYW5kbGVyKHRoaXMuZ2F0ZXdheS5sYWJlbHMuZXJyb3IuZ2VuZXJpYyksXG4gICAgICAgICk7XG5cbiAgICAgICAgdGhpcy5yZW5kZXJlci5yZW5kZXIoXG4gICAgICAgICAgICB0aGlzLmdhdGV3YXkuYnV0dG9uLndyYXBwZXIsXG4gICAgICAgICAgICB0aGlzLmdhdGV3YXkuaG9zdGVkX2ZpZWxkcy53cmFwcGVyLFxuICAgICAgICAgICAgYWN0aW9uSGFuZGxlci5jb25maWd1cmF0aW9uKCksXG4gICAgICAgICk7XG4gICAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBTaW5nbGVQcm9kdWN0Qm9vdHN0YXA7IiwiaW1wb3J0IENhcnRBY3Rpb25IYW5kbGVyIGZyb20gJy4uL0FjdGlvbkhhbmRsZXIvQ2FydEFjdGlvbkhhbmRsZXInO1xuaW1wb3J0IEVycm9ySGFuZGxlciBmcm9tICcuLi9FcnJvckhhbmRsZXInO1xuXG5jbGFzcyBDYXJ0Qm9vdHN0cmFwIHtcbiAgICBjb25zdHJ1Y3RvcihnYXRld2F5LCByZW5kZXJlcikge1xuICAgICAgICB0aGlzLmdhdGV3YXkgPSBnYXRld2F5O1xuICAgICAgICB0aGlzLnJlbmRlcmVyID0gcmVuZGVyZXI7XG4gICAgfVxuXG4gICAgaW5pdCgpIHtcbiAgICAgICAgaWYgKCF0aGlzLnNob3VsZFJlbmRlcigpKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLnJlbmRlcigpO1xuXG4gICAgICAgIGpRdWVyeShkb2N1bWVudC5ib2R5KS5vbigndXBkYXRlZF9jYXJ0X3RvdGFscyB1cGRhdGVkX2NoZWNrb3V0JywgKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5yZW5kZXIoKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgc2hvdWxkUmVuZGVyKCkge1xuICAgICAgICByZXR1cm4gZG9jdW1lbnQucXVlcnlTZWxlY3Rvcih0aGlzLmdhdGV3YXkuYnV0dG9uLndyYXBwZXIpICE9PVxuICAgICAgICAgICAgbnVsbCB8fCBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKHRoaXMuZ2F0ZXdheS5ob3N0ZWRfZmllbGRzLndyYXBwZXIpICE9PVxuICAgICAgICAgICAgbnVsbDtcbiAgICB9XG5cbiAgICByZW5kZXIoKSB7XG4gICAgICAgIGNvbnN0IGFjdGlvbkhhbmRsZXIgPSBuZXcgQ2FydEFjdGlvbkhhbmRsZXIoXG4gICAgICAgICAgICBQYXlQYWxDb21tZXJjZUdhdGV3YXksXG4gICAgICAgICAgICBuZXcgRXJyb3JIYW5kbGVyKHRoaXMuZ2F0ZXdheS5sYWJlbHMuZXJyb3IuZ2VuZXJpYyksXG4gICAgICAgICk7XG5cbiAgICAgICAgdGhpcy5yZW5kZXJlci5yZW5kZXIoXG4gICAgICAgICAgICB0aGlzLmdhdGV3YXkuYnV0dG9uLndyYXBwZXIsXG4gICAgICAgICAgICB0aGlzLmdhdGV3YXkuaG9zdGVkX2ZpZWxkcy53cmFwcGVyLFxuICAgICAgICAgICAgYWN0aW9uSGFuZGxlci5jb25maWd1cmF0aW9uKCksXG4gICAgICAgICk7XG4gICAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBDYXJ0Qm9vdHN0cmFwO1xuIiwiY29uc3Qgb25BcHByb3ZlID0gKGNvbnRleHQsIGVycm9ySGFuZGxlciwgc3Bpbm5lcikgPT4ge1xuICAgIHJldHVybiAoZGF0YSwgYWN0aW9ucykgPT4ge1xuICAgICAgICBzcGlubmVyLmJsb2NrKCk7XG4gICAgICAgIHJldHVybiBmZXRjaChjb250ZXh0LmNvbmZpZy5hamF4LmFwcHJvdmVfb3JkZXIuZW5kcG9pbnQsIHtcbiAgICAgICAgICAgIG1ldGhvZDogJ1BPU1QnLFxuICAgICAgICAgICAgYm9keTogSlNPTi5zdHJpbmdpZnkoe1xuICAgICAgICAgICAgICAgIG5vbmNlOiBjb250ZXh0LmNvbmZpZy5hamF4LmFwcHJvdmVfb3JkZXIubm9uY2UsXG4gICAgICAgICAgICAgICAgb3JkZXJfaWQ6ZGF0YS5vcmRlcklEXG4gICAgICAgICAgICB9KVxuICAgICAgICB9KS50aGVuKChyZXMpPT57XG4gICAgICAgICAgICByZXR1cm4gcmVzLmpzb24oKTtcbiAgICAgICAgfSkudGhlbigoZGF0YSk9PntcbiAgICAgICAgICAgIHNwaW5uZXIudW5ibG9jaygpO1xuICAgICAgICAgICAgaWYgKCFkYXRhLnN1Y2Nlc3MpIHtcbiAgICAgICAgICAgICAgICBpZiAoZGF0YS5kYXRhLmNvZGUgPT09IDEwMCkge1xuICAgICAgICAgICAgICAgICAgICBlcnJvckhhbmRsZXIubWVzc2FnZShkYXRhLmRhdGEubWVzc2FnZSk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgZXJyb3JIYW5kbGVyLmdlbmVyaWNFcnJvcigpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIGFjdGlvbnMgIT09ICd1bmRlZmluZWQnICYmIHR5cGVvZiBhY3Rpb25zLnJlc3RhcnQgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBhY3Rpb25zLnJlc3RhcnQoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGRhdGEuZGF0YS5tZXNzYWdlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNwbGFjZV9vcmRlcicpLmNsaWNrKClcbiAgICAgICAgfSk7XG5cbiAgICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IG9uQXBwcm92ZTtcbiIsImltcG9ydCBvbkFwcHJvdmUgZnJvbSAnLi4vT25BcHByb3ZlSGFuZGxlci9vbkFwcHJvdmVGb3JQYXlOb3cuanMnO1xuaW1wb3J0IHtwYXllckRhdGF9IGZyb20gXCIuLi9IZWxwZXIvUGF5ZXJEYXRhXCI7XG5cbmNsYXNzIENoZWNrb3V0QWN0aW9uSGFuZGxlciB7XG5cbiAgICBjb25zdHJ1Y3Rvcihjb25maWcsIGVycm9ySGFuZGxlciwgc3Bpbm5lcikge1xuICAgICAgICB0aGlzLmNvbmZpZyA9IGNvbmZpZztcbiAgICAgICAgdGhpcy5lcnJvckhhbmRsZXIgPSBlcnJvckhhbmRsZXI7XG4gICAgICAgIHRoaXMuc3Bpbm5lciA9IHNwaW5uZXI7XG4gICAgfVxuXG4gICAgY29uZmlndXJhdGlvbigpIHtcbiAgICAgICAgY29uc3Qgc3Bpbm5lciA9IHRoaXMuc3Bpbm5lcjtcbiAgICAgICAgY29uc3QgY3JlYXRlT3JkZXIgPSAoZGF0YSwgYWN0aW9ucykgPT4ge1xuICAgICAgICAgICAgY29uc3QgcGF5ZXIgPSBwYXllckRhdGEoKTtcbiAgICAgICAgICAgIGNvbnN0IGJuQ29kZSA9IHR5cGVvZiB0aGlzLmNvbmZpZy5ibl9jb2Rlc1t0aGlzLmNvbmZpZy5jb250ZXh0XSAhPT0gJ3VuZGVmaW5lZCcgP1xuICAgICAgICAgICAgICAgIHRoaXMuY29uZmlnLmJuX2NvZGVzW3RoaXMuY29uZmlnLmNvbnRleHRdIDogJyc7XG5cbiAgICAgICAgICAgIGNvbnN0IGVycm9ySGFuZGxlciA9IHRoaXMuZXJyb3JIYW5kbGVyO1xuXG4gICAgICAgICAgICBjb25zdCBmb3JtU2VsZWN0b3IgPSB0aGlzLmNvbmZpZy5jb250ZXh0ID09PSAnY2hlY2tvdXQnID8gJ2Zvcm0uY2hlY2tvdXQnIDogJ2Zvcm0jb3JkZXJfcmV2aWV3JztcbiAgICAgICAgICAgIGNvbnN0IGZvcm1WYWx1ZXMgPSBqUXVlcnkoZm9ybVNlbGVjdG9yKS5zZXJpYWxpemUoKTtcblxuICAgICAgICAgICAgY29uc3QgY3JlYXRlYWNjb3VudCA9IGpRdWVyeSgnI2NyZWF0ZWFjY291bnQnKS5pcyhcIjpjaGVja2VkXCIpID8gdHJ1ZSA6IGZhbHNlO1xuXG4gICAgICAgICAgICByZXR1cm4gZmV0Y2godGhpcy5jb25maWcuYWpheC5jcmVhdGVfb3JkZXIuZW5kcG9pbnQsIHtcbiAgICAgICAgICAgICAgICBtZXRob2Q6ICdQT1NUJyxcbiAgICAgICAgICAgICAgICBib2R5OiBKU09OLnN0cmluZ2lmeSh7XG4gICAgICAgICAgICAgICAgICAgIG5vbmNlOiB0aGlzLmNvbmZpZy5hamF4LmNyZWF0ZV9vcmRlci5ub25jZSxcbiAgICAgICAgICAgICAgICAgICAgcGF5ZXIsXG4gICAgICAgICAgICAgICAgICAgIGJuX2NvZGU6Ym5Db2RlLFxuICAgICAgICAgICAgICAgICAgICBjb250ZXh0OnRoaXMuY29uZmlnLmNvbnRleHQsXG4gICAgICAgICAgICAgICAgICAgIG9yZGVyX2lkOnRoaXMuY29uZmlnLm9yZGVyX2lkLFxuICAgICAgICAgICAgICAgICAgICBmb3JtOmZvcm1WYWx1ZXMsXG4gICAgICAgICAgICAgICAgICAgIGNyZWF0ZWFjY291bnQ6IGNyZWF0ZWFjY291bnRcbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgfSkudGhlbihmdW5jdGlvbiAocmVzKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHJlcy5qc29uKCk7XG4gICAgICAgICAgICB9KS50aGVuKGZ1bmN0aW9uIChkYXRhKSB7XG4gICAgICAgICAgICAgICAgaWYgKCFkYXRhLnN1Y2Nlc3MpIHtcbiAgICAgICAgICAgICAgICAgICAgc3Bpbm5lci51bmJsb2NrKCk7XG4gICAgICAgICAgICAgICAgICAgIC8vaGFuZGxlIGJvdGggbWVzc2FnZXMgc2VudCBmcm9tIFdvb2NvbW1lcmNlIChkYXRhLm1lc3NhZ2VzKSBhbmQgdGhpcyBwbHVnaW4gKGRhdGEuZGF0YS5tZXNzYWdlKVxuICAgICAgICAgICAgICAgICAgICBpZiAodHlwZW9mKGRhdGEubWVzc2FnZXMpICE9PSAndW5kZWZpbmVkJyApXG4gICAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGRvbVBhcnNlciA9IG5ldyBET01QYXJzZXIoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGVycm9ySGFuZGxlci5hcHBlbmRQcmVwYXJlZEVycm9yTWVzc2FnZUVsZW1lbnQoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZG9tUGFyc2VyLnBhcnNlRnJvbVN0cmluZyhkYXRhLm1lc3NhZ2VzLCAndGV4dC9odG1sJylcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLnF1ZXJ5U2VsZWN0b3IoJ3VsJylcbiAgICAgICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBlcnJvckhhbmRsZXIubWVzc2FnZShkYXRhLmRhdGEubWVzc2FnZSwgdHJ1ZSk7XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGNvbnN0IGlucHV0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnaW5wdXQnKTtcbiAgICAgICAgICAgICAgICBpbnB1dC5zZXRBdHRyaWJ1dGUoJ3R5cGUnLCAnaGlkZGVuJyk7XG4gICAgICAgICAgICAgICAgaW5wdXQuc2V0QXR0cmlidXRlKCduYW1lJywgJ3BwY3AtcmVzdW1lLW9yZGVyJyk7XG4gICAgICAgICAgICAgICAgaW5wdXQuc2V0QXR0cmlidXRlKCd2YWx1ZScsIGRhdGEuZGF0YS5wdXJjaGFzZV91bml0c1swXS5jdXN0b21faWQpO1xuICAgICAgICAgICAgICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoZm9ybVNlbGVjdG9yKS5hcHBlbmQoaW5wdXQpO1xuICAgICAgICAgICAgICAgIHJldHVybiBkYXRhLmRhdGEuaWQ7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgY3JlYXRlT3JkZXIsXG4gICAgICAgICAgICBvbkFwcHJvdmU6b25BcHByb3ZlKHRoaXMsIHRoaXMuZXJyb3JIYW5kbGVyLCB0aGlzLnNwaW5uZXIpLFxuICAgICAgICAgICAgb25DYW5jZWw6ICgpID0+IHtcbiAgICAgICAgICAgICAgICBzcGlubmVyLnVuYmxvY2soKTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBvbkVycm9yOiAoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5lcnJvckhhbmRsZXIuZ2VuZXJpY0Vycm9yKCk7XG4gICAgICAgICAgICAgICAgc3Bpbm5lci51bmJsb2NrKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IENoZWNrb3V0QWN0aW9uSGFuZGxlcjtcbiIsImltcG9ydCBFcnJvckhhbmRsZXIgZnJvbSAnLi4vRXJyb3JIYW5kbGVyJztcbmltcG9ydCBDaGVja291dEFjdGlvbkhhbmRsZXIgZnJvbSAnLi4vQWN0aW9uSGFuZGxlci9DaGVja291dEFjdGlvbkhhbmRsZXInO1xuXG5jbGFzcyBDaGVja291dEJvb3RzdGFwIHtcbiAgICBjb25zdHJ1Y3RvcihnYXRld2F5LCByZW5kZXJlciwgbWVzc2FnZXMsIHNwaW5uZXIpIHtcbiAgICAgICAgdGhpcy5nYXRld2F5ID0gZ2F0ZXdheTtcbiAgICAgICAgdGhpcy5yZW5kZXJlciA9IHJlbmRlcmVyO1xuICAgICAgICB0aGlzLm1lc3NhZ2VzID0gbWVzc2FnZXM7XG4gICAgICAgIHRoaXMuc3Bpbm5lciA9IHNwaW5uZXI7XG4gICAgfVxuXG4gICAgaW5pdCgpIHtcblxuICAgICAgICB0aGlzLnJlbmRlcigpO1xuXG4gICAgICAgIGpRdWVyeShkb2N1bWVudC5ib2R5KS5vbigndXBkYXRlZF9jaGVja291dCcsICgpID0+IHtcbiAgICAgICAgICAgIHRoaXMucmVuZGVyKClcbiAgICAgICAgfSk7XG5cbiAgICAgICAgalF1ZXJ5KGRvY3VtZW50LmJvZHkpLlxuICAgICAgICAgIG9uKCd1cGRhdGVkX2NoZWNrb3V0IHBheW1lbnRfbWV0aG9kX3NlbGVjdGVkJywgKCkgPT4ge1xuICAgICAgICAgICAgICB0aGlzLnN3aXRjaEJldHdlZW5QYXlQYWxhbmRPcmRlckJ1dHRvbigpXG4gICAgICAgICAgICAgIHRoaXMuZGlzcGxheVBsYWNlT3JkZXJCdXR0b25Gb3JTYXZlZENyZWRpdENhcmRzKClcblxuICAgICAgICAgIH0pXG5cbiAgICAgICAgalF1ZXJ5KGRvY3VtZW50KS5vbignaG9zdGVkX2ZpZWxkc19sb2FkZWQnLCAoKSA9PiB7XG4gICAgICAgICAgICBqUXVlcnkoJyNzYXZlZC1jcmVkaXQtY2FyZCcpLm9uKCdjaGFuZ2UnLCAoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5kaXNwbGF5UGxhY2VPcmRlckJ1dHRvbkZvclNhdmVkQ3JlZGl0Q2FyZHMoKVxuICAgICAgICAgICAgfSlcbiAgICAgICAgfSk7XG5cbiAgICAgICAgdGhpcy5zd2l0Y2hCZXR3ZWVuUGF5UGFsYW5kT3JkZXJCdXR0b24oKVxuICAgICAgICB0aGlzLmRpc3BsYXlQbGFjZU9yZGVyQnV0dG9uRm9yU2F2ZWRDcmVkaXRDYXJkcygpXG4gICAgfVxuXG4gICAgc2hvdWxkUmVuZGVyKCkge1xuICAgICAgICBpZiAoZG9jdW1lbnQucXVlcnlTZWxlY3Rvcih0aGlzLmdhdGV3YXkuYnV0dG9uLmNhbmNlbF93cmFwcGVyKSkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IodGhpcy5nYXRld2F5LmJ1dHRvbi53cmFwcGVyKSAhPT0gbnVsbCB8fCBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKHRoaXMuZ2F0ZXdheS5ob3N0ZWRfZmllbGRzLndyYXBwZXIpICE9PSBudWxsO1xuICAgIH1cblxuICAgIHJlbmRlcigpIHtcbiAgICAgICAgaWYgKCF0aGlzLnNob3VsZFJlbmRlcigpKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IodGhpcy5nYXRld2F5Lmhvc3RlZF9maWVsZHMud3JhcHBlciArICc+ZGl2JykpIHtcbiAgICAgICAgICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IodGhpcy5nYXRld2F5Lmhvc3RlZF9maWVsZHMud3JhcHBlciArICc+ZGl2Jykuc2V0QXR0cmlidXRlKCdzdHlsZScsICcnKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBhY3Rpb25IYW5kbGVyID0gbmV3IENoZWNrb3V0QWN0aW9uSGFuZGxlcihcbiAgICAgICAgICAgIFBheVBhbENvbW1lcmNlR2F0ZXdheSxcbiAgICAgICAgICAgIG5ldyBFcnJvckhhbmRsZXIodGhpcy5nYXRld2F5LmxhYmVscy5lcnJvci5nZW5lcmljKSxcbiAgICAgICAgICAgIHRoaXMuc3Bpbm5lclxuICAgICAgICApO1xuXG4gICAgICAgIHRoaXMucmVuZGVyZXIucmVuZGVyKFxuICAgICAgICAgICAgdGhpcy5nYXRld2F5LmJ1dHRvbi53cmFwcGVyLFxuICAgICAgICAgICAgdGhpcy5nYXRld2F5Lmhvc3RlZF9maWVsZHMud3JhcHBlcixcbiAgICAgICAgICAgIGFjdGlvbkhhbmRsZXIuY29uZmlndXJhdGlvbigpLFxuICAgICAgICApO1xuICAgIH1cblxuICAgIHN3aXRjaEJldHdlZW5QYXlQYWxhbmRPcmRlckJ1dHRvbigpIHtcbiAgICAgICAgalF1ZXJ5KCcjc2F2ZWQtY3JlZGl0LWNhcmQnKS52YWwoalF1ZXJ5KCcjc2F2ZWQtY3JlZGl0LWNhcmQgb3B0aW9uOmZpcnN0JykudmFsKCkpO1xuXG4gICAgICAgIGNvbnN0IGN1cnJlbnRQYXltZW50TWV0aG9kID0galF1ZXJ5KFxuICAgICAgICAgICAgJ2lucHV0W25hbWU9XCJwYXltZW50X21ldGhvZFwiXTpjaGVja2VkJykudmFsKCk7XG5cbiAgICAgICAgaWYgKGN1cnJlbnRQYXltZW50TWV0aG9kICE9PSAncHBjcC1nYXRld2F5JyAmJiBjdXJyZW50UGF5bWVudE1ldGhvZCAhPT0gJ3BwY3AtY3JlZGl0LWNhcmQtZ2F0ZXdheScpIHtcbiAgICAgICAgICAgIHRoaXMucmVuZGVyZXIuaGlkZUJ1dHRvbnModGhpcy5nYXRld2F5LmJ1dHRvbi53cmFwcGVyKTtcbiAgICAgICAgICAgIHRoaXMucmVuZGVyZXIuaGlkZUJ1dHRvbnModGhpcy5nYXRld2F5Lm1lc3NhZ2VzLndyYXBwZXIpO1xuICAgICAgICAgICAgdGhpcy5yZW5kZXJlci5oaWRlQnV0dG9ucyh0aGlzLmdhdGV3YXkuaG9zdGVkX2ZpZWxkcy53cmFwcGVyKTtcbiAgICAgICAgICAgIGpRdWVyeSgnI3BsYWNlX29yZGVyJykuc2hvdygpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgalF1ZXJ5KCcjcGxhY2Vfb3JkZXInKS5oaWRlKCk7XG4gICAgICAgICAgICBpZiAoY3VycmVudFBheW1lbnRNZXRob2QgPT09ICdwcGNwLWdhdGV3YXknKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5yZW5kZXJlci5zaG93QnV0dG9ucyh0aGlzLmdhdGV3YXkuYnV0dG9uLndyYXBwZXIpO1xuICAgICAgICAgICAgICAgIHRoaXMucmVuZGVyZXIuc2hvd0J1dHRvbnModGhpcy5nYXRld2F5Lm1lc3NhZ2VzLndyYXBwZXIpO1xuICAgICAgICAgICAgICAgIHRoaXMubWVzc2FnZXMucmVuZGVyKClcbiAgICAgICAgICAgICAgICB0aGlzLnJlbmRlcmVyLmhpZGVCdXR0b25zKHRoaXMuZ2F0ZXdheS5ob3N0ZWRfZmllbGRzLndyYXBwZXIpXG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoY3VycmVudFBheW1lbnRNZXRob2QgPT09ICdwcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXknKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5yZW5kZXJlci5oaWRlQnV0dG9ucyh0aGlzLmdhdGV3YXkuYnV0dG9uLndyYXBwZXIpXG4gICAgICAgICAgICAgICAgdGhpcy5yZW5kZXJlci5oaWRlQnV0dG9ucyh0aGlzLmdhdGV3YXkubWVzc2FnZXMud3JhcHBlcilcbiAgICAgICAgICAgICAgICB0aGlzLnJlbmRlcmVyLnNob3dCdXR0b25zKHRoaXMuZ2F0ZXdheS5ob3N0ZWRfZmllbGRzLndyYXBwZXIpXG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBkaXNwbGF5UGxhY2VPcmRlckJ1dHRvbkZvclNhdmVkQ3JlZGl0Q2FyZHMoKSB7XG4gICAgICAgIGNvbnN0IGN1cnJlbnRQYXltZW50TWV0aG9kID0galF1ZXJ5KFxuICAgICAgICAgICdpbnB1dFtuYW1lPVwicGF5bWVudF9tZXRob2RcIl06Y2hlY2tlZCcpLnZhbCgpO1xuICAgICAgICBpZiAoY3VycmVudFBheW1lbnRNZXRob2QgIT09ICdwcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXknKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoalF1ZXJ5KCcjc2F2ZWQtY3JlZGl0LWNhcmQnKS5sZW5ndGggJiYgalF1ZXJ5KCcjc2F2ZWQtY3JlZGl0LWNhcmQnKS52YWwoKSAhPT0gJycpIHtcbiAgICAgICAgICAgIHRoaXMucmVuZGVyZXIuaGlkZUJ1dHRvbnModGhpcy5nYXRld2F5LmJ1dHRvbi53cmFwcGVyKVxuICAgICAgICAgICAgdGhpcy5yZW5kZXJlci5oaWRlQnV0dG9ucyh0aGlzLmdhdGV3YXkubWVzc2FnZXMud3JhcHBlcilcbiAgICAgICAgICAgIHRoaXMucmVuZGVyZXIuaGlkZUJ1dHRvbnModGhpcy5nYXRld2F5Lmhvc3RlZF9maWVsZHMud3JhcHBlcilcbiAgICAgICAgICAgIGpRdWVyeSgnI3BsYWNlX29yZGVyJykuc2hvdygpXG4gICAgICAgICAgICB0aGlzLmRpc2FibGVDcmVkaXRDYXJkRmllbGRzKClcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGpRdWVyeSgnI3BsYWNlX29yZGVyJykuaGlkZSgpXG4gICAgICAgICAgICB0aGlzLnJlbmRlcmVyLmhpZGVCdXR0b25zKHRoaXMuZ2F0ZXdheS5idXR0b24ud3JhcHBlcilcbiAgICAgICAgICAgIHRoaXMucmVuZGVyZXIuaGlkZUJ1dHRvbnModGhpcy5nYXRld2F5Lm1lc3NhZ2VzLndyYXBwZXIpXG4gICAgICAgICAgICB0aGlzLnJlbmRlcmVyLnNob3dCdXR0b25zKHRoaXMuZ2F0ZXdheS5ob3N0ZWRfZmllbGRzLndyYXBwZXIpXG4gICAgICAgICAgICB0aGlzLmVuYWJsZUNyZWRpdENhcmRGaWVsZHMoKVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgZGlzYWJsZUNyZWRpdENhcmRGaWVsZHMoKSB7XG4gICAgICAgIGpRdWVyeSgnbGFiZWxbZm9yPVwicHBjcC1jcmVkaXQtY2FyZC1nYXRld2F5LWNhcmQtbnVtYmVyXCJdJykuYWRkQ2xhc3MoJ3BwY3AtY3JlZGl0LWNhcmQtZ2F0ZXdheS1mb3JtLWZpZWxkLWRpc2FibGVkJylcbiAgICAgICAgalF1ZXJ5KCcjcHBjcC1jcmVkaXQtY2FyZC1nYXRld2F5LWNhcmQtbnVtYmVyJykuYWRkQ2xhc3MoJ3BwY3AtY3JlZGl0LWNhcmQtZ2F0ZXdheS1mb3JtLWZpZWxkLWRpc2FibGVkJylcbiAgICAgICAgalF1ZXJ5KCdsYWJlbFtmb3I9XCJwcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXktY2FyZC1leHBpcnlcIl0nKS5hZGRDbGFzcygncHBjcC1jcmVkaXQtY2FyZC1nYXRld2F5LWZvcm0tZmllbGQtZGlzYWJsZWQnKVxuICAgICAgICBqUXVlcnkoJyNwcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXktY2FyZC1leHBpcnknKS5hZGRDbGFzcygncHBjcC1jcmVkaXQtY2FyZC1nYXRld2F5LWZvcm0tZmllbGQtZGlzYWJsZWQnKVxuICAgICAgICBqUXVlcnkoJ2xhYmVsW2Zvcj1cInBwY3AtY3JlZGl0LWNhcmQtZ2F0ZXdheS1jYXJkLWN2Y1wiXScpLmFkZENsYXNzKCdwcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXktZm9ybS1maWVsZC1kaXNhYmxlZCcpXG4gICAgICAgIGpRdWVyeSgnI3BwY3AtY3JlZGl0LWNhcmQtZ2F0ZXdheS1jYXJkLWN2YycpLmFkZENsYXNzKCdwcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXktZm9ybS1maWVsZC1kaXNhYmxlZCcpXG4gICAgICAgIGpRdWVyeSgnbGFiZWxbZm9yPVwidmF1bHRcIl0nKS5hZGRDbGFzcygncHBjcC1jcmVkaXQtY2FyZC1nYXRld2F5LWZvcm0tZmllbGQtZGlzYWJsZWQnKVxuICAgICAgICBqUXVlcnkoJyNwcGNwLWNyZWRpdC1jYXJkLXZhdWx0JykuYWRkQ2xhc3MoJ3BwY3AtY3JlZGl0LWNhcmQtZ2F0ZXdheS1mb3JtLWZpZWxkLWRpc2FibGVkJylcbiAgICAgICAgalF1ZXJ5KCcjcHBjcC1jcmVkaXQtY2FyZC12YXVsdCcpLmF0dHIoXCJkaXNhYmxlZFwiLCB0cnVlKVxuICAgICAgICB0aGlzLnJlbmRlcmVyLmRpc2FibGVDcmVkaXRDYXJkRmllbGRzKClcbiAgICB9XG5cbiAgICBlbmFibGVDcmVkaXRDYXJkRmllbGRzKCkge1xuICAgICAgICBqUXVlcnkoJ2xhYmVsW2Zvcj1cInBwY3AtY3JlZGl0LWNhcmQtZ2F0ZXdheS1jYXJkLW51bWJlclwiXScpLnJlbW92ZUNsYXNzKCdwcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXktZm9ybS1maWVsZC1kaXNhYmxlZCcpXG4gICAgICAgIGpRdWVyeSgnI3BwY3AtY3JlZGl0LWNhcmQtZ2F0ZXdheS1jYXJkLW51bWJlcicpLnJlbW92ZUNsYXNzKCdwcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXktZm9ybS1maWVsZC1kaXNhYmxlZCcpXG4gICAgICAgIGpRdWVyeSgnbGFiZWxbZm9yPVwicHBjcC1jcmVkaXQtY2FyZC1nYXRld2F5LWNhcmQtZXhwaXJ5XCJdJykucmVtb3ZlQ2xhc3MoJ3BwY3AtY3JlZGl0LWNhcmQtZ2F0ZXdheS1mb3JtLWZpZWxkLWRpc2FibGVkJylcbiAgICAgICAgalF1ZXJ5KCcjcHBjcC1jcmVkaXQtY2FyZC1nYXRld2F5LWNhcmQtZXhwaXJ5JykucmVtb3ZlQ2xhc3MoJ3BwY3AtY3JlZGl0LWNhcmQtZ2F0ZXdheS1mb3JtLWZpZWxkLWRpc2FibGVkJylcbiAgICAgICAgalF1ZXJ5KCdsYWJlbFtmb3I9XCJwcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXktY2FyZC1jdmNcIl0nKS5yZW1vdmVDbGFzcygncHBjcC1jcmVkaXQtY2FyZC1nYXRld2F5LWZvcm0tZmllbGQtZGlzYWJsZWQnKVxuICAgICAgICBqUXVlcnkoJyNwcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXktY2FyZC1jdmMnKS5yZW1vdmVDbGFzcygncHBjcC1jcmVkaXQtY2FyZC1nYXRld2F5LWZvcm0tZmllbGQtZGlzYWJsZWQnKVxuICAgICAgICBqUXVlcnkoJ2xhYmVsW2Zvcj1cInZhdWx0XCJdJykucmVtb3ZlQ2xhc3MoJ3BwY3AtY3JlZGl0LWNhcmQtZ2F0ZXdheS1mb3JtLWZpZWxkLWRpc2FibGVkJylcbiAgICAgICAgalF1ZXJ5KCcjcHBjcC1jcmVkaXQtY2FyZC12YXVsdCcpLnJlbW92ZUNsYXNzKCdwcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXktZm9ybS1maWVsZC1kaXNhYmxlZCcpXG4gICAgICAgIGpRdWVyeSgnI3BwY3AtY3JlZGl0LWNhcmQtdmF1bHQnKS5hdHRyKFwiZGlzYWJsZWRcIiwgZmFsc2UpXG4gICAgICAgIHRoaXMucmVuZGVyZXIuZW5hYmxlQ3JlZGl0Q2FyZEZpZWxkcygpXG4gICAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBDaGVja291dEJvb3RzdGFwXG4iLCJpbXBvcnQgRXJyb3JIYW5kbGVyIGZyb20gJy4uL0Vycm9ySGFuZGxlcic7XG5pbXBvcnQgQ2hlY2tvdXRBY3Rpb25IYW5kbGVyIGZyb20gJy4uL0FjdGlvbkhhbmRsZXIvQ2hlY2tvdXRBY3Rpb25IYW5kbGVyJztcblxuY2xhc3MgUGF5Tm93Qm9vdHN0cmFwIHtcbiAgICBjb25zdHJ1Y3RvcihnYXRld2F5LCByZW5kZXJlciwgbWVzc2FnZXMsIHNwaW5uZXIpIHtcbiAgICAgICAgdGhpcy5nYXRld2F5ID0gZ2F0ZXdheTtcbiAgICAgICAgdGhpcy5yZW5kZXJlciA9IHJlbmRlcmVyO1xuICAgICAgICB0aGlzLm1lc3NhZ2VzID0gbWVzc2FnZXM7XG4gICAgICAgIHRoaXMuc3Bpbm5lciA9IHNwaW5uZXI7XG4gICAgfVxuXG4gICAgaW5pdCgpIHtcblxuICAgICAgICB0aGlzLnJlbmRlcigpO1xuXG4gICAgICAgIGpRdWVyeShkb2N1bWVudC5ib2R5KS5vbigndXBkYXRlZF9jaGVja291dCcsICgpID0+IHtcbiAgICAgICAgICAgIHRoaXMucmVuZGVyKCk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGpRdWVyeShkb2N1bWVudC5ib2R5KS5cbiAgICAgICAgb24oJ3VwZGF0ZWRfY2hlY2tvdXQgcGF5bWVudF9tZXRob2Rfc2VsZWN0ZWQnLCAoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLnN3aXRjaEJldHdlZW5QYXlQYWxhbmRPcmRlckJ1dHRvbigpO1xuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5zd2l0Y2hCZXR3ZWVuUGF5UGFsYW5kT3JkZXJCdXR0b24oKTtcbiAgICB9XG5cbiAgICBzaG91bGRSZW5kZXIoKSB7XG4gICAgICAgIGlmIChkb2N1bWVudC5xdWVyeVNlbGVjdG9yKHRoaXMuZ2F0ZXdheS5idXR0b24uY2FuY2VsX3dyYXBwZXIpKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gZG9jdW1lbnQucXVlcnlTZWxlY3Rvcih0aGlzLmdhdGV3YXkuYnV0dG9uLndyYXBwZXIpICE9PSBudWxsIHx8IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IodGhpcy5nYXRld2F5Lmhvc3RlZF9maWVsZHMud3JhcHBlcikgIT09IG51bGw7XG4gICAgfVxuXG4gICAgcmVuZGVyKCkge1xuICAgICAgICBpZiAoIXRoaXMuc2hvdWxkUmVuZGVyKCkpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBpZiAoZG9jdW1lbnQucXVlcnlTZWxlY3Rvcih0aGlzLmdhdGV3YXkuaG9zdGVkX2ZpZWxkcy53cmFwcGVyICsgJz5kaXYnKSkge1xuICAgICAgICAgICAgZG9jdW1lbnQucXVlcnlTZWxlY3Rvcih0aGlzLmdhdGV3YXkuaG9zdGVkX2ZpZWxkcy53cmFwcGVyICsgJz5kaXYnKS5zZXRBdHRyaWJ1dGUoJ3N0eWxlJywgJycpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGFjdGlvbkhhbmRsZXIgPSBuZXcgQ2hlY2tvdXRBY3Rpb25IYW5kbGVyKFxuICAgICAgICAgICAgUGF5UGFsQ29tbWVyY2VHYXRld2F5LFxuICAgICAgICAgICAgbmV3IEVycm9ySGFuZGxlcih0aGlzLmdhdGV3YXkubGFiZWxzLmVycm9yLmdlbmVyaWMpLFxuICAgICAgICAgICAgdGhpcy5zcGlubmVyXG4gICAgICAgICk7XG5cbiAgICAgICAgdGhpcy5yZW5kZXJlci5yZW5kZXIoXG4gICAgICAgICAgICB0aGlzLmdhdGV3YXkuYnV0dG9uLndyYXBwZXIsXG4gICAgICAgICAgICB0aGlzLmdhdGV3YXkuaG9zdGVkX2ZpZWxkcy53cmFwcGVyLFxuICAgICAgICAgICAgYWN0aW9uSGFuZGxlci5jb25maWd1cmF0aW9uKCksXG4gICAgICAgICk7XG4gICAgfVxuXG4gICAgc3dpdGNoQmV0d2VlblBheVBhbGFuZE9yZGVyQnV0dG9uKCkge1xuICAgICAgICBjb25zdCB1cmxQYXJhbXMgPSBuZXcgVVJMU2VhcmNoUGFyYW1zKHdpbmRvdy5sb2NhdGlvbi5zZWFyY2gpXG4gICAgICAgIGlmICh1cmxQYXJhbXMuaGFzKCdjaGFuZ2VfcGF5bWVudF9tZXRob2QnKSkge1xuICAgICAgICAgICAgcmV0dXJuXG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBjdXJyZW50UGF5bWVudE1ldGhvZCA9IGpRdWVyeShcbiAgICAgICAgICAgICdpbnB1dFtuYW1lPVwicGF5bWVudF9tZXRob2RcIl06Y2hlY2tlZCcpLnZhbCgpO1xuXG4gICAgICAgIGlmIChjdXJyZW50UGF5bWVudE1ldGhvZCAhPT0gJ3BwY3AtZ2F0ZXdheScgJiYgY3VycmVudFBheW1lbnRNZXRob2QgIT09ICdwcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXknKSB7XG4gICAgICAgICAgICB0aGlzLnJlbmRlcmVyLmhpZGVCdXR0b25zKHRoaXMuZ2F0ZXdheS5idXR0b24ud3JhcHBlcik7XG4gICAgICAgICAgICB0aGlzLnJlbmRlcmVyLmhpZGVCdXR0b25zKHRoaXMuZ2F0ZXdheS5tZXNzYWdlcy53cmFwcGVyKTtcbiAgICAgICAgICAgIHRoaXMucmVuZGVyZXIuaGlkZUJ1dHRvbnModGhpcy5nYXRld2F5Lmhvc3RlZF9maWVsZHMud3JhcHBlcik7XG4gICAgICAgICAgICBqUXVlcnkoJyNwbGFjZV9vcmRlcicpLnNob3coKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGpRdWVyeSgnI3BsYWNlX29yZGVyJykuaGlkZSgpO1xuICAgICAgICAgICAgaWYgKGN1cnJlbnRQYXltZW50TWV0aG9kID09PSAncHBjcC1nYXRld2F5Jykge1xuICAgICAgICAgICAgICAgIHRoaXMucmVuZGVyZXIuc2hvd0J1dHRvbnModGhpcy5nYXRld2F5LmJ1dHRvbi53cmFwcGVyKTtcbiAgICAgICAgICAgICAgICB0aGlzLnJlbmRlcmVyLnNob3dCdXR0b25zKHRoaXMuZ2F0ZXdheS5tZXNzYWdlcy53cmFwcGVyKTtcbiAgICAgICAgICAgICAgICB0aGlzLm1lc3NhZ2VzLnJlbmRlcigpO1xuICAgICAgICAgICAgICAgIHRoaXMucmVuZGVyZXIuaGlkZUJ1dHRvbnModGhpcy5nYXRld2F5Lmhvc3RlZF9maWVsZHMud3JhcHBlcik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoY3VycmVudFBheW1lbnRNZXRob2QgPT09ICdwcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXknKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5yZW5kZXJlci5oaWRlQnV0dG9ucyh0aGlzLmdhdGV3YXkuYnV0dG9uLndyYXBwZXIpO1xuICAgICAgICAgICAgICAgIHRoaXMucmVuZGVyZXIuaGlkZUJ1dHRvbnModGhpcy5nYXRld2F5Lm1lc3NhZ2VzLndyYXBwZXIpO1xuICAgICAgICAgICAgICAgIHRoaXMucmVuZGVyZXIuc2hvd0J1dHRvbnModGhpcy5nYXRld2F5Lmhvc3RlZF9maWVsZHMud3JhcHBlcik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IFBheU5vd0Jvb3RzdHJhcDtcbiIsImNsYXNzIFJlbmRlcmVyIHtcbiAgICBjb25zdHJ1Y3RvcihjcmVkaXRDYXJkUmVuZGVyZXIsIGRlZmF1bHRDb25maWcpIHtcbiAgICAgICAgdGhpcy5kZWZhdWx0Q29uZmlnID0gZGVmYXVsdENvbmZpZztcbiAgICAgICAgdGhpcy5jcmVkaXRDYXJkUmVuZGVyZXIgPSBjcmVkaXRDYXJkUmVuZGVyZXI7XG4gICAgfVxuXG4gICAgcmVuZGVyKHdyYXBwZXIsIGhvc3RlZEZpZWxkc1dyYXBwZXIsIGNvbnRleHRDb25maWcpIHtcblxuICAgICAgICB0aGlzLnJlbmRlckJ1dHRvbnMod3JhcHBlciwgY29udGV4dENvbmZpZyk7XG4gICAgICAgIHRoaXMuY3JlZGl0Q2FyZFJlbmRlcmVyLnJlbmRlcihob3N0ZWRGaWVsZHNXcmFwcGVyLCBjb250ZXh0Q29uZmlnKTtcbiAgICB9XG5cbiAgICByZW5kZXJCdXR0b25zKHdyYXBwZXIsIGNvbnRleHRDb25maWcpIHtcbiAgICAgICAgaWYgKCEgZG9jdW1lbnQucXVlcnlTZWxlY3Rvcih3cmFwcGVyKSB8fCB0aGlzLmlzQWxyZWFkeVJlbmRlcmVkKHdyYXBwZXIpIHx8ICd1bmRlZmluZWQnID09PSB0eXBlb2YgcGF5cGFsLkJ1dHRvbnMgKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBzdHlsZSA9IHdyYXBwZXIgPT09IHRoaXMuZGVmYXVsdENvbmZpZy5idXR0b24ud3JhcHBlciA/IHRoaXMuZGVmYXVsdENvbmZpZy5idXR0b24uc3R5bGUgOiB0aGlzLmRlZmF1bHRDb25maWcuYnV0dG9uLm1pbmlfY2FydF9zdHlsZTtcbiAgICAgICAgcGF5cGFsLkJ1dHRvbnMoe1xuICAgICAgICAgICAgc3R5bGUsXG4gICAgICAgICAgICAuLi5jb250ZXh0Q29uZmlnLFxuICAgICAgICB9KS5yZW5kZXIod3JhcHBlcik7XG4gICAgfVxuXG4gICAgaXNBbHJlYWR5UmVuZGVyZWQod3JhcHBlcikge1xuICAgICAgICByZXR1cm4gZG9jdW1lbnQucXVlcnlTZWxlY3Rvcih3cmFwcGVyKS5oYXNDaGlsZE5vZGVzKCk7XG4gICAgfVxuXG4gICAgaGlkZUJ1dHRvbnMoZWxlbWVudCkge1xuICAgICAgICBjb25zdCBkb21FbGVtZW50ID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcihlbGVtZW50KTtcbiAgICAgICAgaWYgKCEgZG9tRWxlbWVudCApIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICBkb21FbGVtZW50LnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIHNob3dCdXR0b25zKGVsZW1lbnQpIHtcbiAgICAgICAgY29uc3QgZG9tRWxlbWVudCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoZWxlbWVudCk7XG4gICAgICAgIGlmICghIGRvbUVsZW1lbnQgKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgZG9tRWxlbWVudC5zdHlsZS5kaXNwbGF5ID0gJ2Jsb2NrJztcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuXG4gICAgZGlzYWJsZUNyZWRpdENhcmRGaWVsZHMoKSB7XG4gICAgICAgIHRoaXMuY3JlZGl0Q2FyZFJlbmRlcmVyLmRpc2FibGVGaWVsZHMoKTtcbiAgICB9XG5cbiAgICBlbmFibGVDcmVkaXRDYXJkRmllbGRzKCkge1xuICAgICAgICB0aGlzLmNyZWRpdENhcmRSZW5kZXJlci5lbmFibGVGaWVsZHMoKTtcbiAgICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IFJlbmRlcmVyO1xuIiwiY29uc3QgZGNjSW5wdXRGYWN0b3J5ID0gKG9yaWdpbmFsKSA9PiB7XG4gICAgY29uc3Qgc3R5bGVzID0gd2luZG93LmdldENvbXB1dGVkU3R5bGUob3JpZ2luYWwpO1xuICAgIGNvbnN0IG5ld0VsZW1lbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdzcGFuJyk7XG4gICAgbmV3RWxlbWVudC5zZXRBdHRyaWJ1dGUoJ2lkJywgb3JpZ2luYWwuaWQpO1xuICAgIE9iamVjdC52YWx1ZXMoc3R5bGVzKS5mb3JFYWNoKCAocHJvcCkgPT4ge1xuICAgICAgICBpZiAoISBzdHlsZXNbcHJvcF0gfHwgISBpc05hTihwcm9wKSApIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBuZXdFbGVtZW50LnN0eWxlLnNldFByb3BlcnR5KHByb3AsJycgKyBzdHlsZXNbcHJvcF0pO1xuICAgIH0pO1xuICAgIHJldHVybiBuZXdFbGVtZW50O1xufVxuXG5leHBvcnQgZGVmYXVsdCBkY2NJbnB1dEZhY3Rvcnk7IiwiaW1wb3J0IGRjY0lucHV0RmFjdG9yeSBmcm9tIFwiLi4vSGVscGVyL0RjY0lucHV0RmFjdG9yeVwiO1xuXG5jbGFzcyBDcmVkaXRDYXJkUmVuZGVyZXIge1xuXG4gICAgY29uc3RydWN0b3IoZGVmYXVsdENvbmZpZywgZXJyb3JIYW5kbGVyLCBzcGlubmVyKSB7XG4gICAgICAgIHRoaXMuZGVmYXVsdENvbmZpZyA9IGRlZmF1bHRDb25maWc7XG4gICAgICAgIHRoaXMuZXJyb3JIYW5kbGVyID0gZXJyb3JIYW5kbGVyO1xuICAgICAgICB0aGlzLnNwaW5uZXIgPSBzcGlubmVyO1xuICAgICAgICB0aGlzLmNhcmRWYWxpZCA9IGZhbHNlO1xuICAgICAgICB0aGlzLmZvcm1WYWxpZCA9IGZhbHNlO1xuICAgICAgICB0aGlzLmN1cnJlbnRIb3N0ZWRGaWVsZHNJbnN0YW5jZSA9IG51bGw7XG4gICAgICAgIHRoaXMuZm9ybVN1Ym1pc3Npb25TdWJzY3JpYmVkID0gZmFsc2U7XG4gICAgfVxuXG4gICAgcmVuZGVyKHdyYXBwZXIsIGNvbnRleHRDb25maWcpIHtcblxuICAgICAgICBpZiAoXG4gICAgICAgICAgICAoXG4gICAgICAgICAgICAgICAgdGhpcy5kZWZhdWx0Q29uZmlnLmNvbnRleHQgIT09ICdjaGVja291dCdcbiAgICAgICAgICAgICAgICAmJiB0aGlzLmRlZmF1bHRDb25maWcuY29udGV4dCAhPT0gJ3BheS1ub3cnXG4gICAgICAgICAgICApXG4gICAgICAgICAgICB8fCB3cmFwcGVyID09PSBudWxsXG4gICAgICAgICAgICB8fCBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKHdyYXBwZXIpID09PSBudWxsXG4gICAgICAgICkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGlmIChcbiAgICAgICAgICAgIHR5cGVvZiBwYXlwYWwuSG9zdGVkRmllbGRzID09PSAndW5kZWZpbmVkJ1xuICAgICAgICAgICAgfHwgISBwYXlwYWwuSG9zdGVkRmllbGRzLmlzRWxpZ2libGUoKVxuICAgICAgICApIHtcbiAgICAgICAgICAgIGNvbnN0IHdyYXBwZXJFbGVtZW50ID0gZG9jdW1lbnQucXVlcnlTZWxlY3Rvcih3cmFwcGVyKTtcbiAgICAgICAgICAgIHdyYXBwZXJFbGVtZW50LnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQod3JhcHBlckVsZW1lbnQpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRoaXMuY3VycmVudEhvc3RlZEZpZWxkc0luc3RhbmNlKSB7XG4gICAgICAgICAgICB0aGlzLmN1cnJlbnRIb3N0ZWRGaWVsZHNJbnN0YW5jZS50ZWFyZG93bigpXG4gICAgICAgICAgICAgICAgLmNhdGNoKGVyciA9PiBjb25zb2xlLmVycm9yKGBIb3N0ZWQgZmllbGRzIHRlYXJkb3duIGVycm9yOiAke2Vycn1gKSk7XG4gICAgICAgICAgICB0aGlzLmN1cnJlbnRIb3N0ZWRGaWVsZHNJbnN0YW5jZSA9IG51bGw7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBnYXRlV2F5Qm94ID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignLnBheW1lbnRfYm94LnBheW1lbnRfbWV0aG9kX3BwY3AtY3JlZGl0LWNhcmQtZ2F0ZXdheScpO1xuICAgICAgICBjb25zdCBvbGREaXNwbGF5U3R5bGUgPSBnYXRlV2F5Qm94LnN0eWxlLmRpc3BsYXk7XG4gICAgICAgIGdhdGVXYXlCb3guc3R5bGUuZGlzcGxheSA9ICdibG9jayc7XG5cbiAgICAgICAgY29uc3QgaGlkZURjY0dhdGV3YXkgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjcHBjcC1oaWRlLWRjYycpO1xuICAgICAgICBpZiAoaGlkZURjY0dhdGV3YXkpIHtcbiAgICAgICAgICAgIGhpZGVEY2NHYXRld2F5LnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQoaGlkZURjY0dhdGV3YXkpO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgY2FyZE51bWJlckZpZWxkID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI3BwY3AtY3JlZGl0LWNhcmQtZ2F0ZXdheS1jYXJkLW51bWJlcicpO1xuXG4gICAgICAgIGNvbnN0IHN0eWxlc1JhdyA9IHdpbmRvdy5nZXRDb21wdXRlZFN0eWxlKGNhcmROdW1iZXJGaWVsZCk7XG4gICAgICAgIGxldCBzdHlsZXMgPSB7fTtcbiAgICAgICAgT2JqZWN0LnZhbHVlcyhzdHlsZXNSYXcpLmZvckVhY2goIChwcm9wKSA9PiB7XG4gICAgICAgICAgICBpZiAoISBzdHlsZXNSYXdbcHJvcF0pIHtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBzdHlsZXNbcHJvcF0gPSAnJyArIHN0eWxlc1Jhd1twcm9wXTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgY29uc3QgY2FyZE51bWJlciA9IGRjY0lucHV0RmFjdG9yeShjYXJkTnVtYmVyRmllbGQpO1xuICAgICAgICBjYXJkTnVtYmVyRmllbGQucGFyZW50Tm9kZS5yZXBsYWNlQ2hpbGQoY2FyZE51bWJlciwgY2FyZE51bWJlckZpZWxkKTtcblxuICAgICAgICBjb25zdCBjYXJkRXhwaXJ5RmllbGQgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjcHBjcC1jcmVkaXQtY2FyZC1nYXRld2F5LWNhcmQtZXhwaXJ5Jyk7XG4gICAgICAgIGNvbnN0IGNhcmRFeHBpcnkgPSBkY2NJbnB1dEZhY3RvcnkoY2FyZEV4cGlyeUZpZWxkKTtcbiAgICAgICAgY2FyZEV4cGlyeUZpZWxkLnBhcmVudE5vZGUucmVwbGFjZUNoaWxkKGNhcmRFeHBpcnksIGNhcmRFeHBpcnlGaWVsZCk7XG5cbiAgICAgICAgY29uc3QgY2FyZENvZGVGaWVsZCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNwcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXktY2FyZC1jdmMnKTtcbiAgICAgICAgY29uc3QgY2FyZENvZGUgPSBkY2NJbnB1dEZhY3RvcnkoY2FyZENvZGVGaWVsZCk7XG4gICAgICAgIGNhcmRDb2RlRmllbGQucGFyZW50Tm9kZS5yZXBsYWNlQ2hpbGQoY2FyZENvZGUsIGNhcmRDb2RlRmllbGQpO1xuXG4gICAgICAgIGdhdGVXYXlCb3guc3R5bGUuZGlzcGxheSA9IG9sZERpc3BsYXlTdHlsZTtcblxuICAgICAgICBjb25zdCBmb3JtV3JhcHBlciA9ICcucGF5bWVudF9ib3ggcGF5bWVudF9tZXRob2RfcHBjcC1jcmVkaXQtY2FyZC1nYXRld2F5JztcbiAgICAgICAgaWYgKFxuICAgICAgICAgICAgdGhpcy5kZWZhdWx0Q29uZmlnLmVuZm9yY2VfdmF1bHRcbiAgICAgICAgICAgICYmIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoZm9ybVdyYXBwZXIgKyAnIC5wcGNwLWNyZWRpdC1jYXJkLXZhdWx0JylcbiAgICAgICAgKSB7XG4gICAgICAgICAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKGZvcm1XcmFwcGVyICsgJyAucHBjcC1jcmVkaXQtY2FyZC12YXVsdCcpLmNoZWNrZWQgPSB0cnVlO1xuICAgICAgICAgICAgZG9jdW1lbnQucXVlcnlTZWxlY3Rvcihmb3JtV3JhcHBlciArICcgLnBwY3AtY3JlZGl0LWNhcmQtdmF1bHQnKS5zZXRBdHRyaWJ1dGUoJ2Rpc2FibGVkJywgdHJ1ZSk7XG4gICAgICAgIH1cbiAgICAgICAgcGF5cGFsLkhvc3RlZEZpZWxkcy5yZW5kZXIoe1xuICAgICAgICAgICAgY3JlYXRlT3JkZXI6IGNvbnRleHRDb25maWcuY3JlYXRlT3JkZXIsXG4gICAgICAgICAgICBzdHlsZXM6IHtcbiAgICAgICAgICAgICAgICAnaW5wdXQnOiBzdHlsZXNcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBmaWVsZHM6IHtcbiAgICAgICAgICAgICAgICBudW1iZXI6IHtcbiAgICAgICAgICAgICAgICAgICAgc2VsZWN0b3I6ICcjcHBjcC1jcmVkaXQtY2FyZC1nYXRld2F5LWNhcmQtbnVtYmVyJyxcbiAgICAgICAgICAgICAgICAgICAgcGxhY2Vob2xkZXI6IHRoaXMuZGVmYXVsdENvbmZpZy5ob3N0ZWRfZmllbGRzLmxhYmVscy5jcmVkaXRfY2FyZF9udW1iZXIsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBjdnY6IHtcbiAgICAgICAgICAgICAgICAgICAgc2VsZWN0b3I6ICcjcHBjcC1jcmVkaXQtY2FyZC1nYXRld2F5LWNhcmQtY3ZjJyxcbiAgICAgICAgICAgICAgICAgICAgcGxhY2Vob2xkZXI6IHRoaXMuZGVmYXVsdENvbmZpZy5ob3N0ZWRfZmllbGRzLmxhYmVscy5jdnYsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBleHBpcmF0aW9uRGF0ZToge1xuICAgICAgICAgICAgICAgICAgICBzZWxlY3RvcjogJyNwcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXktY2FyZC1leHBpcnknLFxuICAgICAgICAgICAgICAgICAgICBwbGFjZWhvbGRlcjogdGhpcy5kZWZhdWx0Q29uZmlnLmhvc3RlZF9maWVsZHMubGFiZWxzLm1tX3l5LFxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfSkudGhlbihob3N0ZWRGaWVsZHMgPT4ge1xuICAgICAgICAgICAgZG9jdW1lbnQuZGlzcGF0Y2hFdmVudChuZXcgQ3VzdG9tRXZlbnQoXCJob3N0ZWRfZmllbGRzX2xvYWRlZFwiKSk7XG4gICAgICAgICAgICB0aGlzLmN1cnJlbnRIb3N0ZWRGaWVsZHNJbnN0YW5jZSA9IGhvc3RlZEZpZWxkcztcblxuICAgICAgICAgICAgaG9zdGVkRmllbGRzLm9uKCdpbnB1dFN1Ym1pdFJlcXVlc3QnLCAoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5fc3VibWl0KGNvbnRleHRDb25maWcpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBob3N0ZWRGaWVsZHMub24oJ2NhcmRUeXBlQ2hhbmdlJywgKGV2ZW50KSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKCAhIGV2ZW50LmNhcmRzLmxlbmd0aCApIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5jYXJkVmFsaWQgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjb25zdCB2YWxpZENhcmRzID0gdGhpcy5kZWZhdWx0Q29uZmlnLmhvc3RlZF9maWVsZHMudmFsaWRfY2FyZHM7XG4gICAgICAgICAgICAgICAgdGhpcy5jYXJkVmFsaWQgPSB2YWxpZENhcmRzLmluZGV4T2YoZXZlbnQuY2FyZHNbMF0udHlwZSkgIT09IC0xO1xuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIGhvc3RlZEZpZWxkcy5vbigndmFsaWRpdHlDaGFuZ2UnLCAoZXZlbnQpID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCBmb3JtVmFsaWQgPSBPYmplY3Qua2V5cyhldmVudC5maWVsZHMpLmV2ZXJ5KGZ1bmN0aW9uIChrZXkpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGV2ZW50LmZpZWxkc1trZXldLmlzVmFsaWQ7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICB0aGlzLmZvcm1WYWxpZCA9IGZvcm1WYWxpZDtcblxuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIGlmICghdGhpcy5mb3JtU3VibWlzc2lvblN1YnNjcmliZWQpIHtcbiAgICAgICAgICAgICAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKHdyYXBwZXIgKyAnIGJ1dHRvbicpLmFkZEV2ZW50TGlzdGVuZXIoXG4gICAgICAgICAgICAgICAgICAgICdjbGljaycsXG4gICAgICAgICAgICAgICAgICAgIGV2ZW50ID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9zdWJtaXQoY29udGV4dENvbmZpZyk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgIHRoaXMuZm9ybVN1Ym1pc3Npb25TdWJzY3JpYmVkID0gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG5cbiAgICAgICAgZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI3BheW1lbnRfbWV0aG9kX3BwY3AtY3JlZGl0LWNhcmQtZ2F0ZXdheScpLmFkZEV2ZW50TGlzdGVuZXIoXG4gICAgICAgICAgICAnY2xpY2snLFxuICAgICAgICAgICAgKCkgPT4ge1xuICAgICAgICAgICAgICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJ2xhYmVsW2Zvcj1wcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXktY2FyZC1udW1iZXJdJykuY2xpY2soKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgKVxuICAgIH1cblxuICAgIGRpc2FibGVGaWVsZHMoKSB7XG4gICAgICAgIGlmKCB0aGlzLmN1cnJlbnRIb3N0ZWRGaWVsZHNJbnN0YW5jZSkge1xuICAgICAgICAgICAgdGhpcy5jdXJyZW50SG9zdGVkRmllbGRzSW5zdGFuY2Uuc2V0QXR0cmlidXRlKHtcbiAgICAgICAgICAgICAgICBmaWVsZDogJ251bWJlcicsXG4gICAgICAgICAgICAgICAgYXR0cmlidXRlOiAnZGlzYWJsZWQnXG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgdGhpcy5jdXJyZW50SG9zdGVkRmllbGRzSW5zdGFuY2Uuc2V0QXR0cmlidXRlKHtcbiAgICAgICAgICAgICAgICBmaWVsZDogJ2N2dicsXG4gICAgICAgICAgICAgICAgYXR0cmlidXRlOiAnZGlzYWJsZWQnXG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgdGhpcy5jdXJyZW50SG9zdGVkRmllbGRzSW5zdGFuY2Uuc2V0QXR0cmlidXRlKHtcbiAgICAgICAgICAgICAgICBmaWVsZDogJ2V4cGlyYXRpb25EYXRlJyxcbiAgICAgICAgICAgICAgICBhdHRyaWJ1dGU6ICdkaXNhYmxlZCdcbiAgICAgICAgICAgIH0pXG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBlbmFibGVGaWVsZHMoKSB7XG4gICAgICAgIGlmKCB0aGlzLmN1cnJlbnRIb3N0ZWRGaWVsZHNJbnN0YW5jZSkge1xuICAgICAgICAgICAgdGhpcy5jdXJyZW50SG9zdGVkRmllbGRzSW5zdGFuY2UucmVtb3ZlQXR0cmlidXRlKHtcbiAgICAgICAgICAgICAgICBmaWVsZDogJ251bWJlcicsXG4gICAgICAgICAgICAgICAgYXR0cmlidXRlOiAnZGlzYWJsZWQnXG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgdGhpcy5jdXJyZW50SG9zdGVkRmllbGRzSW5zdGFuY2UucmVtb3ZlQXR0cmlidXRlKHtcbiAgICAgICAgICAgICAgICBmaWVsZDogJ2N2dicsXG4gICAgICAgICAgICAgICAgYXR0cmlidXRlOiAnZGlzYWJsZWQnXG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgdGhpcy5jdXJyZW50SG9zdGVkRmllbGRzSW5zdGFuY2UucmVtb3ZlQXR0cmlidXRlKHtcbiAgICAgICAgICAgICAgICBmaWVsZDogJ2V4cGlyYXRpb25EYXRlJyxcbiAgICAgICAgICAgICAgICBhdHRyaWJ1dGU6ICdkaXNhYmxlZCdcbiAgICAgICAgICAgIH0pXG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBfc3VibWl0KGNvbnRleHRDb25maWcpIHtcbiAgICAgICAgdGhpcy5zcGlubmVyLmJsb2NrKCk7XG4gICAgICAgIHRoaXMuZXJyb3JIYW5kbGVyLmNsZWFyKCk7XG5cbiAgICAgICAgaWYgKHRoaXMuZm9ybVZhbGlkICYmIHRoaXMuY2FyZFZhbGlkKSB7XG4gICAgICAgICAgICBjb25zdCBzYXZlX2NhcmQgPSB0aGlzLmRlZmF1bHRDb25maWcuc2F2ZV9jYXJkID8gdHJ1ZSA6IGZhbHNlO1xuICAgICAgICAgICAgbGV0IHZhdWx0ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3BwY3AtY3JlZGl0LWNhcmQtdmF1bHQnKSA/XG4gICAgICAgICAgICAgICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3BwY3AtY3JlZGl0LWNhcmQtdmF1bHQnKS5jaGVja2VkIDogc2F2ZV9jYXJkO1xuICAgICAgICAgICAgaWYgKHRoaXMuZGVmYXVsdENvbmZpZy5lbmZvcmNlX3ZhdWx0KSB7XG4gICAgICAgICAgICAgICAgdmF1bHQgPSB0cnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29uc3QgY29udGluZ2VuY3kgPSB0aGlzLmRlZmF1bHRDb25maWcuaG9zdGVkX2ZpZWxkcy5jb250aW5nZW5jeTtcbiAgICAgICAgICAgIGNvbnN0IGhvc3RlZEZpZWxkc0RhdGEgPSB7XG4gICAgICAgICAgICAgICAgdmF1bHQ6IHZhdWx0XG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgaWYgKGNvbnRpbmdlbmN5ICE9PSAnTk9fM0RfU0VDVVJFJykge1xuICAgICAgICAgICAgICAgIGhvc3RlZEZpZWxkc0RhdGEuY29udGluZ2VuY2llcyA9IFtjb250aW5nZW5jeV07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLmN1cnJlbnRIb3N0ZWRGaWVsZHNJbnN0YW5jZS5zdWJtaXQoaG9zdGVkRmllbGRzRGF0YSkudGhlbigocGF5bG9hZCkgPT4ge1xuICAgICAgICAgICAgICAgIHBheWxvYWQub3JkZXJJRCA9IHBheWxvYWQub3JkZXJJZDtcbiAgICAgICAgICAgICAgICB0aGlzLnNwaW5uZXIudW5ibG9jaygpO1xuICAgICAgICAgICAgICAgIHJldHVybiBjb250ZXh0Q29uZmlnLm9uQXBwcm92ZShwYXlsb2FkKTtcbiAgICAgICAgICAgIH0pLmNhdGNoKGVyciA9PiB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihlcnIpO1xuICAgICAgICAgICAgICAgIHRoaXMuc3Bpbm5lci51bmJsb2NrKCk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuc3Bpbm5lci51bmJsb2NrKCk7XG4gICAgICAgICAgICBjb25zdCBtZXNzYWdlID0gISB0aGlzLmNhcmRWYWxpZCA/IHRoaXMuZGVmYXVsdENvbmZpZy5ob3N0ZWRfZmllbGRzLmxhYmVscy5jYXJkX25vdF9zdXBwb3J0ZWQgOiB0aGlzLmRlZmF1bHRDb25maWcuaG9zdGVkX2ZpZWxkcy5sYWJlbHMuZmllbGRzX25vdF92YWxpZDtcbiAgICAgICAgICAgIHRoaXMuZXJyb3JIYW5kbGVyLm1lc3NhZ2UobWVzc2FnZSk7XG4gICAgICAgIH1cbiAgICB9XG59XG5leHBvcnQgZGVmYXVsdCBDcmVkaXRDYXJkUmVuZGVyZXI7XG4iLCJjb25zdCBzdG9yYWdlS2V5ID0gJ3BwY3AtZGF0YS1jbGllbnQtaWQnO1xuXG5jb25zdCB2YWxpZGF0ZVRva2VuID0gKHRva2VuLCB1c2VyKSA9PiB7XG4gICAgaWYgKCEgdG9rZW4pIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICBpZiAodG9rZW4udXNlciAhPT0gdXNlcikge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGNvbnN0IGN1cnJlbnRUaW1lID0gbmV3IERhdGUoKS5nZXRUaW1lKCk7XG4gICAgY29uc3QgaXNFeHBpcmVkID0gY3VycmVudFRpbWUgPj0gdG9rZW4uZXhwaXJhdGlvbiAqIDEwMDA7XG4gICAgcmV0dXJuICEgaXNFeHBpcmVkO1xufVxuXG5jb25zdCBzdG9yZWRUb2tlbkZvclVzZXIgPSAodXNlcikgPT4ge1xuICAgIGNvbnN0IHRva2VuID0gSlNPTi5wYXJzZShzZXNzaW9uU3RvcmFnZS5nZXRJdGVtKHN0b3JhZ2VLZXkpKTtcbiAgICBpZiAodmFsaWRhdGVUb2tlbih0b2tlbiwgdXNlcikpIHtcbiAgICAgICAgcmV0dXJuIHRva2VuLnRva2VuO1xuICAgIH1cbiAgICByZXR1cm4gbnVsbDtcbn1cblxuY29uc3Qgc3RvcmVUb2tlbiA9ICh0b2tlbikgPT4ge1xuICAgIHNlc3Npb25TdG9yYWdlLnNldEl0ZW0oc3RvcmFnZUtleSwgSlNPTi5zdHJpbmdpZnkodG9rZW4pKTtcbn1cblxuY29uc3QgZGF0YUNsaWVudElkQXR0cmlidXRlSGFuZGxlciA9IChzY3JpcHQsIGNvbmZpZykgPT4ge1xuICAgIGZldGNoKGNvbmZpZy5lbmRwb2ludCwge1xuICAgICAgICBtZXRob2Q6ICdQT1NUJyxcbiAgICAgICAgYm9keTogSlNPTi5zdHJpbmdpZnkoe1xuICAgICAgICAgICAgbm9uY2U6IGNvbmZpZy5ub25jZVxuICAgICAgICB9KVxuICAgIH0pLnRoZW4oKHJlcyk9PntcbiAgICAgICAgcmV0dXJuIHJlcy5qc29uKCk7XG4gICAgfSkudGhlbigoZGF0YSk9PntcbiAgICAgICAgY29uc3QgaXNWYWxpZCA9IHZhbGlkYXRlVG9rZW4oZGF0YSwgY29uZmlnLnVzZXIpO1xuICAgICAgICBpZiAoIWlzVmFsaWQpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBzdG9yZVRva2VuKGRhdGEpO1xuICAgICAgICBzY3JpcHQuc2V0QXR0cmlidXRlKCdkYXRhLWNsaWVudC10b2tlbicsIGRhdGEudG9rZW4pO1xuICAgICAgICBkb2N1bWVudC5ib2R5LmFwcGVuZChzY3JpcHQpO1xuICAgIH0pO1xufVxuXG5leHBvcnQgZGVmYXVsdCBkYXRhQ2xpZW50SWRBdHRyaWJ1dGVIYW5kbGVyO1xuIiwiY2xhc3MgTWVzc2FnZVJlbmRlcmVyIHtcblxuICAgIGNvbnN0cnVjdG9yKGNvbmZpZykge1xuICAgICAgICB0aGlzLmNvbmZpZyA9IGNvbmZpZztcbiAgICB9XG5cbiAgICByZW5kZXIoKSB7XG4gICAgICAgIGlmICghIHRoaXMuc2hvdWxkUmVuZGVyKCkpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIHBheXBhbC5NZXNzYWdlcyh7XG4gICAgICAgICAgICBhbW91bnQ6IHRoaXMuY29uZmlnLmFtb3VudCxcbiAgICAgICAgICAgIHBsYWNlbWVudDogdGhpcy5jb25maWcucGxhY2VtZW50LFxuICAgICAgICAgICAgc3R5bGU6IHRoaXMuY29uZmlnLnN0eWxlXG4gICAgICAgIH0pLnJlbmRlcih0aGlzLmNvbmZpZy53cmFwcGVyKTtcbiAgICB9XG5cbiAgICByZW5kZXJXaXRoQW1vdW50KGFtb3VudCkge1xuXG4gICAgICAgIGlmICghIHRoaXMuc2hvdWxkUmVuZGVyKCkpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IG5ld1dyYXBwZXIgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICAgICAgbmV3V3JhcHBlci5zZXRBdHRyaWJ1dGUoJ2lkJywgdGhpcy5jb25maWcud3JhcHBlci5yZXBsYWNlKCcjJywgJycpKTtcblxuICAgICAgICBjb25zdCBzaWJsaW5nID0gZG9jdW1lbnQucXVlcnlTZWxlY3Rvcih0aGlzLmNvbmZpZy53cmFwcGVyKS5uZXh0U2libGluZztcbiAgICAgICAgZG9jdW1lbnQucXVlcnlTZWxlY3Rvcih0aGlzLmNvbmZpZy53cmFwcGVyKS5wYXJlbnRFbGVtZW50LnJlbW92ZUNoaWxkKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IodGhpcy5jb25maWcud3JhcHBlcikpO1xuICAgICAgICBzaWJsaW5nLnBhcmVudEVsZW1lbnQuaW5zZXJ0QmVmb3JlKG5ld1dyYXBwZXIsIHNpYmxpbmcpO1xuICAgICAgICBwYXlwYWwuTWVzc2FnZXMoe1xuICAgICAgICAgICAgYW1vdW50LFxuICAgICAgICAgICAgcGxhY2VtZW50OiB0aGlzLmNvbmZpZy5wbGFjZW1lbnQsXG4gICAgICAgICAgICBzdHlsZTogdGhpcy5jb25maWcuc3R5bGVcbiAgICAgICAgfSkucmVuZGVyKHRoaXMuY29uZmlnLndyYXBwZXIpO1xuICAgIH1cblxuICAgIHNob3VsZFJlbmRlcigpIHtcblxuICAgICAgICBpZiAodHlwZW9mIHBheXBhbC5NZXNzYWdlcyA9PT0gJ3VuZGVmaW5lZCcgfHwgdHlwZW9mIHRoaXMuY29uZmlnLndyYXBwZXIgPT09ICd1bmRlZmluZWQnICkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIGlmICghIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IodGhpcy5jb25maWcud3JhcHBlcikpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG59XG5leHBvcnQgZGVmYXVsdCBNZXNzYWdlUmVuZGVyZXI7IiwiY2xhc3MgU3Bpbm5lciB7XG5cbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgdGhpcy50YXJnZXQgPSAnZm9ybS53b29jb21tZXJjZS1jaGVja291dCc7XG4gICAgfVxuXG4gICAgc2V0VGFyZ2V0KHRhcmdldCkge1xuICAgICAgICB0aGlzLnRhcmdldCA9IHRhcmdldDtcbiAgICB9XG5cbiAgICBibG9jaygpIHtcblxuICAgICAgICBqUXVlcnkoIHRoaXMudGFyZ2V0ICkuYmxvY2soe1xuICAgICAgICAgICAgbWVzc2FnZTogbnVsbCxcbiAgICAgICAgICAgIG92ZXJsYXlDU1M6IHtcbiAgICAgICAgICAgICAgICBiYWNrZ3JvdW5kOiAnI2ZmZicsXG4gICAgICAgICAgICAgICAgb3BhY2l0eTogMC42XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHVuYmxvY2soKSB7XG5cbiAgICAgICAgalF1ZXJ5KCB0aGlzLnRhcmdldCApLnVuYmxvY2soKTtcbiAgICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IFNwaW5uZXI7XG4iLCJpbXBvcnQgTWluaUNhcnRCb290c3RhcCBmcm9tICcuL21vZHVsZXMvQ29udGV4dEJvb3RzdHJhcC9NaW5pQ2FydEJvb3RzdGFwJztcbmltcG9ydCBTaW5nbGVQcm9kdWN0Qm9vdHN0YXAgZnJvbSAnLi9tb2R1bGVzL0NvbnRleHRCb290c3RyYXAvU2luZ2xlUHJvZHVjdEJvb3RzdGFwJztcbmltcG9ydCBDYXJ0Qm9vdHN0cmFwIGZyb20gJy4vbW9kdWxlcy9Db250ZXh0Qm9vdHN0cmFwL0NhcnRCb290c3RhcCc7XG5pbXBvcnQgQ2hlY2tvdXRCb290c3RhcCBmcm9tICcuL21vZHVsZXMvQ29udGV4dEJvb3RzdHJhcC9DaGVja291dEJvb3RzdGFwJztcbmltcG9ydCBQYXlOb3dCb290c3RyYXAgZnJvbSBcIi4vbW9kdWxlcy9Db250ZXh0Qm9vdHN0cmFwL1BheU5vd0Jvb3RzdHJhcFwiO1xuaW1wb3J0IFJlbmRlcmVyIGZyb20gJy4vbW9kdWxlcy9SZW5kZXJlci9SZW5kZXJlcic7XG5pbXBvcnQgRXJyb3JIYW5kbGVyIGZyb20gJy4vbW9kdWxlcy9FcnJvckhhbmRsZXInO1xuaW1wb3J0IENyZWRpdENhcmRSZW5kZXJlciBmcm9tIFwiLi9tb2R1bGVzL1JlbmRlcmVyL0NyZWRpdENhcmRSZW5kZXJlclwiO1xuaW1wb3J0IGRhdGFDbGllbnRJZEF0dHJpYnV0ZUhhbmRsZXIgZnJvbSBcIi4vbW9kdWxlcy9EYXRhQ2xpZW50SWRBdHRyaWJ1dGVIYW5kbGVyXCI7XG5pbXBvcnQgTWVzc2FnZVJlbmRlcmVyIGZyb20gXCIuL21vZHVsZXMvUmVuZGVyZXIvTWVzc2FnZVJlbmRlcmVyXCI7XG5pbXBvcnQgU3Bpbm5lciBmcm9tIFwiLi9tb2R1bGVzL0hlbHBlci9TcGlubmVyXCI7XG5cbmNvbnN0IGJvb3RzdHJhcCA9ICgpID0+IHtcbiAgICBjb25zdCBlcnJvckhhbmRsZXIgPSBuZXcgRXJyb3JIYW5kbGVyKFBheVBhbENvbW1lcmNlR2F0ZXdheS5sYWJlbHMuZXJyb3IuZ2VuZXJpYyk7XG4gICAgY29uc3Qgc3Bpbm5lciA9IG5ldyBTcGlubmVyKCk7XG4gICAgY29uc3QgY3JlZGl0Q2FyZFJlbmRlcmVyID0gbmV3IENyZWRpdENhcmRSZW5kZXJlcihQYXlQYWxDb21tZXJjZUdhdGV3YXksIGVycm9ySGFuZGxlciwgc3Bpbm5lcik7XG4gICAgY29uc3QgcmVuZGVyZXIgPSBuZXcgUmVuZGVyZXIoY3JlZGl0Q2FyZFJlbmRlcmVyLCBQYXlQYWxDb21tZXJjZUdhdGV3YXkpO1xuICAgIGNvbnN0IG1lc3NhZ2VSZW5kZXJlciA9IG5ldyBNZXNzYWdlUmVuZGVyZXIoUGF5UGFsQ29tbWVyY2VHYXRld2F5Lm1lc3NhZ2VzKTtcbiAgICBjb25zdCBjb250ZXh0ID0gUGF5UGFsQ29tbWVyY2VHYXRld2F5LmNvbnRleHQ7XG4gICAgaWYgKGNvbnRleHQgPT09ICdtaW5pLWNhcnQnIHx8IGNvbnRleHQgPT09ICdwcm9kdWN0Jykge1xuICAgICAgICBpZiAoUGF5UGFsQ29tbWVyY2VHYXRld2F5Lm1pbmlfY2FydF9idXR0b25zX2VuYWJsZWQgPT09ICcxJykge1xuICAgICAgICAgICAgY29uc3QgbWluaUNhcnRCb290c3RyYXAgPSBuZXcgTWluaUNhcnRCb290c3RhcChcbiAgICAgICAgICAgICAgICBQYXlQYWxDb21tZXJjZUdhdGV3YXksXG4gICAgICAgICAgICAgICAgcmVuZGVyZXJcbiAgICAgICAgICAgICk7XG5cbiAgICAgICAgICAgIG1pbmlDYXJ0Qm9vdHN0cmFwLmluaXQoKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGlmIChjb250ZXh0ID09PSAncHJvZHVjdCcgJiYgUGF5UGFsQ29tbWVyY2VHYXRld2F5LnNpbmdsZV9wcm9kdWN0X2J1dHRvbnNfZW5hYmxlZCA9PT0gJzEnKSB7XG4gICAgICAgIGNvbnN0IHNpbmdsZVByb2R1Y3RCb290c3RyYXAgPSBuZXcgU2luZ2xlUHJvZHVjdEJvb3RzdGFwKFxuICAgICAgICAgICAgUGF5UGFsQ29tbWVyY2VHYXRld2F5LFxuICAgICAgICAgICAgcmVuZGVyZXIsXG4gICAgICAgICAgICBtZXNzYWdlUmVuZGVyZXIsXG4gICAgICAgICk7XG5cbiAgICAgICAgc2luZ2xlUHJvZHVjdEJvb3RzdHJhcC5pbml0KCk7XG4gICAgfVxuXG4gICAgaWYgKGNvbnRleHQgPT09ICdjYXJ0Jykge1xuICAgICAgICBjb25zdCBjYXJ0Qm9vdHN0cmFwID0gbmV3IENhcnRCb290c3RyYXAoXG4gICAgICAgICAgICBQYXlQYWxDb21tZXJjZUdhdGV3YXksXG4gICAgICAgICAgICByZW5kZXJlcixcbiAgICAgICAgKTtcblxuICAgICAgICBjYXJ0Qm9vdHN0cmFwLmluaXQoKTtcbiAgICB9XG5cbiAgICBpZiAoY29udGV4dCA9PT0gJ2NoZWNrb3V0Jykge1xuICAgICAgICBjb25zdCBjaGVja291dEJvb3RzdGFwID0gbmV3IENoZWNrb3V0Qm9vdHN0YXAoXG4gICAgICAgICAgICBQYXlQYWxDb21tZXJjZUdhdGV3YXksXG4gICAgICAgICAgICByZW5kZXJlcixcbiAgICAgICAgICAgIG1lc3NhZ2VSZW5kZXJlcixcbiAgICAgICAgICAgIHNwaW5uZXJcbiAgICAgICAgKTtcblxuICAgICAgICBjaGVja291dEJvb3RzdGFwLmluaXQoKTtcbiAgICB9XG5cbiAgICBpZiAoY29udGV4dCA9PT0gJ3BheS1ub3cnICkge1xuICAgICAgICBjb25zdCBwYXlOb3dCb290c3RyYXAgPSBuZXcgUGF5Tm93Qm9vdHN0cmFwKFxuICAgICAgICAgICAgUGF5UGFsQ29tbWVyY2VHYXRld2F5LFxuICAgICAgICAgICAgcmVuZGVyZXIsXG4gICAgICAgICAgICBtZXNzYWdlUmVuZGVyZXIsXG4gICAgICAgICAgICBzcGlubmVyXG4gICAgICAgICk7XG4gICAgICAgIHBheU5vd0Jvb3RzdHJhcC5pbml0KCk7XG4gICAgfVxuXG4gICAgaWYgKGNvbnRleHQgIT09ICdjaGVja291dCcpIHtcbiAgICAgICAgbWVzc2FnZVJlbmRlcmVyLnJlbmRlcigpO1xuICAgIH1cbn07XG5kb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKFxuICAgICdET01Db250ZW50TG9hZGVkJyxcbiAgICAoKSA9PiB7XG4gICAgICAgIGlmICghdHlwZW9mIChQYXlQYWxDb21tZXJjZUdhdGV3YXkpKSB7XG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKCdQYXlQYWwgYnV0dG9uIGNvdWxkIG5vdCBiZSBjb25maWd1cmVkLicpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHNjcmlwdCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3NjcmlwdCcpO1xuXG4gICAgICAgIHNjcmlwdC5hZGRFdmVudExpc3RlbmVyKCdsb2FkJywgKGV2ZW50KSA9PiB7XG4gICAgICAgICAgICBib290c3RyYXAoKTtcbiAgICAgICAgfSk7XG4gICAgICAgIHNjcmlwdC5zZXRBdHRyaWJ1dGUoJ3NyYycsIFBheVBhbENvbW1lcmNlR2F0ZXdheS5idXR0b24udXJsKTtcbiAgICAgICAgT2JqZWN0LmVudHJpZXMoUGF5UGFsQ29tbWVyY2VHYXRld2F5LnNjcmlwdF9hdHRyaWJ1dGVzKS5mb3JFYWNoKFxuICAgICAgICAgICAgKGtleVZhbHVlKSA9PiB7XG4gICAgICAgICAgICAgICAgc2NyaXB0LnNldEF0dHJpYnV0ZShrZXlWYWx1ZVswXSwga2V5VmFsdWVbMV0pO1xuICAgICAgICAgICAgfVxuICAgICAgICApO1xuXG4gICAgICAgIGlmIChQYXlQYWxDb21tZXJjZUdhdGV3YXkuZGF0YV9jbGllbnRfaWQuc2V0X2F0dHJpYnV0ZSkge1xuICAgICAgICAgICAgZGF0YUNsaWVudElkQXR0cmlidXRlSGFuZGxlcihzY3JpcHQsIFBheVBhbENvbW1lcmNlR2F0ZXdheS5kYXRhX2NsaWVudF9pZCk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBkb2N1bWVudC5ib2R5LmFwcGVuZChzY3JpcHQpO1xuICAgIH0sXG4pO1xuIl0sIm5hbWVzIjpbIkVycm9ySGFuZGxlciIsImNvbnN0cnVjdG9yIiwiZ2VuZXJpY0Vycm9yVGV4dCIsIndyYXBwZXIiLCJkb2N1bWVudCIsInF1ZXJ5U2VsZWN0b3IiLCJtZXNzYWdlc0xpc3QiLCJnZW5lcmljRXJyb3IiLCJjbGFzc0xpc3QiLCJjb250YWlucyIsImNsZWFyIiwibWVzc2FnZSIsImFwcGVuZFByZXBhcmVkRXJyb3JNZXNzYWdlRWxlbWVudCIsImVycm9yTWVzc2FnZUVsZW1lbnQiLCJwcmVwYXJlTWVzc2FnZXNMaXN0IiwicmVwbGFjZVdpdGgiLCJ0ZXh0IiwicGVyc2lzdCIsIlN0cmluZyIsImxlbmd0aCIsIkVycm9yIiwiYWRkIiwicmVtb3ZlIiwibWVzc2FnZU5vZGUiLCJwcmVwYXJlTWVzc2FnZXNMaXN0SXRlbSIsImFwcGVuZENoaWxkIiwialF1ZXJ5Iiwic2Nyb2xsX3RvX25vdGljZXMiLCJjcmVhdGVFbGVtZW50Iiwic2V0QXR0cmlidXRlIiwibGkiLCJpbm5lckhUTUwiLCJzYW5pdGl6ZSIsInRleHRhcmVhIiwidmFsdWUiLCJyZXBsYWNlIiwiaW5uZXJUZXh0Iiwib25BcHByb3ZlIiwiY29udGV4dCIsImVycm9ySGFuZGxlciIsImRhdGEiLCJhY3Rpb25zIiwiZmV0Y2giLCJjb25maWciLCJhamF4IiwiYXBwcm92ZV9vcmRlciIsImVuZHBvaW50IiwibWV0aG9kIiwiYm9keSIsIkpTT04iLCJzdHJpbmdpZnkiLCJub25jZSIsIm9yZGVyX2lkIiwib3JkZXJJRCIsInRoZW4iLCJyZXMiLCJqc29uIiwic3VjY2VzcyIsInJlc3RhcnQiLCJjYXRjaCIsImVyciIsImxvY2F0aW9uIiwiaHJlZiIsInJlZGlyZWN0IiwicGF5ZXJEYXRhIiwicGF5ZXIiLCJQYXlQYWxDb21tZXJjZUdhdGV3YXkiLCJwaG9uZSIsInBob25lX3R5cGUiLCJwaG9uZV9udW1iZXIiLCJuYXRpb25hbF9udW1iZXIiLCJlbWFpbF9hZGRyZXNzIiwibmFtZSIsInN1cm5hbWUiLCJnaXZlbl9uYW1lIiwiYWRkcmVzcyIsImNvdW50cnlfY29kZSIsImFkZHJlc3NfbGluZV8xIiwiYWRkcmVzc19saW5lXzIiLCJhZG1pbl9hcmVhXzEiLCJhZG1pbl9hcmVhXzIiLCJwb3N0YWxfY29kZSIsIkNhcnRBY3Rpb25IYW5kbGVyIiwiY29uZmlndXJhdGlvbiIsImNyZWF0ZU9yZGVyIiwiYm5Db2RlIiwiYm5fY29kZXMiLCJjcmVhdGVfb3JkZXIiLCJwdXJjaGFzZV91bml0cyIsImJuX2NvZGUiLCJjb25zb2xlIiwiZXJyb3IiLCJpZCIsIm9uRXJyb3IiLCJNaW5pQ2FydEJvb3RzdGFwIiwiZ2F0ZXdheSIsInJlbmRlcmVyIiwiYWN0aW9uSGFuZGxlciIsImluaXQiLCJsYWJlbHMiLCJnZW5lcmljIiwicmVuZGVyIiwib24iLCJzaG91bGRSZW5kZXIiLCJidXR0b24iLCJtaW5pX2NhcnRfd3JhcHBlciIsImhvc3RlZF9maWVsZHMiLCJQcm9kdWN0IiwiVXBkYXRlQ2FydCIsInVwZGF0ZSIsIm9uUmVzb2x2ZSIsInByb2R1Y3RzIiwiUHJvbWlzZSIsInJlc29sdmUiLCJyZWplY3QiLCJyZXN1bHQiLCJyZXNvbHZlZCIsIkJ1dHRvbnNUb2dnbGVMaXN0ZW5lciIsImVsZW1lbnQiLCJzaG93Q2FsbGJhY2siLCJoaWRlQ2FsbGJhY2siLCJvYnNlcnZlciIsImF0dHJpYnV0ZXMiLCJjYWxsYmFjayIsIk11dGF0aW9uT2JzZXJ2ZXIiLCJvYnNlcnZlIiwiZGlzY29ubmVjdCIsInF1YW50aXR5IiwidmFyaWF0aW9ucyIsIlNpbmdsZVByb2R1Y3RBY3Rpb25IYW5kbGVyIiwidXBkYXRlQ2FydCIsInNob3dCdXR0b25DYWxsYmFjayIsImhpZGVCdXR0b25DYWxsYmFjayIsImZvcm1FbGVtZW50IiwiaGFzVmFyaWF0aW9ucyIsImdldFByb2R1Y3RzIiwiaXNHcm91cGVkUHJvZHVjdCIsInF0eSIsInF1ZXJ5U2VsZWN0b3JBbGwiLCJmb3JFYWNoIiwiZWxlbWVudE5hbWUiLCJnZXRBdHRyaWJ1dGUiLCJtYXRjaCIsInBhcnNlSW50IiwicHVzaCIsInByb21pc2UiLCJtYXAiLCJTaW5nbGVQcm9kdWN0Qm9vdHN0YXAiLCJtZXNzYWdlcyIsImhpZGVCdXR0b25zIiwiY2hhbmdlX2NhcnQiLCJzaG93QnV0dG9ucyIsInByaWNlVGV4dCIsImFtb3VudCIsInJlbmRlcldpdGhBbW91bnQiLCJDYXJ0Qm9vdHN0cmFwIiwic3Bpbm5lciIsImJsb2NrIiwidW5ibG9jayIsImNvZGUiLCJjbGljayIsIkNoZWNrb3V0QWN0aW9uSGFuZGxlciIsImZvcm1TZWxlY3RvciIsImZvcm1WYWx1ZXMiLCJzZXJpYWxpemUiLCJjcmVhdGVhY2NvdW50IiwiaXMiLCJmb3JtIiwiZG9tUGFyc2VyIiwiRE9NUGFyc2VyIiwicGFyc2VGcm9tU3RyaW5nIiwiaW5wdXQiLCJjdXN0b21faWQiLCJhcHBlbmQiLCJvbkNhbmNlbCIsIkNoZWNrb3V0Qm9vdHN0YXAiLCJzd2l0Y2hCZXR3ZWVuUGF5UGFsYW5kT3JkZXJCdXR0b24iLCJkaXNwbGF5UGxhY2VPcmRlckJ1dHRvbkZvclNhdmVkQ3JlZGl0Q2FyZHMiLCJjYW5jZWxfd3JhcHBlciIsInZhbCIsImN1cnJlbnRQYXltZW50TWV0aG9kIiwic2hvdyIsImhpZGUiLCJkaXNhYmxlQ3JlZGl0Q2FyZEZpZWxkcyIsImVuYWJsZUNyZWRpdENhcmRGaWVsZHMiLCJhZGRDbGFzcyIsImF0dHIiLCJyZW1vdmVDbGFzcyIsIlBheU5vd0Jvb3RzdHJhcCIsInVybFBhcmFtcyIsIlVSTFNlYXJjaFBhcmFtcyIsIndpbmRvdyIsInNlYXJjaCIsImhhcyIsIlJlbmRlcmVyIiwiY3JlZGl0Q2FyZFJlbmRlcmVyIiwiZGVmYXVsdENvbmZpZyIsImhvc3RlZEZpZWxkc1dyYXBwZXIiLCJjb250ZXh0Q29uZmlnIiwicmVuZGVyQnV0dG9ucyIsImlzQWxyZWFkeVJlbmRlcmVkIiwicGF5cGFsIiwiQnV0dG9ucyIsInN0eWxlIiwibWluaV9jYXJ0X3N0eWxlIiwiaGFzQ2hpbGROb2RlcyIsImRvbUVsZW1lbnQiLCJkaXNwbGF5IiwiZGlzYWJsZUZpZWxkcyIsImVuYWJsZUZpZWxkcyIsImRjY0lucHV0RmFjdG9yeSIsIm9yaWdpbmFsIiwic3R5bGVzIiwiZ2V0Q29tcHV0ZWRTdHlsZSIsIm5ld0VsZW1lbnQiLCJPYmplY3QiLCJ2YWx1ZXMiLCJwcm9wIiwiaXNOYU4iLCJzZXRQcm9wZXJ0eSIsIkNyZWRpdENhcmRSZW5kZXJlciIsImNhcmRWYWxpZCIsImZvcm1WYWxpZCIsImN1cnJlbnRIb3N0ZWRGaWVsZHNJbnN0YW5jZSIsImZvcm1TdWJtaXNzaW9uU3Vic2NyaWJlZCIsIkhvc3RlZEZpZWxkcyIsImlzRWxpZ2libGUiLCJ3cmFwcGVyRWxlbWVudCIsInBhcmVudE5vZGUiLCJyZW1vdmVDaGlsZCIsInRlYXJkb3duIiwiZ2F0ZVdheUJveCIsIm9sZERpc3BsYXlTdHlsZSIsImhpZGVEY2NHYXRld2F5IiwiY2FyZE51bWJlckZpZWxkIiwic3R5bGVzUmF3IiwiY2FyZE51bWJlciIsInJlcGxhY2VDaGlsZCIsImNhcmRFeHBpcnlGaWVsZCIsImNhcmRFeHBpcnkiLCJjYXJkQ29kZUZpZWxkIiwiY2FyZENvZGUiLCJmb3JtV3JhcHBlciIsImVuZm9yY2VfdmF1bHQiLCJjaGVja2VkIiwiZmllbGRzIiwibnVtYmVyIiwic2VsZWN0b3IiLCJwbGFjZWhvbGRlciIsImNyZWRpdF9jYXJkX251bWJlciIsImN2diIsImV4cGlyYXRpb25EYXRlIiwibW1feXkiLCJob3N0ZWRGaWVsZHMiLCJkaXNwYXRjaEV2ZW50IiwiQ3VzdG9tRXZlbnQiLCJfc3VibWl0IiwiZXZlbnQiLCJjYXJkcyIsInZhbGlkQ2FyZHMiLCJ2YWxpZF9jYXJkcyIsImluZGV4T2YiLCJ0eXBlIiwia2V5cyIsImV2ZXJ5Iiwia2V5IiwiaXNWYWxpZCIsImFkZEV2ZW50TGlzdGVuZXIiLCJwcmV2ZW50RGVmYXVsdCIsImZpZWxkIiwiYXR0cmlidXRlIiwicmVtb3ZlQXR0cmlidXRlIiwic2F2ZV9jYXJkIiwidmF1bHQiLCJnZXRFbGVtZW50QnlJZCIsImNvbnRpbmdlbmN5IiwiaG9zdGVkRmllbGRzRGF0YSIsImNvbnRpbmdlbmNpZXMiLCJzdWJtaXQiLCJwYXlsb2FkIiwib3JkZXJJZCIsImNhcmRfbm90X3N1cHBvcnRlZCIsImZpZWxkc19ub3RfdmFsaWQiLCJzdG9yYWdlS2V5IiwidmFsaWRhdGVUb2tlbiIsInRva2VuIiwidXNlciIsImN1cnJlbnRUaW1lIiwiRGF0ZSIsImdldFRpbWUiLCJpc0V4cGlyZWQiLCJleHBpcmF0aW9uIiwic3RvcmVkVG9rZW5Gb3JVc2VyIiwicGFyc2UiLCJzZXNzaW9uU3RvcmFnZSIsImdldEl0ZW0iLCJzdG9yZVRva2VuIiwic2V0SXRlbSIsImRhdGFDbGllbnRJZEF0dHJpYnV0ZUhhbmRsZXIiLCJzY3JpcHQiLCJNZXNzYWdlUmVuZGVyZXIiLCJNZXNzYWdlcyIsInBsYWNlbWVudCIsIm5ld1dyYXBwZXIiLCJzaWJsaW5nIiwibmV4dFNpYmxpbmciLCJwYXJlbnRFbGVtZW50IiwiaW5zZXJ0QmVmb3JlIiwiU3Bpbm5lciIsInRhcmdldCIsInNldFRhcmdldCIsIm92ZXJsYXlDU1MiLCJiYWNrZ3JvdW5kIiwib3BhY2l0eSIsImJvb3RzdHJhcCIsIm1lc3NhZ2VSZW5kZXJlciIsIm1pbmlfY2FydF9idXR0b25zX2VuYWJsZWQiLCJtaW5pQ2FydEJvb3RzdHJhcCIsInNpbmdsZV9wcm9kdWN0X2J1dHRvbnNfZW5hYmxlZCIsInNpbmdsZVByb2R1Y3RCb290c3RyYXAiLCJjYXJ0Qm9vdHN0cmFwIiwiY2hlY2tvdXRCb290c3RhcCIsInBheU5vd0Jvb3RzdHJhcCIsInVybCIsImVudHJpZXMiLCJzY3JpcHRfYXR0cmlidXRlcyIsImtleVZhbHVlIiwiZGF0YV9jbGllbnRfaWQiLCJzZXRfYXR0cmlidXRlIl0sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///94\n")}},__webpack_exports__={};__webpack_modules__[94]()})();
modules/ppcp-button/composer.json ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "woocommerce/ppcp-button",
3
+ "type": "dhii-mod",
4
+ "description": "Button module for PPCP",
5
+ "license": "GPL-2.0",
6
+ "require": {
7
+ "php": "^7.1 | ^8.0",
8
+ "dhii/module-interface": "^0.3.0-alpha1"
9
+ },
10
+ "autoload": {
11
+ "psr-4": {
12
+ "WooCommerce\\PayPalCommerce\\Button\\": "src"
13
+ }
14
+ },
15
+ "minimum-stability": "dev",
16
+ "prefer-stable": true
17
+ }
modules/ppcp-button/resources/js/modules/Renderer/CreditCardRenderer.js CHANGED
@@ -182,8 +182,11 @@ class CreditCardRenderer {
182
 
183
  if (this.formValid && this.cardValid) {
184
  const save_card = this.defaultConfig.save_card ? true : false;
185
- const vault = document.getElementById('ppcp-credit-card-vault') ?
186
  document.getElementById('ppcp-credit-card-vault').checked : save_card;
 
 
 
187
  const contingency = this.defaultConfig.hosted_fields.contingency;
188
  const hostedFieldsData = {
189
  vault: vault
182
 
183
  if (this.formValid && this.cardValid) {
184
  const save_card = this.defaultConfig.save_card ? true : false;
185
+ let vault = document.getElementById('ppcp-credit-card-vault') ?
186
  document.getElementById('ppcp-credit-card-vault').checked : save_card;
187
+ if (this.defaultConfig.enforce_vault) {
188
+ vault = true;
189
+ }
190
  const contingency = this.defaultConfig.hosted_fields.contingency;
191
  const hostedFieldsData = {
192
  vault: vault
modules/ppcp-button/services.php CHANGED
@@ -9,6 +9,7 @@ declare(strict_types=1);
9
 
10
  namespace WooCommerce\PayPalCommerce\Button;
11
 
 
12
  use WooCommerce\PayPalCommerce\Button\Assets\DisabledSmartButton;
13
  use WooCommerce\PayPalCommerce\Button\Assets\SmartButton;
14
  use WooCommerce\PayPalCommerce\Button\Assets\SmartButtonInterface;
@@ -25,7 +26,7 @@ use WooCommerce\PayPalCommerce\Onboarding\Environment;
25
  use WooCommerce\PayPalCommerce\Onboarding\State;
26
 
27
  return array(
28
- 'button.client_id' => static function ( $container ): string {
29
 
30
  $settings = $container->get( 'wcgateway.settings' );
31
  $client_id = $settings->has( 'client_id' ) ? $settings->get( 'client_id' ) : '';
@@ -43,7 +44,7 @@ return array(
43
  return $env->current_environment_is( Environment::SANDBOX ) ?
44
  CONNECT_WOO_SANDBOX_CLIENT_ID : CONNECT_WOO_CLIENT_ID;
45
  },
46
- 'button.smart-button' => static function ( $container ): SmartButtonInterface {
47
 
48
  $state = $container->get( 'onboarding.state' );
49
  /**
@@ -84,16 +85,16 @@ return array(
84
  $settings_status
85
  );
86
  },
87
- 'button.url' => static function ( $container ): string {
88
  return plugins_url(
89
  '/modules/ppcp-button/',
90
  dirname( __FILE__, 3 ) . '/woocommerce-paypal-payments.php'
91
  );
92
  },
93
- 'button.request-data' => static function ( $container ): RequestData {
94
  return new RequestData();
95
  },
96
- 'button.endpoint.change-cart' => static function ( $container ): ChangeCartEndpoint {
97
  if ( ! \WC()->cart ) {
98
  throw new RuntimeException( 'cant initialize endpoint at this moment' );
99
  }
@@ -105,7 +106,7 @@ return array(
105
  $logger = $container->get( 'woocommerce.logger.woocommerce' );
106
  return new ChangeCartEndpoint( $cart, $shipping, $request_data, $repository, $data_store, $logger );
107
  },
108
- 'button.endpoint.create-order' => static function ( $container ): CreateOrderEndpoint {
109
  $request_data = $container->get( 'button.request-data' );
110
  $cart_repository = $container->get( 'api.repository.cart' );
111
  $purchase_unit_factory = $container->get( 'api.factory.purchase-unit' );
@@ -114,7 +115,8 @@ return array(
114
  $session_handler = $container->get( 'session.handler' );
115
  $settings = $container->get( 'wcgateway.settings' );
116
  $early_order_handler = $container->get( 'button.helper.early-order-handler' );
117
- $logger = $container->get( 'woocommerce.logger.woocommerce' );
 
118
  return new CreateOrderEndpoint(
119
  $request_data,
120
  $cart_repository,
@@ -124,10 +126,11 @@ return array(
124
  $session_handler,
125
  $settings,
126
  $early_order_handler,
 
127
  $logger
128
  );
129
  },
130
- 'button.helper.early-order-handler' => static function ( $container ) : EarlyOrderHandler {
131
 
132
  $state = $container->get( 'onboarding.state' );
133
  $order_processor = $container->get( 'wcgateway.order-processor' );
@@ -135,7 +138,7 @@ return array(
135
  $prefix = $container->get( 'api.prefix' );
136
  return new EarlyOrderHandler( $state, $order_processor, $session_handler, $prefix );
137
  },
138
- 'button.endpoint.approve-order' => static function ( $container ): ApproveOrderEndpoint {
139
  $request_data = $container->get( 'button.request-data' );
140
  $order_endpoint = $container->get( 'api.endpoint.order' );
141
  $session_handler = $container->get( 'session.handler' );
@@ -153,7 +156,7 @@ return array(
153
  $logger
154
  );
155
  },
156
- 'button.endpoint.data-client-id' => static function( $container ) : DataClientIdEndpoint {
157
  $request_data = $container->get( 'button.request-data' );
158
  $identity_token = $container->get( 'api.endpoint.identity-token' );
159
  $logger = $container->get( 'woocommerce.logger.woocommerce' );
@@ -163,11 +166,22 @@ return array(
163
  $logger
164
  );
165
  },
166
- 'button.helper.three-d-secure' => static function ( $container ): ThreeDSecure {
167
  $logger = $container->get( 'woocommerce.logger.woocommerce' );
168
  return new ThreeDSecure( $logger );
169
  },
170
- 'button.helper.messages-apply' => static function ( $container ): MessagesApply {
171
  return new MessagesApply();
172
  },
 
 
 
 
 
 
 
 
 
 
 
173
  );
9
 
10
  namespace WooCommerce\PayPalCommerce\Button;
11
 
12
+ use Psr\Container\ContainerInterface;
13
  use WooCommerce\PayPalCommerce\Button\Assets\DisabledSmartButton;
14
  use WooCommerce\PayPalCommerce\Button\Assets\SmartButton;
15
  use WooCommerce\PayPalCommerce\Button\Assets\SmartButtonInterface;
26
  use WooCommerce\PayPalCommerce\Onboarding\State;
27
 
28
  return array(
29
+ 'button.client_id' => static function ( ContainerInterface $container ): string {
30
 
31
  $settings = $container->get( 'wcgateway.settings' );
32
  $client_id = $settings->has( 'client_id' ) ? $settings->get( 'client_id' ) : '';
44
  return $env->current_environment_is( Environment::SANDBOX ) ?
45
  CONNECT_WOO_SANDBOX_CLIENT_ID : CONNECT_WOO_CLIENT_ID;
46
  },
47
+ 'button.smart-button' => static function ( ContainerInterface $container ): SmartButtonInterface {
48
 
49
  $state = $container->get( 'onboarding.state' );
50
  /**
85
  $settings_status
86
  );
87
  },
88
+ 'button.url' => static function ( ContainerInterface $container ): string {
89
  return plugins_url(
90
  '/modules/ppcp-button/',
91
  dirname( __FILE__, 3 ) . '/woocommerce-paypal-payments.php'
92
  );
93
  },
94
+ 'button.request-data' => static function ( ContainerInterface $container ): RequestData {
95
  return new RequestData();
96
  },
97
+ 'button.endpoint.change-cart' => static function ( ContainerInterface $container ): ChangeCartEndpoint {
98
  if ( ! \WC()->cart ) {
99
  throw new RuntimeException( 'cant initialize endpoint at this moment' );
100
  }
106
  $logger = $container->get( 'woocommerce.logger.woocommerce' );
107
  return new ChangeCartEndpoint( $cart, $shipping, $request_data, $repository, $data_store, $logger );
108
  },
109
+ 'button.endpoint.create-order' => static function ( ContainerInterface $container ): CreateOrderEndpoint {
110
  $request_data = $container->get( 'button.request-data' );
111
  $cart_repository = $container->get( 'api.repository.cart' );
112
  $purchase_unit_factory = $container->get( 'api.factory.purchase-unit' );
115
  $session_handler = $container->get( 'session.handler' );
116
  $settings = $container->get( 'wcgateway.settings' );
117
  $early_order_handler = $container->get( 'button.helper.early-order-handler' );
118
+ $registration_needed = $container->get( 'button.current-user-must-register' );
119
+ $logger = $container->get( 'woocommerce.logger.woocommerce' );
120
  return new CreateOrderEndpoint(
121
  $request_data,
122
  $cart_repository,
126
  $session_handler,
127
  $settings,
128
  $early_order_handler,
129
+ $registration_needed,
130
  $logger
131
  );
132
  },
133
+ 'button.helper.early-order-handler' => static function ( ContainerInterface $container ) : EarlyOrderHandler {
134
 
135
  $state = $container->get( 'onboarding.state' );
136
  $order_processor = $container->get( 'wcgateway.order-processor' );
138
  $prefix = $container->get( 'api.prefix' );
139
  return new EarlyOrderHandler( $state, $order_processor, $session_handler, $prefix );
140
  },
141
+ 'button.endpoint.approve-order' => static function ( ContainerInterface $container ): ApproveOrderEndpoint {
142
  $request_data = $container->get( 'button.request-data' );
143
  $order_endpoint = $container->get( 'api.endpoint.order' );
144
  $session_handler = $container->get( 'session.handler' );
156
  $logger
157
  );
158
  },
159
+ 'button.endpoint.data-client-id' => static function( ContainerInterface $container ) : DataClientIdEndpoint {
160
  $request_data = $container->get( 'button.request-data' );
161
  $identity_token = $container->get( 'api.endpoint.identity-token' );
162
  $logger = $container->get( 'woocommerce.logger.woocommerce' );
166
  $logger
167
  );
168
  },
169
+ 'button.helper.three-d-secure' => static function ( ContainerInterface $container ): ThreeDSecure {
170
  $logger = $container->get( 'woocommerce.logger.woocommerce' );
171
  return new ThreeDSecure( $logger );
172
  },
173
+ 'button.helper.messages-apply' => static function ( ContainerInterface $container ): MessagesApply {
174
  return new MessagesApply();
175
  },
176
+
177
+ 'button.is-logged-in' => static function ( ContainerInterface $container ): bool {
178
+ return is_user_logged_in();
179
+ },
180
+ 'button.registration-required' => static function ( ContainerInterface $container ): bool {
181
+ return WC()->checkout()->is_registration_required();
182
+ },
183
+ 'button.current-user-must-register' => static function ( ContainerInterface $container ): bool {
184
+ return ! $container->get( 'button.is-logged-in' ) &&
185
+ $container->get( 'button.registration-required' );
186
+ },
187
  );
modules/ppcp-button/src/Assets/{class-disabledsmartbutton.php → DisabledSmartButton.php} RENAMED
File without changes
modules/ppcp-button/src/Assets/{class-smartbutton.php → SmartButton.php} RENAMED
@@ -22,7 +22,7 @@ use WooCommerce\PayPalCommerce\Session\SessionHandler;
22
  use WooCommerce\PayPalCommerce\Subscription\Helper\SubscriptionHelper;
23
  use WooCommerce\PayPalCommerce\Vaulting\PaymentTokenRepository;
24
  use WooCommerce\PayPalCommerce\WcGateway\Gateway\CreditCardGateway;
25
- use Woocommerce\PayPalCommerce\WcGateway\Helper\SettingsStatus;
26
  use WooCommerce\PayPalCommerce\WcGateway\Settings\Settings;
27
 
28
  /**
@@ -199,14 +199,18 @@ class SmartButton implements SmartButtonInterface {
199
  11
200
  );
201
 
 
202
  add_filter(
203
  'woocommerce_credit_card_form_fields',
204
- function ( $default_fields, $id ) {
205
  if ( is_user_logged_in() && $this->settings->has( 'vault_enabled' ) && $this->settings->get( 'vault_enabled' ) && CreditCardGateway::ID === $id ) {
206
- $default_fields['card-vault'] = sprintf(
207
- '<p class="form-row form-row-wide"><label for="vault"><input class="ppcp-credit-card-vault" type="checkbox" id="ppcp-credit-card-vault" name="vault">%s</label></p>',
208
- esc_html__( 'Save your Credit Card', 'woocommerce-paypal-payments' )
209
- );
 
 
 
210
 
211
  $tokens = $this->payment_token_repository->all_for_user_id( get_current_user_id() );
212
  if ( $tokens && $this->payment_token_repository->tokens_contains_card( $tokens ) ) {
@@ -728,7 +732,7 @@ class SmartButton implements SmartButtonInterface {
728
  private function payerData() {
729
 
730
  $customer = WC()->customer;
731
- if ( ! is_user_logged_in() || ! is_a( $customer, \WC_Customer::class ) ) {
732
  return null;
733
  }
734
  return $this->payer_factory->from_customer( $customer )->to_array();
@@ -741,6 +745,8 @@ class SmartButton implements SmartButtonInterface {
741
  * @throws \WooCommerce\PayPalCommerce\WcGateway\Exception\NotFoundException If a setting was not found.
742
  */
743
  private function url(): string {
 
 
744
  $params = array(
745
  'client-id' => $this->client_id,
746
  'currency' => get_woocommerce_currency(),
@@ -748,13 +754,14 @@ class SmartButton implements SmartButtonInterface {
748
  'components' => implode( ',', $this->components() ),
749
  'vault' => $this->can_save_vault_token() ? 'true' : 'false',
750
  'commit' => is_checkout() ? 'true' : 'false',
751
- 'intent' => ( $this->settings->has( 'intent' ) ) ?
752
- $this->settings->get( 'intent' ) : 'capture',
 
753
  );
754
  if (
755
  $this->environment->current_environment_is( Environment::SANDBOX )
756
  && defined( 'WP_DEBUG' ) && \WP_DEBUG && is_user_logged_in()
757
- && WC()->customer && WC()->customer->get_billing_country()
758
  && 2 === strlen( WC()->customer->get_billing_country() )
759
  ) {
760
  $params['buyer-country'] = WC()->customer->get_billing_country();
22
  use WooCommerce\PayPalCommerce\Subscription\Helper\SubscriptionHelper;
23
  use WooCommerce\PayPalCommerce\Vaulting\PaymentTokenRepository;
24
  use WooCommerce\PayPalCommerce\WcGateway\Gateway\CreditCardGateway;
25
+ use WooCommerce\PayPalCommerce\WcGateway\Helper\SettingsStatus;
26
  use WooCommerce\PayPalCommerce\WcGateway\Settings\Settings;
27
 
28
  /**
199
  11
200
  );
201
 
202
+ $subscription_helper = $this->subscription_helper;
203
  add_filter(
204
  'woocommerce_credit_card_form_fields',
205
+ function ( array $default_fields, $id ) use ( $subscription_helper ) : array {
206
  if ( is_user_logged_in() && $this->settings->has( 'vault_enabled' ) && $this->settings->get( 'vault_enabled' ) && CreditCardGateway::ID === $id ) {
207
+
208
+ if ( ! $subscription_helper->cart_contains_subscription() ) {
209
+ $default_fields['card-vault'] = sprintf(
210
+ '<p class="form-row form-row-wide"><label for="vault"><input class="ppcp-credit-card-vault" type="checkbox" id="ppcp-credit-card-vault" name="vault">%s</label></p>',
211
+ esc_html__( 'Save your Credit Card', 'woocommerce-paypal-payments' )
212
+ );
213
+ }
214
 
215
  $tokens = $this->payment_token_repository->all_for_user_id( get_current_user_id() );
216
  if ( $tokens && $this->payment_token_repository->tokens_contains_card( $tokens ) ) {
732
  private function payerData() {
733
 
734
  $customer = WC()->customer;
735
+ if ( ! is_user_logged_in() || ! ( $customer instanceof \WC_Customer ) ) {
736
  return null;
737
  }
738
  return $this->payer_factory->from_customer( $customer )->to_array();
745
  * @throws \WooCommerce\PayPalCommerce\WcGateway\Exception\NotFoundException If a setting was not found.
746
  */
747
  private function url(): string {
748
+ $intent = ( $this->settings->has( 'intent' ) ) ? $this->settings->get( 'intent' ) : 'capture';
749
+
750
  $params = array(
751
  'client-id' => $this->client_id,
752
  'currency' => get_woocommerce_currency(),
754
  'components' => implode( ',', $this->components() ),
755
  'vault' => $this->can_save_vault_token() ? 'true' : 'false',
756
  'commit' => is_checkout() ? 'true' : 'false',
757
+ 'intent' => ( $this->subscription_helper->cart_contains_subscription() || $this->subscription_helper->current_product_is_subscription() )
758
+ ? 'authorize'
759
+ : $intent,
760
  );
761
  if (
762
  $this->environment->current_environment_is( Environment::SANDBOX )
763
  && defined( 'WP_DEBUG' ) && \WP_DEBUG && is_user_logged_in()
764
+ && WC()->customer instanceof \WC_Customer && WC()->customer->get_billing_country()
765
  && 2 === strlen( WC()->customer->get_billing_country() )
766
  ) {
767
  $params['buyer-country'] = WC()->customer->get_billing_country();
modules/ppcp-button/src/Assets/{class-smartbuttoninterface.php → SmartButtonInterface.php} RENAMED
File without changes
modules/ppcp-button/src/{class-buttonmodule.php → ButtonModule.php} RENAMED
@@ -27,9 +27,7 @@ class ButtonModule implements ModuleInterface {
27
 
28
 
29
  /**
30
- * Sets up the module.
31
- *
32
- * @return ServiceProviderInterface
33
  */
34
  public function setup(): ServiceProviderInterface {
35
  return new ServiceProvider(
@@ -39,19 +37,17 @@ class ButtonModule implements ModuleInterface {
39
  }
40
 
41
  /**
42
- * Runs the module.
43
- *
44
- * @param ContainerInterface|null $container The Container.
45
  */
46
- public function run( ContainerInterface $container ): void {
47
 
48
  add_action(
49
  'wp',
50
- static function () use ( $container ) {
51
  if ( is_admin() ) {
52
  return;
53
  }
54
- $smart_button = $container->get( 'button.smart-button' );
55
  /**
56
  * The Smart Button.
57
  *
@@ -62,9 +58,9 @@ class ButtonModule implements ModuleInterface {
62
  );
63
  add_action(
64
  'wp_enqueue_scripts',
65
- static function () use ( $container ) {
66
 
67
- $smart_button = $container->get( 'button.smart-button' );
68
  /**
69
  * The Smart Button.
70
  *
@@ -76,8 +72,8 @@ class ButtonModule implements ModuleInterface {
76
 
77
  add_filter(
78
  'woocommerce_create_order',
79
- static function ( $value ) use ( $container ) {
80
- $early_order_handler = $container->get( 'button.helper.early-order-handler' );
81
  if ( ! is_null( $value ) ) {
82
  $value = (int) $value;
83
  }
@@ -90,7 +86,7 @@ class ButtonModule implements ModuleInterface {
90
  }
91
  );
92
 
93
- $this->register_ajax_endpoints( $container );
94
  }
95
 
96
  /**
27
 
28
 
29
  /**
30
+ * {@inheritDoc}
 
 
31
  */
32
  public function setup(): ServiceProviderInterface {
33
  return new ServiceProvider(
37
  }
38
 
39
  /**
40
+ * {@inheritDoc}
 
 
41
  */
42
+ public function run( ContainerInterface $c ): void {
43
 
44
  add_action(
45
  'wp',
46
+ static function () use ( $c ) {
47
  if ( is_admin() ) {
48
  return;
49
  }
50
+ $smart_button = $c->get( 'button.smart-button' );
51
  /**
52
  * The Smart Button.
53
  *
58
  );
59
  add_action(
60
  'wp_enqueue_scripts',
61
+ static function () use ( $c ) {
62
 
63
+ $smart_button = $c->get( 'button.smart-button' );
64
  /**
65
  * The Smart Button.
66
  *
72
 
73
  add_filter(
74
  'woocommerce_create_order',
75
+ static function ( $value ) use ( $c ) {
76
+ $early_order_handler = $c->get( 'button.helper.early-order-handler' );
77
  if ( ! is_null( $value ) ) {
78
  $value = (int) $value;
79
  }
86
  }
87
  );
88
 
89
+ $this->register_ajax_endpoints( $c );
90
  }
91
 
92
  /**
modules/ppcp-button/src/Endpoint/{class-approveorderendpoint.php → ApproveOrderEndpoint.php} RENAMED
@@ -121,7 +121,7 @@ class ApproveOrderEndpoint implements EndpointInterface {
121
  * Handles the request.
122
  *
123
  * @return bool
124
- * @throws RuntimeException When no order was found.
125
  */
126
  public function handle_request(): bool {
127
  try {
@@ -133,15 +133,6 @@ class ApproveOrderEndpoint implements EndpointInterface {
133
  }
134
 
135
  $order = $this->api_endpoint->order( $data['order_id'] );
136
- if ( ! $order ) {
137
- throw new RuntimeException(
138
- sprintf(
139
- // translators: %s is the id of the order.
140
- __( 'Order %s not found.', 'woocommerce-paypal-payments' ),
141
- $data['order_id']
142
- )
143
- );
144
- }
145
 
146
  if ( $order->payment_source() && $order->payment_source()->card() ) {
147
  if ( $this->settings->has( 'disable_cards' ) ) {
121
  * Handles the request.
122
  *
123
  * @return bool
124
+ * @throws RuntimeException When order not found or handling failed.
125
  */
126
  public function handle_request(): bool {
127
  try {
133
  }
134
 
135
  $order = $this->api_endpoint->order( $data['order_id'] );
 
 
 
 
 
 
 
 
 
136
 
137
  if ( $order->payment_source() && $order->payment_source()->card() ) {
138
  if ( $this->settings->has( 'disable_cards' ) ) {
modules/ppcp-button/src/Endpoint/{class-changecartendpoint.php → ChangeCartEndpoint.php} RENAMED
File without changes
modules/ppcp-button/src/Endpoint/{class-createorderendpoint.php → CreateOrderEndpoint.php} RENAMED
@@ -31,7 +31,6 @@ use WooCommerce\PayPalCommerce\WcGateway\Settings\Settings;
31
  */
32
  class CreateOrderEndpoint implements EndpointInterface {
33
 
34
-
35
  const ENDPOINT = 'ppc-create-order';
36
 
37
  /**
@@ -104,6 +103,13 @@ class CreateOrderEndpoint implements EndpointInterface {
104
  */
105
  private $purchase_units;
106
 
 
 
 
 
 
 
 
107
  /**
108
  * The logger.
109
  *
@@ -122,6 +128,7 @@ class CreateOrderEndpoint implements EndpointInterface {
122
  * @param SessionHandler $session_handler The SessionHandler object.
123
  * @param Settings $settings The Settings object.
124
  * @param EarlyOrderHandler $early_order_handler The EarlyOrderHandler object.
 
125
  * @param LoggerInterface $logger The logger.
126
  */
127
  public function __construct(
@@ -133,6 +140,7 @@ class CreateOrderEndpoint implements EndpointInterface {
133
  SessionHandler $session_handler,
134
  Settings $settings,
135
  EarlyOrderHandler $early_order_handler,
 
136
  LoggerInterface $logger
137
  ) {
138
 
@@ -144,6 +152,7 @@ class CreateOrderEndpoint implements EndpointInterface {
144
  $this->session_handler = $session_handler;
145
  $this->settings = $settings;
146
  $this->early_order_handler = $early_order_handler;
 
147
  $this->logger = $logger;
148
  }
149
 
@@ -160,6 +169,7 @@ class CreateOrderEndpoint implements EndpointInterface {
160
  * Handles the request.
161
  *
162
  * @return bool
 
163
  */
164
  public function handle_request(): bool {
165
  try {
@@ -186,21 +196,31 @@ class CreateOrderEndpoint implements EndpointInterface {
186
  $this->set_bn_code( $data );
187
 
188
  if ( 'checkout' === $data['context'] ) {
189
- if ( isset( $data['createaccount'] ) && '1' === $data['createaccount'] ) {
190
- $this->process_checkout_form_when_creating_account( $data['form'], $wc_order );
 
 
 
191
  }
192
 
193
- $this->process_checkout_form( $data['form'] );
 
 
 
 
 
 
 
194
  }
 
195
  if ( 'pay-now' === $data['context'] && get_option( 'woocommerce_terms_page_id', '' ) !== '' ) {
196
  $this->validate_paynow_form( $data['form'] );
197
  }
198
 
199
- // if we are here so the context is not 'checkout' as it exits before. Therefore, a PayPal order is not created yet.
200
- // It would be a good idea to refactor the checkout process in the future.
201
  $order = $this->create_paypal_order( $wc_order );
202
  wp_send_json_success( $order->to_array() );
203
  return true;
 
204
  } catch ( \RuntimeException $error ) {
205
  $this->logger->error( 'Order creation failed: ' . $error->getMessage() );
206
 
@@ -275,7 +295,7 @@ class CreateOrderEndpoint implements EndpointInterface {
275
  * @throws RuntimeException If create order request fails.
276
  */
277
  private function create_paypal_order( \WC_Order $wc_order = null ): Order {
278
- $needs_shipping = WC()->cart && WC()->cart->needs_shipping();
279
  $shipping_address_is_fix = $needs_shipping && 'checkout' === $this->parsed_request_data['context'];
280
 
281
  return $this->api_endpoint->create(
@@ -320,7 +340,6 @@ class CreateOrderEndpoint implements EndpointInterface {
320
  return $payer;
321
  }
322
 
323
-
324
  /**
325
  * Sets the BN Code for the following request.
326
  *
@@ -354,41 +373,6 @@ class CreateOrderEndpoint implements EndpointInterface {
354
  return $payment_method;
355
  }
356
 
357
- /**
358
- * Prepare the Request parameter and process the checkout form and validate it.
359
- *
360
- * @param string $form_values The values of the form.
361
- *
362
- * @throws Exception On Error.
363
- */
364
- private function process_checkout_form( string $form_values ) {
365
- $form_values = explode( '&', $form_values );
366
-
367
- $parsed_values = array();
368
- foreach ( $form_values as $field ) {
369
- $field = explode( '=', $field );
370
-
371
- if ( count( $field ) !== 2 ) {
372
- continue;
373
- }
374
- $parsed_values[ $field[0] ] = $field[1];
375
- }
376
- $_POST = $parsed_values;
377
- $_REQUEST = $parsed_values;
378
-
379
- add_filter(
380
- 'woocommerce_after_checkout_validation',
381
- array(
382
- $this,
383
- 'after_checkout_validation',
384
- ),
385
- 10,
386
- 2
387
- );
388
- $checkout = \WC()->checkout();
389
- $checkout->process_checkout();
390
- }
391
-
392
  /**
393
  * Checks whether the terms input field is checked.
394
  *
@@ -397,53 +381,10 @@ class CreateOrderEndpoint implements EndpointInterface {
397
  */
398
  private function validate_paynow_form( string $form_values ) {
399
  $parsed_values = wp_parse_args( $form_values );
400
- if ( ! isset( $parsed_values['terms'] ) ) {
401
  throw new \RuntimeException(
402
  __( 'Please read and accept the terms and conditions to proceed with your order.', 'woocommerce-paypal-payments' )
403
  );
404
  }
405
  }
406
-
407
- /**
408
- * Processes checkout and creates the PayPal order after success form validation.
409
- *
410
- * @param string $form_values The values of the form.
411
- * @param \WC_Order|null $wc_order WC order to get data from.
412
- * @throws Exception On Error.
413
- */
414
- private function process_checkout_form_when_creating_account( string $form_values, \WC_Order $wc_order = null ) {
415
- $form_values = explode( '&', $form_values );
416
- $parsed_values = array();
417
- foreach ( $form_values as $field ) {
418
- $field = explode( '=', $field );
419
-
420
- if ( count( $field ) !== 2 ) {
421
- continue;
422
- }
423
- $parsed_values[ $field[0] ] = $field[1];
424
- }
425
- $_POST = $parsed_values;
426
- $_REQUEST = $parsed_values;
427
-
428
- add_action(
429
- 'woocommerce_after_checkout_validation',
430
- function ( array $data, \WP_Error $errors ) use ( $wc_order ) {
431
- if ( ! $errors->errors ) {
432
- try {
433
- $order = $this->create_paypal_order( $wc_order );
434
- } catch ( Exception $exception ) {
435
- $this->logger->error( 'Order creation failed: ' . $exception->getMessage() );
436
- throw $exception;
437
- }
438
- wp_send_json_success( $order->to_array() );
439
- return true;
440
- }
441
- },
442
- 10,
443
- 2
444
- );
445
-
446
- $checkout = \WC()->checkout();
447
- $checkout->process_checkout();
448
- }
449
  }
31
  */
32
  class CreateOrderEndpoint implements EndpointInterface {
33
 
 
34
  const ENDPOINT = 'ppc-create-order';
35
 
36
  /**
103
  */
104
  private $purchase_units;
105
 
106
+ /**
107
+ * Whether a new user must be registered during checkout.
108
+ *
109
+ * @var bool
110
+ */
111
+ private $registration_needed;
112
+
113
  /**
114
  * The logger.
115
  *
128
  * @param SessionHandler $session_handler The SessionHandler object.
129
  * @param Settings $settings The Settings object.
130
  * @param EarlyOrderHandler $early_order_handler The EarlyOrderHandler object.
131
+ * @param bool $registration_needed Whether a new user must be registered during checkout.
132
  * @param LoggerInterface $logger The logger.
133
  */
134
  public function __construct(
140
  SessionHandler $session_handler,
141
  Settings $settings,
142
  EarlyOrderHandler $early_order_handler,
143
+ bool $registration_needed,
144
  LoggerInterface $logger
145
  ) {
146
 
152
  $this->session_handler = $session_handler;
153
  $this->settings = $settings;
154
  $this->early_order_handler = $early_order_handler;
155
+ $this->registration_needed = $registration_needed;
156
  $this->logger = $logger;
157
  }
158
 
169
  * Handles the request.
170
  *
171
  * @return bool
172
+ * @throws Exception On Error.
173
  */
174
  public function handle_request(): bool {
175
  try {
196
  $this->set_bn_code( $data );
197
 
198
  if ( 'checkout' === $data['context'] ) {
199
+ try {
200
+ $order = $this->create_paypal_order( $wc_order );
201
+ } catch ( Exception $exception ) {
202
+ $this->logger->error( 'Order creation failed: ' . $exception->getMessage() );
203
+ throw $exception;
204
  }
205
 
206
+ if (
207
+ ! $this->early_order_handler->should_create_early_order()
208
+ || $this->registration_needed
209
+ || isset( $data['createaccount'] ) && '1' === $data['createaccount'] ) {
210
+ wp_send_json_success( $order->to_array() );
211
+ }
212
+
213
+ $this->early_order_handler->register_for_order( $order );
214
  }
215
+
216
  if ( 'pay-now' === $data['context'] && get_option( 'woocommerce_terms_page_id', '' ) !== '' ) {
217
  $this->validate_paynow_form( $data['form'] );
218
  }
219
 
 
 
220
  $order = $this->create_paypal_order( $wc_order );
221
  wp_send_json_success( $order->to_array() );
222
  return true;
223
+
224
  } catch ( \RuntimeException $error ) {
225
  $this->logger->error( 'Order creation failed: ' . $error->getMessage() );
226
 
295
  * @throws RuntimeException If create order request fails.
296
  */
297
  private function create_paypal_order( \WC_Order $wc_order = null ): Order {
298
+ $needs_shipping = WC()->cart instanceof \WC_Cart && WC()->cart->needs_shipping();
299
  $shipping_address_is_fix = $needs_shipping && 'checkout' === $this->parsed_request_data['context'];
300
 
301
  return $this->api_endpoint->create(
340
  return $payer;
341
  }
342
 
 
343
  /**
344
  * Sets the BN Code for the following request.
345
  *
373
  return $payment_method;
374
  }
375
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
376
  /**
377
  * Checks whether the terms input field is checked.
378
  *
381
  */
382
  private function validate_paynow_form( string $form_values ) {
383
  $parsed_values = wp_parse_args( $form_values );
384
+ if ( isset( $parsed_values['terms-field'] ) && ! isset( $parsed_values['terms'] ) ) {
385
  throw new \RuntimeException(
386
  __( 'Please read and accept the terms and conditions to proceed with your order.', 'woocommerce-paypal-payments' )
387
  );
388
  }
389
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
390
  }
modules/ppcp-button/src/Endpoint/{class-dataclientidendpoint.php → DataClientIdEndpoint.php} RENAMED
File without changes
modules/ppcp-button/src/Endpoint/{class-endpointinterface.php → EndpointInterface.php} RENAMED
File without changes
modules/ppcp-button/src/Endpoint/{class-requestdata.php → RequestData.php} RENAMED
File without changes
modules/ppcp-button/src/Exception/{class-runtimeexception.php → RuntimeException.php} RENAMED
File without changes
modules/ppcp-button/src/Helper/{class-earlyorderhandler.php → EarlyOrderHandler.php} RENAMED
File without changes
modules/ppcp-button/src/Helper/{class-messagesapply.php → MessagesApply.php} RENAMED
File without changes
modules/ppcp-button/src/Helper/{class-messagesdisclaimers.php → MessagesDisclaimers.php} RENAMED
File without changes
modules/ppcp-button/src/Helper/{class-threedsecure.php → ThreeDSecure.php} RENAMED
File without changes
modules/ppcp-compat/composer.json ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "woocommerce/ppcp-compat",
3
+ "type": "dhii-mod",
4
+ "description": "Compatibility module for PPCP",
5
+ "license": "GPL-2.0",
6
+ "require": {
7
+ "php": "^7.1 | ^8.0",
8
+ "dhii/module-interface": "^0.3.0-alpha1"
9
+ },
10
+ "autoload": {
11
+ "psr-4": {
12
+ "WooCommerce\\PayPalCommerce\\Compat\\": "src"
13
+ }
14
+ },
15
+ "minimum-stability": "dev",
16
+ "prefer-stable": true
17
+ }
modules/ppcp-compat/services.php CHANGED
@@ -9,6 +9,8 @@ declare(strict_types=1);
9
 
10
  namespace WooCommerce\PayPalCommerce\Compat;
11
 
 
 
12
  return array(
13
 
14
  'compat.ppec.mock-gateway' => static function( $container ) {
@@ -23,7 +25,7 @@ return array(
23
  return new PPEC\MockGateway( $title );
24
  },
25
 
26
- 'compat.ppec.subscriptions-handler' => static function ( $container ) {
27
  $ppcp_renewal_handler = $container->get( 'subscription.renewal-handler' );
28
  $gateway = $container->get( 'compat.ppec.mock-gateway' );
29
 
9
 
10
  namespace WooCommerce\PayPalCommerce\Compat;
11
 
12
+ use Psr\Container\ContainerInterface;
13
+
14
  return array(
15
 
16
  'compat.ppec.mock-gateway' => static function( $container ) {
25
  return new PPEC\MockGateway( $title );
26
  },
27
 
28
+ 'compat.ppec.subscriptions-handler' => static function ( ContainerInterface $container ) {
29
  $ppcp_renewal_handler = $container->get( 'subscription.renewal-handler' );
30
  $gateway = $container->get( 'compat.ppec.mock-gateway' );
31
 
modules/ppcp-compat/src/{class-compatmodule.php → CompatModule.php} RENAMED
@@ -35,10 +35,10 @@ class CompatModule implements ModuleInterface {
35
  /**
36
  * Run the compatibility module.
37
  *
38
- * @param ContainerInterface|null $container The Container.
39
  */
40
- public function run( ContainerInterface $container ): void {
41
- $this->initialize_ppec_compat_layer( $container );
42
  }
43
 
44
  /**
35
  /**
36
  * Run the compatibility module.
37
  *
38
+ * @param ContainerInterface|null $c The Container.
39
  */
40
+ public function run( ContainerInterface $c ): void {
41
+ $this->initialize_ppec_compat_layer( $c );
42
  }
43
 
44
  /**
modules/ppcp-compat/src/PPEC/{class-deactivatenote.php → DeactivateNote.php} RENAMED
File without changes
modules/ppcp-compat/src/PPEC/{class-mockgateway.php → MockGateway.php} RENAMED
File without changes
modules/ppcp-compat/src/PPEC/{class-ppechelper.php → PPECHelper.php} RENAMED
@@ -44,7 +44,12 @@ class PPECHelper {
44
  * @return bool
45
  */
46
  public static function is_gateway_available() {
47
- return self::is_plugin_active() && is_callable( 'wc_gateway_ppec' ) && wc_gateway_ppec()->settings->get_active_api_credentials();
 
 
 
 
 
48
  }
49
 
50
  /**
44
  * @return bool
45
  */
46
  public static function is_gateway_available() {
47
+ if ( ! self::is_plugin_active() || ! is_callable( 'wc_gateway_ppec' ) ) {
48
+ return false;
49
+ }
50
+
51
+ $ppec = wc_gateway_ppec();
52
+ return is_object( $ppec ) && $ppec->settings && $ppec->settings->get_active_api_credentials();
53
  }
54
 
55
  /**
modules/ppcp-compat/src/PPEC/{class-settingsimporter.php → SettingsImporter.php} RENAMED
File without changes
modules/ppcp-compat/src/PPEC/{class-subscriptionshandler.php → SubscriptionsHandler.php} RENAMED
File without changes
modules/ppcp-onboarding/composer.json ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "woocommerce/ppcp-onboarding",
3
+ "type": "dhii-mod",
4
+ "description": "Onboarding module for PPCP",
5
+ "license": "GPL-2.0",
6
+ "require": {
7
+ "php": "^7.1 | ^8.0",
8
+ "dhii/module-interface": "^0.3.0-alpha1"
9
+ },
10
+ "autoload": {
11
+ "psr-4": {
12
+ "WooCommerce\\PayPalCommerce\\Onboarding\\": "src"
13
+ }
14
+ },
15
+ "minimum-stability": "dev",
16
+ "prefer-stable": true
17
+ }
modules/ppcp-onboarding/services.php CHANGED
@@ -9,6 +9,7 @@ declare(strict_types=1);
9
 
10
  namespace WooCommerce\PayPalCommerce\Onboarding;
11
 
 
12
  use WooCommerce\PayPalCommerce\ApiClient\Authentication\Bearer;
13
  use WooCommerce\PayPalCommerce\ApiClient\Authentication\ConnectBearer;
14
  use WooCommerce\PayPalCommerce\ApiClient\Authentication\PayPalBearer;
@@ -18,10 +19,10 @@ use WooCommerce\PayPalCommerce\ApiClient\Helper\Cache;
18
  use WooCommerce\PayPalCommerce\Onboarding\Assets\OnboardingAssets;
19
  use WooCommerce\PayPalCommerce\Onboarding\Endpoint\LoginSellerEndpoint;
20
  use WooCommerce\PayPalCommerce\Onboarding\Render\OnboardingRenderer;
21
- use WooCommerce\PayPalCommerce\Onboarding\Onboarding_REST_Controller;
22
 
23
  return array(
24
- 'api.sandbox-host' => static function ( $container ): string {
25
 
26
  $state = $container->get( 'onboarding.state' );
27
 
@@ -35,7 +36,7 @@ return array(
35
  }
36
  return CONNECT_WOO_SANDBOX_URL;
37
  },
38
- 'api.production-host' => static function ( $container ): string {
39
 
40
  $state = $container->get( 'onboarding.state' );
41
 
@@ -50,7 +51,7 @@ return array(
50
  }
51
  return CONNECT_WOO_URL;
52
  },
53
- 'api.host' => static function ( $container ): string {
54
  $environment = $container->get( 'onboarding.environment' );
55
 
56
  /**
@@ -62,19 +63,19 @@ return array(
62
  ? (string) $container->get( 'api.sandbox-host' ) : (string) $container->get( 'api.production-host' );
63
 
64
  },
65
- 'api.paypal-host-production' => static function( $container ) : string {
66
  return PAYPAL_API_URL;
67
  },
68
- 'api.paypal-host-sandbox' => static function( $container ) : string {
69
  return PAYPAL_SANDBOX_API_URL;
70
  },
71
- 'api.partner_merchant_id-production' => static function( $container ) : string {
72
  return CONNECT_WOO_MERCHANT_ID;
73
  },
74
- 'api.partner_merchant_id-sandbox' => static function( $container ) : string {
75
  return CONNECT_WOO_SANDBOX_MERCHANT_ID;
76
  },
77
- 'api.paypal-host' => function( $container ) : string {
78
  $environment = $container->get( 'onboarding.environment' );
79
  /**
80
  * The current environment.
@@ -88,7 +89,7 @@ return array(
88
 
89
  },
90
 
91
- 'api.bearer' => static function ( $container ): Bearer {
92
 
93
  $state = $container->get( 'onboarding.state' );
94
 
@@ -115,17 +116,17 @@ return array(
115
  $settings
116
  );
117
  },
118
- 'onboarding.state' => function( $container ) : State {
119
  $environment = $container->get( 'onboarding.environment' );
120
  $settings = $container->get( 'wcgateway.settings' );
121
  return new State( $environment, $settings );
122
  },
123
- 'onboarding.environment' => function( $container ) : Environment {
124
  $settings = $container->get( 'wcgateway.settings' );
125
  return new Environment( $settings );
126
  },
127
 
128
- 'onboarding.assets' => function( $container ) : OnboardingAssets {
129
  $state = $container->get( 'onboarding.state' );
130
  $login_seller_endpoint = $container->get( 'onboarding.endpoint.login-seller' );
131
  return new OnboardingAssets(
@@ -135,14 +136,14 @@ return array(
135
  );
136
  },
137
 
138
- 'onboarding.url' => static function ( $container ): string {
139
  return plugins_url(
140
  '/modules/ppcp-onboarding/',
141
  dirname( __FILE__, 3 ) . '/woocommerce-paypal-payments.php'
142
  );
143
  },
144
 
145
- 'api.endpoint.login-seller-production' => static function ( $container ) : LoginSeller {
146
 
147
  $logger = $container->get( 'woocommerce.logger.woocommerce' );
148
  return new LoginSeller(
@@ -152,7 +153,7 @@ return array(
152
  );
153
  },
154
 
155
- 'api.endpoint.login-seller-sandbox' => static function ( $container ) : LoginSeller {
156
 
157
  $logger = $container->get( 'woocommerce.logger.woocommerce' );
158
  return new LoginSeller(
@@ -162,7 +163,7 @@ return array(
162
  );
163
  },
164
 
165
- 'onboarding.endpoint.login-seller' => static function ( $container ) : LoginSellerEndpoint {
166
 
167
  $request_data = $container->get( 'button.request-data' );
168
  $login_seller_production = $container->get( 'api.endpoint.login-seller-production' );
@@ -182,7 +183,7 @@ return array(
182
  $logger
183
  );
184
  },
185
- 'api.endpoint.partner-referrals-sandbox' => static function ( $container ) : PartnerReferrals {
186
 
187
  return new PartnerReferrals(
188
  CONNECT_WOO_SANDBOX_URL,
@@ -191,7 +192,7 @@ return array(
191
  $container->get( 'woocommerce.logger.woocommerce' )
192
  );
193
  },
194
- 'api.endpoint.partner-referrals-production' => static function ( $container ) : PartnerReferrals {
195
 
196
  return new PartnerReferrals(
197
  CONNECT_WOO_URL,
@@ -200,7 +201,7 @@ return array(
200
  $container->get( 'woocommerce.logger.woocommerce' )
201
  );
202
  },
203
- 'onboarding.render' => static function ( $container ) : OnboardingRenderer {
204
 
205
  $partner_referrals = $container->get( 'api.endpoint.partner-referrals-production' );
206
  $partner_referrals_sandbox = $container->get( 'api.endpoint.partner-referrals-sandbox' );
@@ -211,7 +212,7 @@ return array(
211
  $partner_referrals_sandbox
212
  );
213
  },
214
- 'onboarding.rest' => static function( $container ) : Onboarding_REST_Controller {
215
- return new Onboarding_REST_Controller( $container );
216
  },
217
  );
9
 
10
  namespace WooCommerce\PayPalCommerce\Onboarding;
11
 
12
+ use Psr\Container\ContainerInterface;
13
  use WooCommerce\PayPalCommerce\ApiClient\Authentication\Bearer;
14
  use WooCommerce\PayPalCommerce\ApiClient\Authentication\ConnectBearer;
15
  use WooCommerce\PayPalCommerce\ApiClient\Authentication\PayPalBearer;
19
  use WooCommerce\PayPalCommerce\Onboarding\Assets\OnboardingAssets;
20
  use WooCommerce\PayPalCommerce\Onboarding\Endpoint\LoginSellerEndpoint;
21
  use WooCommerce\PayPalCommerce\Onboarding\Render\OnboardingRenderer;
22
+ use WooCommerce\PayPalCommerce\Onboarding\OnboardingRESTController;
23
 
24
  return array(
25
+ 'api.sandbox-host' => static function ( ContainerInterface $container ): string {
26
 
27
  $state = $container->get( 'onboarding.state' );
28
 
36
  }
37
  return CONNECT_WOO_SANDBOX_URL;
38
  },
39
+ 'api.production-host' => static function ( ContainerInterface $container ): string {
40
 
41
  $state = $container->get( 'onboarding.state' );
42
 
51
  }
52
  return CONNECT_WOO_URL;
53
  },
54
+ 'api.host' => static function ( ContainerInterface $container ): string {
55
  $environment = $container->get( 'onboarding.environment' );
56
 
57
  /**
63
  ? (string) $container->get( 'api.sandbox-host' ) : (string) $container->get( 'api.production-host' );
64
 
65
  },
66
+ 'api.paypal-host-production' => static function( ContainerInterface $container ) : string {
67
  return PAYPAL_API_URL;
68
  },
69
+ 'api.paypal-host-sandbox' => static function( ContainerInterface $container ) : string {
70
  return PAYPAL_SANDBOX_API_URL;
71
  },
72
+ 'api.partner_merchant_id-production' => static function( ContainerInterface $container ) : string {
73
  return CONNECT_WOO_MERCHANT_ID;
74
  },
75
+ 'api.partner_merchant_id-sandbox' => static function( ContainerInterface $container ) : string {
76
  return CONNECT_WOO_SANDBOX_MERCHANT_ID;
77
  },
78
+ 'api.paypal-host' => function( ContainerInterface $container ) : string {
79
  $environment = $container->get( 'onboarding.environment' );
80
  /**
81
  * The current environment.
89
 
90
  },
91
 
92
+ 'api.bearer' => static function ( ContainerInterface $container ): Bearer {
93
 
94
  $state = $container->get( 'onboarding.state' );
95
 
116
  $settings
117
  );
118
  },
119
+ 'onboarding.state' => function( ContainerInterface $container ) : State {
120
  $environment = $container->get( 'onboarding.environment' );
121
  $settings = $container->get( 'wcgateway.settings' );
122
  return new State( $environment, $settings );
123
  },
124
+ 'onboarding.environment' => function( ContainerInterface $container ) : Environment {
125
  $settings = $container->get( 'wcgateway.settings' );
126
  return new Environment( $settings );
127
  },
128
 
129
+ 'onboarding.assets' => function( ContainerInterface $container ) : OnboardingAssets {
130
  $state = $container->get( 'onboarding.state' );
131
  $login_seller_endpoint = $container->get( 'onboarding.endpoint.login-seller' );
132
  return new OnboardingAssets(
136
  );
137
  },
138
 
139
+ 'onboarding.url' => static function ( ContainerInterface $container ): string {
140
  return plugins_url(
141
  '/modules/ppcp-onboarding/',
142
  dirname( __FILE__, 3 ) . '/woocommerce-paypal-payments.php'
143
  );
144
  },
145
 
146
+ 'api.endpoint.login-seller-production' => static function ( ContainerInterface $container ) : LoginSeller {
147
 
148
  $logger = $container->get( 'woocommerce.logger.woocommerce' );
149
  return new LoginSeller(
153
  );
154
  },
155
 
156
+ 'api.endpoint.login-seller-sandbox' => static function ( ContainerInterface $container ) : LoginSeller {
157
 
158
  $logger = $container->get( 'woocommerce.logger.woocommerce' );
159
  return new LoginSeller(
163
  );
164
  },
165
 
166
+ 'onboarding.endpoint.login-seller' => static function ( ContainerInterface $container ) : LoginSellerEndpoint {
167
 
168
  $request_data = $container->get( 'button.request-data' );
169
  $login_seller_production = $container->get( 'api.endpoint.login-seller-production' );
183
  $logger
184
  );
185
  },
186
+ 'api.endpoint.partner-referrals-sandbox' => static function ( ContainerInterface $container ) : PartnerReferrals {
187
 
188
  return new PartnerReferrals(
189
  CONNECT_WOO_SANDBOX_URL,
192
  $container->get( 'woocommerce.logger.woocommerce' )
193
  );
194
  },
195
+ 'api.endpoint.partner-referrals-production' => static function ( ContainerInterface $container ) : PartnerReferrals {
196
 
197
  return new PartnerReferrals(
198
  CONNECT_WOO_URL,
201
  $container->get( 'woocommerce.logger.woocommerce' )
202
  );
203
  },
204
+ 'onboarding.render' => static function ( ContainerInterface $container ) : OnboardingRenderer {
205
 
206
  $partner_referrals = $container->get( 'api.endpoint.partner-referrals-production' );
207
  $partner_referrals_sandbox = $container->get( 'api.endpoint.partner-referrals-sandbox' );
212
  $partner_referrals_sandbox
213
  );
214
  },
215
+ 'onboarding.rest' => static function( $container ) : OnboardingRESTController {
216
+ return new OnboardingRESTController( $container );
217
  },
218
  );
modules/ppcp-onboarding/src/Assets/{class-onboardingassets.php → OnboardingAssets.php} RENAMED
File without changes
modules/ppcp-onboarding/src/Endpoint/{class-loginsellerendpoint.php → LoginSellerEndpoint.php} RENAMED
File without changes
modules/ppcp-onboarding/src/{class-environment.php → Environment.php} RENAMED
File without changes
modules/ppcp-onboarding/src/{class-onboardingmodule.php → OnboardingModule.php} RENAMED
@@ -24,9 +24,7 @@ use Psr\Container\ContainerInterface;
24
  class OnboardingModule implements ModuleInterface {
25
 
26
  /**
27
- * Sets up the module.
28
- *
29
- * @return ServiceProviderInterface
30
  */
31
  public function setup(): ServiceProviderInterface {
32
  return new ServiceProvider(
@@ -36,13 +34,11 @@ class OnboardingModule implements ModuleInterface {
36
  }
37
 
38
  /**
39
- * Runs the module.
40
- *
41
- * @param ContainerInterface|null $container The container.
42
  */
43
- public function run( ContainerInterface $container ): void {
44
 
45
- $asset_loader = $container->get( 'onboarding.assets' );
46
  /**
47
  * The OnboardingAssets.
48
  *
@@ -65,11 +61,11 @@ class OnboardingModule implements ModuleInterface {
65
 
66
  add_filter(
67
  'woocommerce_form_field',
68
- static function ( $field, $key, $config ) use ( $container ) {
69
  if ( 'ppcp_onboarding' !== $config['type'] ) {
70
  return $field;
71
  }
72
- $renderer = $container->get( 'onboarding.render' );
73
  $is_production = 'production' === $config['env'];
74
 
75
  /**
@@ -89,8 +85,8 @@ class OnboardingModule implements ModuleInterface {
89
 
90
  add_action(
91
  'wc_ajax_' . LoginSellerEndpoint::ENDPOINT,
92
- static function () use ( $container ) {
93
- $endpoint = $container->get( 'onboarding.endpoint.login-seller' );
94
 
95
  /**
96
  * The ChangeCartEndpoint.
@@ -102,7 +98,7 @@ class OnboardingModule implements ModuleInterface {
102
  );
103
 
104
  // Initialize REST routes at the appropriate time.
105
- $rest_controller = $container->get( 'onboarding.rest' );
106
  add_action( 'rest_api_init', array( $rest_controller, 'register_routes' ) );
107
  }
108
 
24
  class OnboardingModule implements ModuleInterface {
25
 
26
  /**
27
+ * {@inheritDoc}
 
 
28
  */
29
  public function setup(): ServiceProviderInterface {
30
  return new ServiceProvider(
34
  }
35
 
36
  /**
37
+ * {@inheritDoc}
 
 
38
  */
39
+ public function run( ContainerInterface $c ): void {
40
 
41
+ $asset_loader = $c->get( 'onboarding.assets' );
42
  /**
43
  * The OnboardingAssets.
44
  *
61
 
62
  add_filter(
63
  'woocommerce_form_field',
64
+ static function ( $field, $key, $config ) use ( $c ) {
65
  if ( 'ppcp_onboarding' !== $config['type'] ) {
66
  return $field;
67
  }
68
+ $renderer = $c->get( 'onboarding.render' );
69
  $is_production = 'production' === $config['env'];
70
 
71
  /**
85
 
86
  add_action(
87
  'wc_ajax_' . LoginSellerEndpoint::ENDPOINT,
88
+ static function () use ( $c ) {
89
+ $endpoint = $c->get( 'onboarding.endpoint.login-seller' );
90
 
91
  /**
92
  * The ChangeCartEndpoint.
98
  );
99
 
100
  // Initialize REST routes at the appropriate time.
101
+ $rest_controller = $c->get( 'onboarding.rest' );
102
  add_action( 'rest_api_init', array( $rest_controller, 'register_routes' ) );
103
  }
104
 
modules/ppcp-onboarding/src/{class-onboarding-rest-controller.php → OnboardingRESTController.php} RENAMED
@@ -16,7 +16,7 @@ use WooCommerce\PayPalCommerce\WcGateway\Gateway\PayPalGateway;
16
  /**
17
  * Exposes and handles REST routes related to onboarding.
18
  */
19
- class Onboarding_REST_Controller {
20
 
21
  /**
22
  * REST namespace.
16
  /**
17
  * Exposes and handles REST routes related to onboarding.
18
  */
19
+ class OnboardingRESTController {
20
 
21
  /**
22
  * REST namespace.
modules/ppcp-onboarding/src/Render/{class-onboardingrenderer.php → OnboardingRenderer.php} RENAMED
File without changes
modules/ppcp-onboarding/src/{class-state.php → State.php} RENAMED
File without changes
modules/ppcp-session/composer.json ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "woocommerce/ppcp-session",
3
+ "type": "dhii-mod",
4
+ "description": "Session module for PPCP",
5
+ "license": "GPL-2.0",
6
+ "require": {
7
+ "php": "^7.1 | ^8.0",
8
+ "dhii/module-interface": "^0.3.0-alpha1"
9
+ },
10
+ "autoload": {
11
+ "psr-4": {
12
+ "WooCommerce\\PayPalCommerce\\Session\\": "src"
13
+ }
14
+ },
15
+ "minimum-stability": "dev",
16
+ "prefer-stable": true
17
+ }
modules/ppcp-session/services.php CHANGED
@@ -9,12 +9,12 @@ declare(strict_types=1);
9
 
10
  namespace WooCommerce\PayPalCommerce\Session;
11
 
12
- use Dhii\Data\Container\ContainerInterface;
13
  use WooCommerce\PayPalCommerce\Session\Cancellation\CancelController;
14
  use WooCommerce\PayPalCommerce\Session\Cancellation\CancelView;
15
 
16
  return array(
17
- 'session.handler' => function ( $container ) : SessionHandler {
18
 
19
  if ( is_null( WC()->session ) ) {
20
  return new SessionHandler();
@@ -27,10 +27,10 @@ return array(
27
  WC()->session->set( SessionHandler::ID, $session_handler );
28
  return $session_handler;
29
  },
30
- 'session.cancellation.view' => function ( $container ) : CancelView {
31
  return new CancelView();
32
  },
33
- 'session.cancellation.controller' => function ( $container ) : CancelController {
34
  return new CancelController(
35
  $container->get( 'session.handler' ),
36
  $container->get( 'session.cancellation.view' )
9
 
10
  namespace WooCommerce\PayPalCommerce\Session;
11
 
12
+ use Psr\Container\ContainerInterface;
13
  use WooCommerce\PayPalCommerce\Session\Cancellation\CancelController;
14
  use WooCommerce\PayPalCommerce\Session\Cancellation\CancelView;
15
 
16
  return array(
17
+ 'session.handler' => function ( ContainerInterface $container ) : SessionHandler {
18
 
19
  if ( is_null( WC()->session ) ) {
20
  return new SessionHandler();
27
  WC()->session->set( SessionHandler::ID, $session_handler );
28
  return $session_handler;
29
  },
30
+ 'session.cancellation.view' => function ( ContainerInterface $container ) : CancelView {
31
  return new CancelView();
32
  },
33
+ 'session.cancellation.controller' => function ( ContainerInterface $container ) : CancelController {
34
  return new CancelController(
35
  $container->get( 'session.handler' ),
36
  $container->get( 'session.cancellation.view' )
modules/ppcp-session/src/Cancellation/{class-cancelcontroller.php → CancelController.php} RENAMED
File without changes
modules/ppcp-session/src/Cancellation/{class-cancelview.php → CancelView.php} RENAMED
File without changes
modules/ppcp-session/src/{class-sessionhandler.php → SessionHandler.php} RENAMED
File without changes
modules/ppcp-session/src/{class-sessionmodule.php → SessionModule.php} RENAMED
@@ -21,9 +21,7 @@ use Psr\Container\ContainerInterface;
21
  class SessionModule implements ModuleInterface {
22
 
23
  /**
24
- * Sets up the module.
25
- *
26
- * @return ServiceProviderInterface
27
  */
28
  public function setup(): ServiceProviderInterface {
29
  return new ServiceProvider(
@@ -33,15 +31,13 @@ class SessionModule implements ModuleInterface {
33
  }
34
 
35
  /**
36
- * Run the module.
37
- *
38
- * @param ContainerInterface|null $container The container.
39
  */
40
- public function run( ContainerInterface $container ): void {
41
  add_action(
42
  'woocommerce_init',
43
- function () use ( $container ) {
44
- $controller = $container->get( 'session.cancellation.controller' );
45
  /**
46
  * The Cancel controller.
47
  *
21
  class SessionModule implements ModuleInterface {
22
 
23
  /**
24
+ * {@inheritDoc}
 
 
25
  */
26
  public function setup(): ServiceProviderInterface {
27
  return new ServiceProvider(
31
  }
32
 
33
  /**
34
+ * {@inheritDoc}
 
 
35
  */
36
+ public function run( ContainerInterface $c ): void {
37
  add_action(
38
  'woocommerce_init',
39
+ function () use ( $c ) {
40
+ $controller = $c->get( 'session.cancellation.controller' );
41
  /**
42
  * The Cancel controller.
43
  *
modules/ppcp-status-report/composer.json ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "woocommerce/ppcp-status-report",
3
+ "type": "dhii-mod",
4
+ "description": "Status report module for PPCP",
5
+ "license": "GPL-2.0",
6
+ "require": {
7
+ "php": "^7.1 | ^8.0",
8
+ "dhii/module-interface": "^0.3.0-alpha1"
9
+ },
10
+ "autoload": {
11
+ "psr-4": {
12
+ "WooCommerce\\PayPalCommerce\\StatusReport\\": "src"
13
+ }
14
+ },
15
+ "minimum-stability": "dev",
16
+ "prefer-stable": true
17
+ }
modules/ppcp-status-report/services.php CHANGED
@@ -10,7 +10,7 @@ declare(strict_types=1);
10
  namespace WooCommerce\PayPalCommerce\StatusReport;
11
 
12
  return array(
13
- 'status-report.renderer' => static function ( $container ): Renderer {
14
  return new Renderer();
15
  },
16
  );
10
  namespace WooCommerce\PayPalCommerce\StatusReport;
11
 
12
  return array(
13
+ 'status-report.renderer' => static function (): Renderer {
14
  return new Renderer();
15
  },
16
  );
modules/ppcp-status-report/src/{class-renderer.php → Renderer.php} RENAMED
File without changes
modules/ppcp-status-report/src/{class-statusreportmodule.php → StatusReportModule.php} RENAMED
@@ -38,27 +38,27 @@ class StatusReportModule implements ModuleInterface {
38
  /**
39
  * {@inheritDoc}
40
  *
41
- * @param ContainerInterface $container A services container instance.
42
  */
43
- public function run( ContainerInterface $container ): void {
44
  add_action(
45
  'woocommerce_system_status_report',
46
- function () use ( $container ) {
47
 
48
  /* @var State $state The state. */
49
- $state = $container->get( 'onboarding.state' );
50
 
51
  /* @var Bearer $bearer The bearer. */
52
- $bearer = $container->get( 'api.bearer' );
53
 
54
  /* @var DccApplies $dcc_applies The ddc applies. */
55
- $dcc_applies = $container->get( 'api.helpers.dccapplies' );
56
 
57
  /* @var MessagesApply $messages_apply The messages apply. */
58
- $messages_apply = $container->get( 'button.helper.messages-apply' );
59
 
60
  /* @var Renderer $renderer The renderer. */
61
- $renderer = $container->get( 'status-report.renderer' );
62
 
63
  $items = array(
64
  array(
38
  /**
39
  * {@inheritDoc}
40
  *
41
+ * @param ContainerInterface $c A services container instance.
42
  */
43
+ public function run( ContainerInterface $c ): void {
44
  add_action(
45
  'woocommerce_system_status_report',
46
+ function () use ( $c ) {
47
 
48
  /* @var State $state The state. */
49
+ $state = $c->get( 'onboarding.state' );
50
 
51
  /* @var Bearer $bearer The bearer. */
52
+ $bearer = $c->get( 'api.bearer' );
53
 
54
  /* @var DccApplies $dcc_applies The ddc applies. */
55
+ $dcc_applies = $c->get( 'api.helpers.dccapplies' );
56
 
57
  /* @var MessagesApply $messages_apply The messages apply. */
58
+ $messages_apply = $c->get( 'button.helper.messages-apply' );
59
 
60
  /* @var Renderer $renderer The renderer. */
61
+ $renderer = $c->get( 'status-report.renderer' );
62
 
63
  $items = array(
64
  array(
modules/ppcp-subscription/composer.json ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "woocommerce/ppcp-subscription",
3
+ "type": "dhii-mod",
4
+ "description": "Subscription module for PPCP",
5
+ "license": "GPL-2.0",
6
+ "require": {
7
+ "php": "^7.1 | ^8.0",
8
+ "dhii/module-interface": "^0.3.0-alpha1"
9
+ },
10
+ "autoload": {
11
+ "psr-4": {
12
+ "WooCommerce\\PayPalCommerce\\Subscription\\": "src"
13
+ }
14
+ },
15
+ "minimum-stability": "dev",
16
+ "prefer-stable": true
17
+ }
modules/ppcp-subscription/services.php CHANGED
@@ -10,12 +10,14 @@ declare(strict_types=1);
10
  namespace WooCommerce\PayPalCommerce\Subscription;
11
 
12
  use WooCommerce\PayPalCommerce\Subscription\Helper\SubscriptionHelper;
 
 
13
 
14
  return array(
15
- 'subscription.helper' => static function ( $container ): SubscriptionHelper {
16
  return new SubscriptionHelper();
17
  },
18
- 'subscription.renewal-handler' => static function ( $container ): RenewalHandler {
19
  $logger = $container->get( 'woocommerce.logger.woocommerce' );
20
  $repository = $container->get( 'vaulting.repository.payment-token' );
21
  $endpoint = $container->get( 'api.endpoint.order' );
@@ -29,4 +31,9 @@ return array(
29
  $payer_factory
30
  );
31
  },
 
 
 
 
 
32
  );
10
  namespace WooCommerce\PayPalCommerce\Subscription;
11
 
12
  use WooCommerce\PayPalCommerce\Subscription\Helper\SubscriptionHelper;
13
+ use Psr\Container\ContainerInterface;
14
+ use WooCommerce\PayPalCommerce\Vaulting\PaymentTokenRepository;
15
 
16
  return array(
17
+ 'subscription.helper' => static function ( ContainerInterface $container ): SubscriptionHelper {
18
  return new SubscriptionHelper();
19
  },
20
+ 'subscription.renewal-handler' => static function ( ContainerInterface $container ): RenewalHandler {
21
  $logger = $container->get( 'woocommerce.logger.woocommerce' );
22
  $repository = $container->get( 'vaulting.repository.payment-token' );
23
  $endpoint = $container->get( 'api.endpoint.order' );
31
  $payer_factory
32
  );
33
  },
34
+ 'subscription.repository.payment-token' => static function ( ContainerInterface $container ): PaymentTokenRepository {
35
+ $factory = $container->get( 'api.factory.payment-token' );
36
+ $endpoint = $container->get( 'api.endpoint.payment-token' );
37
+ return new PaymentTokenRepository( $factory, $endpoint );
38
+ },
39
  );
modules/ppcp-subscription/src/Helper/{class-subscriptionhelper.php → SubscriptionHelper.php} RENAMED
@@ -47,7 +47,7 @@ class SubscriptionHelper {
47
  if ( ! isset( $item['data'] ) || ! is_a( $item['data'], \WC_Product::class ) ) {
48
  continue;
49
  }
50
- if ( $item['data']->is_type( 'subscription' ) ) {
51
  return true;
52
  }
53
  }
47
  if ( ! isset( $item['data'] ) || ! is_a( $item['data'], \WC_Product::class ) ) {
48
  continue;
49
  }
50
+ if ( $item['data']->is_type( 'subscription' ) || $item['data']->is_type( 'subscription_variation' ) ) {
51
  return true;
52
  }
53
  }
modules/ppcp-subscription/src/{class-renewalhandler.php → RenewalHandler.php} RENAMED
@@ -18,6 +18,7 @@ use WooCommerce\PayPalCommerce\ApiClient\Factory\PurchaseUnitFactory;
18
  use WooCommerce\PayPalCommerce\Vaulting\PaymentTokenRepository;
19
  use WooCommerce\PayPalCommerce\WcGateway\Gateway\PayPalGateway;
20
  use Psr\Log\LoggerInterface;
 
21
 
22
  /**
23
  * Class RenewalHandler
@@ -240,7 +241,7 @@ class RenewalHandler {
240
 
241
  if ( $order->intent() === 'AUTHORIZE' ) {
242
  $this->order_endpoint->authorize( $order );
243
- $wc_order->update_meta_data( PayPalGateway::CAPTURED_META_KEY, 'false' );
244
  }
245
  }
246
  }
18
  use WooCommerce\PayPalCommerce\Vaulting\PaymentTokenRepository;
19
  use WooCommerce\PayPalCommerce\WcGateway\Gateway\PayPalGateway;
20
  use Psr\Log\LoggerInterface;
21
+ use WooCommerce\PayPalCommerce\WcGateway\Processor\AuthorizedPaymentsProcessor;
22
 
23
  /**
24
  * Class RenewalHandler
241
 
242
  if ( $order->intent() === 'AUTHORIZE' ) {
243
  $this->order_endpoint->authorize( $order );
244
+ $wc_order->update_meta_data( AuthorizedPaymentsProcessor::CAPTURED_META_KEY, 'false' );
245
  }
246
  }
247
  }
modules/ppcp-subscription/src/{class-subscriptionmodule.php → SubscriptionModule.php} RENAMED
@@ -28,9 +28,7 @@ use WooCommerce\PayPalCommerce\WcGateway\Exception\NotFoundException;
28
  class SubscriptionModule implements ModuleInterface {
29
 
30
  /**
31
- * Setup the module.
32
- *
33
- * @return ServiceProviderInterface
34
  */
35
  public function setup(): ServiceProviderInterface {
36
  return new ServiceProvider(
@@ -40,15 +38,13 @@ class SubscriptionModule implements ModuleInterface {
40
  }
41
 
42
  /**
43
- * Runs the module.
44
- *
45
- * @param ContainerInterface|null $container The container.
46
  */
47
- public function run( ContainerInterface $container ): void {
48
  add_action(
49
  'woocommerce_scheduled_subscription_payment_' . PayPalGateway::ID,
50
- function ( $amount, $order ) use ( $container ) {
51
- $this->renew( $order, $container );
52
  },
53
  10,
54
  2
@@ -56,8 +52,8 @@ class SubscriptionModule implements ModuleInterface {
56
 
57
  add_action(
58
  'woocommerce_scheduled_subscription_payment_' . CreditCardGateway::ID,
59
- function ( $amount, $order ) use ( $container ) {
60
- $this->renew( $order, $container );
61
  },
62
  10,
63
  2
@@ -65,9 +61,9 @@ class SubscriptionModule implements ModuleInterface {
65
 
66
  add_action(
67
  'woocommerce_subscription_payment_complete',
68
- function ( $subscription ) use ( $container ) {
69
- $payment_token_repository = $container->get( 'vaulting.repository.payment-token' );
70
- $logger = $container->get( 'woocommerce.logger.woocommerce' );
71
 
72
  $this->add_payment_token_id( $subscription, $payment_token_repository, $logger );
73
  }
@@ -75,10 +71,10 @@ class SubscriptionModule implements ModuleInterface {
75
 
76
  add_filter(
77
  'woocommerce_gateway_description',
78
- function ( $description, $id ) use ( $container ) {
79
- $payment_token_repository = $container->get( 'vaulting.repository.payment-token' );
80
- $settings = $container->get( 'wcgateway.settings' );
81
- $subscription_helper = $container->get( 'subscription.helper' );
82
 
83
  return $this->display_saved_paypal_payments( $settings, (string) $id, $payment_token_repository, (string) $description, $subscription_helper );
84
  },
@@ -88,10 +84,10 @@ class SubscriptionModule implements ModuleInterface {
88
 
89
  add_filter(
90
  'woocommerce_credit_card_form_fields',
91
- function ( $default_fields, $id ) use ( $container ) {
92
- $payment_token_repository = $container->get( 'vaulting.repository.payment-token' );
93
- $settings = $container->get( 'wcgateway.settings' );
94
- $subscription_helper = $container->get( 'subscription.helper' );
95
 
96
  return $this->display_saved_credit_cards( $settings, $id, $payment_token_repository, $default_fields, $subscription_helper );
97
  },
@@ -116,7 +112,7 @@ class SubscriptionModule implements ModuleInterface {
116
  * @return void
117
  */
118
  protected function renew( $order, $container ) {
119
- if ( ! is_a( $order, \WC_Order::class ) ) {
120
  return;
121
  }
122
 
28
  class SubscriptionModule implements ModuleInterface {
29
 
30
  /**
31
+ * {@inheritDoc}
 
 
32
  */
33
  public function setup(): ServiceProviderInterface {
34
  return new ServiceProvider(
38
  }
39
 
40
  /**
41
+ * {@inheritDoc}
 
 
42
  */
43
+ public function run( ContainerInterface $c ): void {
44
  add_action(
45
  'woocommerce_scheduled_subscription_payment_' . PayPalGateway::ID,
46
+ function ( $amount, $order ) use ( $c ) {
47
+ $this->renew( $order, $c );
48
  },
49
  10,
50
  2
52
 
53
  add_action(
54
  'woocommerce_scheduled_subscription_payment_' . CreditCardGateway::ID,
55
+ function ( $amount, $order ) use ( $c ) {
56
+ $this->renew( $order, $c );
57
  },
58
  10,
59
  2
61
 
62
  add_action(
63
  'woocommerce_subscription_payment_complete',
64
+ function ( $subscription ) use ( $c ) {
65
+ $payment_token_repository = $c->get( 'vaulting.repository.payment-token' );
66
+ $logger = $c->get( 'woocommerce.logger.woocommerce' );
67
 
68
  $this->add_payment_token_id( $subscription, $payment_token_repository, $logger );
69
  }
71
 
72
  add_filter(
73
  'woocommerce_gateway_description',
74
+ function ( $description, $id ) use ( $c ) {
75
+ $payment_token_repository = $c->get( 'vaulting.repository.payment-token' );
76
+ $settings = $c->get( 'wcgateway.settings' );
77
+ $subscription_helper = $c->get( 'subscription.helper' );
78
 
79
  return $this->display_saved_paypal_payments( $settings, (string) $id, $payment_token_repository, (string) $description, $subscription_helper );
80
  },
84
 
85
  add_filter(
86
  'woocommerce_credit_card_form_fields',
87
+ function ( $default_fields, $id ) use ( $c ) {
88
+ $payment_token_repository = $c->get( 'vaulting.repository.payment-token' );
89
+ $settings = $c->get( 'wcgateway.settings' );
90
+ $subscription_helper = $c->get( 'subscription.helper' );
91
 
92
  return $this->display_saved_credit_cards( $settings, $id, $payment_token_repository, $default_fields, $subscription_helper );
93
  },
112
  * @return void
113
  */
114
  protected function renew( $order, $container ) {
115
+ if ( ! ( $order instanceof \WC_Order ) ) {
116
  return;
117
  }
118
 
modules/ppcp-vaulting/composer.json ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "woocommerce/ppcp-vaulting",
3
+ "type": "dhii-mod",
4
+ "description": "Vaulting module for PPCP",
5
+ "license": "GPL-2.0",
6
+ "require": {
7
+ "php": "^7.1 | ^8.0",
8
+ "dhii/module-interface": "^0.3.0-alpha1"
9
+ },
10
+ "autoload": {
11
+ "psr-4": {
12
+ "WooCommerce\\PayPalCommerce\\Vaulting\\": "src"
13
+ }
14
+ },
15
+ "minimum-stability": "dev",
16
+ "prefer-stable": true
17
+ }
modules/ppcp-vaulting/services.php CHANGED
@@ -9,17 +9,18 @@ declare(strict_types=1);
9
 
10
  namespace WooCommerce\PayPalCommerce\Vaulting;
11
 
 
12
  use WooCommerce\PayPalCommerce\Vaulting\Assets\MyAccountPaymentsAssets;
13
  use WooCommerce\PayPalCommerce\Vaulting\Endpoint\DeletePaymentTokenEndpoint;
14
 
15
  return array(
16
- 'vaulting.module-url' => static function ( $container ): string {
17
  return plugins_url(
18
  '/modules/ppcp-vaulting/',
19
  dirname( __FILE__, 3 ) . '/woocommerce-paypal-payments.php'
20
  );
21
  },
22
- 'vaulting.assets.myaccount-payments' => function( $container ) : MyAccountPaymentsAssets {
23
  return new MyAccountPaymentsAssets(
24
  $container->get( 'vaulting.module-url' )
25
  );
@@ -27,12 +28,12 @@ return array(
27
  'vaulting.payment-tokens-renderer' => static function (): PaymentTokensRenderer {
28
  return new PaymentTokensRenderer();
29
  },
30
- 'vaulting.repository.payment-token' => static function ( $container ): PaymentTokenRepository {
31
  $factory = $container->get( 'api.factory.payment-token' );
32
  $endpoint = $container->get( 'api.endpoint.payment-token' );
33
  return new PaymentTokenRepository( $factory, $endpoint );
34
  },
35
- 'vaulting.endpoint.delete' => function( $container ) : DeletePaymentTokenEndpoint {
36
  return new DeletePaymentTokenEndpoint(
37
  $container->get( 'vaulting.repository.payment-token' ),
38
  $container->get( 'button.request-data' ),
9
 
10
  namespace WooCommerce\PayPalCommerce\Vaulting;
11
 
12
+ use Psr\Container\ContainerInterface;
13
  use WooCommerce\PayPalCommerce\Vaulting\Assets\MyAccountPaymentsAssets;
14
  use WooCommerce\PayPalCommerce\Vaulting\Endpoint\DeletePaymentTokenEndpoint;
15
 
16
  return array(
17
+ 'vaulting.module-url' => static function ( ContainerInterface $container ): string {
18
  return plugins_url(
19
  '/modules/ppcp-vaulting/',
20
  dirname( __FILE__, 3 ) . '/woocommerce-paypal-payments.php'
21
  );
22
  },
23
+ 'vaulting.assets.myaccount-payments' => function( ContainerInterface $container ) : MyAccountPaymentsAssets {
24
  return new MyAccountPaymentsAssets(
25
  $container->get( 'vaulting.module-url' )
26
  );
28
  'vaulting.payment-tokens-renderer' => static function (): PaymentTokensRenderer {
29
  return new PaymentTokensRenderer();
30
  },
31
+ 'vaulting.repository.payment-token' => static function ( ContainerInterface $container ): PaymentTokenRepository {
32
  $factory = $container->get( 'api.factory.payment-token' );
33
  $endpoint = $container->get( 'api.endpoint.payment-token' );
34
  return new PaymentTokenRepository( $factory, $endpoint );
35
  },
36
+ 'vaulting.endpoint.delete' => function( ContainerInterface $container ) : DeletePaymentTokenEndpoint {
37
  return new DeletePaymentTokenEndpoint(
38
  $container->get( 'vaulting.repository.payment-token' ),
39
  $container->get( 'button.request-data' ),
modules/ppcp-vaulting/src/Assets/{class-myaccountpaymentsassets.php → MyAccountPaymentsAssets.php} RENAMED
@@ -24,7 +24,7 @@ class MyAccountPaymentsAssets {
24
  private $module_url;
25
 
26
  /**
27
- * WebhooksStatusPageAssets constructor.
28
  *
29
  * @param string $module_url The URL to the module.
30
  */
24
  private $module_url;
25
 
26
  /**
27
+ * MyAccountPaymentsAssets constructor.
28
  *
29
  * @param string $module_url The URL to the module.
30
  */
modules/ppcp-vaulting/src/Endpoint/{class-deletepaymenttokenendpoint.php → DeletePaymentTokenEndpoint.php} RENAMED
File without changes
modules/ppcp-vaulting/src/{class-paymenttokenrepository.php → PaymentTokenRepository.php} RENAMED
File without changes
modules/ppcp-vaulting/src/{class-paymenttokensrenderer.php → PaymentTokensRenderer.php} RENAMED
File without changes
modules/ppcp-vaulting/src/{class-vaultingmodule.php → VaultingModule.php} RENAMED
@@ -57,6 +57,27 @@ class VaultingModule implements ModuleInterface {
57
  }
58
  );
59
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
60
  add_action(
61
  'woocommerce_account_ppcp-paypal-payment-tokens_endpoint',
62
  function () use ( $container ) {
57
  }
58
  );
59
 
60
+ add_action(
61
+ 'woocommerce_paypal_payments_gateway_migrate',
62
+ function () {
63
+ add_action(
64
+ 'init',
65
+ function () {
66
+ add_rewrite_endpoint( 'ppcp-paypal-payment-tokens', EP_PAGES );
67
+ flush_rewrite_rules();
68
+ }
69
+ );
70
+ }
71
+ );
72
+
73
+ add_action(
74
+ 'woocommerce_paypal_payments_gateway_activate',
75
+ function () {
76
+ add_rewrite_endpoint( 'ppcp-paypal-payment-tokens', EP_PAGES );
77
+ flush_rewrite_rules();
78
+ }
79
+ );
80
+
81
  add_action(
82
  'woocommerce_account_ppcp-paypal-payment-tokens_endpoint',
83
  function () use ( $container ) {
modules/ppcp-wc-gateway/composer.json ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "woocommerce/ppcp-wc-gateway",
3
+ "type": "dhii-mod",
4
+ "description": "WC gateway module for PPCP",
5
+ "license": "GPL-2.0",
6
+ "require": {
7
+ "php": "^7.1 | ^8.0",
8
+ "dhii/module-interface": "^0.3.0-alpha1"
9
+ },
10
+ "autoload": {
11
+ "psr-4": {
12
+ "WooCommerce\\PayPalCommerce\\WcGateway\\": "src"
13
+ }
14
+ },
15
+ "minimum-stability": "dev",
16
+ "prefer-stable": true
17
+ }
modules/ppcp-wc-gateway/extensions.php CHANGED
@@ -20,15 +20,15 @@ use Psr\Log\LoggerInterface;
20
 
21
  return array(
22
 
23
- 'api.merchant_email' => static function ( $container ): string {
24
  $settings = $container->get( 'wcgateway.settings' );
25
  return $settings->has( 'merchant_email' ) ? (string) $settings->get( 'merchant_email' ) : '';
26
  },
27
- 'api.merchant_id' => static function ( $container ): string {
28
  $settings = $container->get( 'wcgateway.settings' );
29
  return $settings->has( 'merchant_id' ) ? (string) $settings->get( 'merchant_id' ) : '';
30
  },
31
- 'api.partner_merchant_id' => static function ( $container ): string {
32
  $environment = $container->get( 'onboarding.environment' );
33
 
34
  /**
@@ -39,20 +39,20 @@ return array(
39
  return $environment->current_environment_is( Environment::SANDBOX ) ?
40
  (string) $container->get( 'api.partner_merchant_id-sandbox' ) : (string) $container->get( 'api.partner_merchant_id-production' );
41
  },
42
- 'api.key' => static function ( $container ): string {
43
  $settings = $container->get( 'wcgateway.settings' );
44
  $key = $settings->has( 'client_id' ) ? (string) $settings->get( 'client_id' ) : '';
45
  return $key;
46
  },
47
- 'api.secret' => static function ( $container ): string {
48
  $settings = $container->get( 'wcgateway.settings' );
49
  return $settings->has( 'client_secret' ) ? (string) $settings->get( 'client_secret' ) : '';
50
  },
51
- 'api.prefix' => static function ( $container ): string {
52
  $settings = $container->get( 'wcgateway.settings' );
53
  return $settings->has( 'prefix' ) ? (string) $settings->get( 'prefix' ) : 'WC-';
54
  },
55
- 'api.endpoint.order' => static function ( $container ): OrderEndpoint {
56
  $order_factory = $container->get( 'api.factory.order' );
57
  $patch_collection_factory = $container->get( 'api.factory.patch-collection-factory' );
58
  $logger = $container->get( 'woocommerce.logger.woocommerce' );
@@ -73,6 +73,7 @@ return array(
73
  $intent = $settings->has( 'intent' ) && strtoupper( (string) $settings->get( 'intent' ) ) === 'AUTHORIZE' ? 'AUTHORIZE' : 'CAPTURE';
74
  $application_context_repository = $container->get( 'api.repository.application-context' );
75
  $pay_pal_request_id_repository = $container->get( 'api.repository.paypal-request-id' );
 
76
  return new OrderEndpoint(
77
  $container->get( 'api.host' ),
78
  $container->get( 'api.bearer' ),
@@ -82,10 +83,11 @@ return array(
82
  $logger,
83
  $application_context_repository,
84
  $pay_pal_request_id_repository,
 
85
  $bn_code
86
  );
87
  },
88
- 'woocommerce.logger.woocommerce' => function ( $container ): LoggerInterface {
89
  $settings = $container->get( 'wcgateway.settings' );
90
  if ( ! function_exists( 'wc_get_logger' ) || ! $settings->has( 'logging_enabled' ) || ! $settings->get( 'logging_enabled' ) ) {
91
  return new NullLogger();
20
 
21
  return array(
22
 
23
+ 'api.merchant_email' => static function ( ContainerInterface $container ): string {
24
  $settings = $container->get( 'wcgateway.settings' );
25
  return $settings->has( 'merchant_email' ) ? (string) $settings->get( 'merchant_email' ) : '';
26
  },
27
+ 'api.merchant_id' => static function ( ContainerInterface $container ): string {
28
  $settings = $container->get( 'wcgateway.settings' );
29
  return $settings->has( 'merchant_id' ) ? (string) $settings->get( 'merchant_id' ) : '';
30
  },
31
+ 'api.partner_merchant_id' => static function ( ContainerInterface $container ): string {
32
  $environment = $container->get( 'onboarding.environment' );
33
 
34
  /**
39
  return $environment->current_environment_is( Environment::SANDBOX ) ?
40
  (string) $container->get( 'api.partner_merchant_id-sandbox' ) : (string) $container->get( 'api.partner_merchant_id-production' );
41
  },
42
+ 'api.key' => static function ( ContainerInterface $container ): string {
43
  $settings = $container->get( 'wcgateway.settings' );
44
  $key = $settings->has( 'client_id' ) ? (string) $settings->get( 'client_id' ) : '';
45
  return $key;
46
  },
47
+ 'api.secret' => static function ( ContainerInterface $container ): string {
48
  $settings = $container->get( 'wcgateway.settings' );
49
  return $settings->has( 'client_secret' ) ? (string) $settings->get( 'client_secret' ) : '';
50
  },
51
+ 'api.prefix' => static function ( ContainerInterface $container ): string {
52
  $settings = $container->get( 'wcgateway.settings' );
53
  return $settings->has( 'prefix' ) ? (string) $settings->get( 'prefix' ) : 'WC-';
54
  },
55
+ 'api.endpoint.order' => static function ( ContainerInterface $container ): OrderEndpoint {
56
  $order_factory = $container->get( 'api.factory.order' );
57
  $patch_collection_factory = $container->get( 'api.factory.patch-collection-factory' );
58
  $logger = $container->get( 'woocommerce.logger.woocommerce' );
73
  $intent = $settings->has( 'intent' ) && strtoupper( (string) $settings->get( 'intent' ) ) === 'AUTHORIZE' ? 'AUTHORIZE' : 'CAPTURE';
74
  $application_context_repository = $container->get( 'api.repository.application-context' );
75
  $pay_pal_request_id_repository = $container->get( 'api.repository.paypal-request-id' );
76
+ $subscription_helper = $container->get( 'subscription.helper' );
77
  return new OrderEndpoint(
78
  $container->get( 'api.host' ),
79
  $container->get( 'api.bearer' ),
83
  $logger,
84
  $application_context_repository,
85
  $pay_pal_request_id_repository,
86
+ $subscription_helper,
87
  $bn_code
88
  );
89
  },
90
+ 'woocommerce.logger.woocommerce' => function ( ContainerInterface $container ): LoggerInterface {
91
  $settings = $container->get( 'wcgateway.settings' );
92
  if ( ! function_exists( 'wc_get_logger' ) || ! $settings->has( 'logging_enabled' ) || ! $settings->get( 'logging_enabled' ) ) {
93
  return new NullLogger();
modules/ppcp-wc-gateway/module.php CHANGED
@@ -12,5 +12,5 @@ namespace WooCommerce\PayPalCommerce\WcGateway;
12
  use Dhii\Modular\Module\ModuleInterface;
13
 
14
  return static function (): ModuleInterface {
15
- return new WcGatewayModule();
16
  };
12
  use Dhii\Modular\Module\ModuleInterface;
13
 
14
  return static function (): ModuleInterface {
15
+ return new WCGatewayModule();
16
  };
modules/ppcp-wc-gateway/services.php CHANGED
@@ -11,6 +11,7 @@ declare(strict_types=1);
11
 
12
  namespace WooCommerce\PayPalCommerce\WcGateway;
13
 
 
14
  use WooCommerce\PayPalCommerce\ApiClient\Entity\ApplicationContext;
15
  use WooCommerce\PayPalCommerce\ApiClient\Helper\Cache;
16
  use WooCommerce\PayPalCommerce\ApiClient\Helper\DccApplies;
@@ -26,8 +27,8 @@ use WooCommerce\PayPalCommerce\WcGateway\Endpoint\ReturnUrlEndpoint;
26
  use WooCommerce\PayPalCommerce\WcGateway\Gateway\CreditCardGateway;
27
  use WooCommerce\PayPalCommerce\WcGateway\Gateway\PayPalGateway;
28
  use WooCommerce\PayPalCommerce\WcGateway\Gateway\TransactionUrlProvider;
29
- use Woocommerce\PayPalCommerce\WcGateway\Helper\DccProductStatus;
30
- use Woocommerce\PayPalCommerce\WcGateway\Helper\SettingsStatus;
31
  use WooCommerce\PayPalCommerce\WcGateway\Notice\AuthorizeOrderActionNotice;
32
  use WooCommerce\PayPalCommerce\WcGateway\Notice\ConnectAdminNotice;
33
  use WooCommerce\PayPalCommerce\WcGateway\Notice\DccWithoutPayPalAdminNotice;
@@ -41,11 +42,10 @@ use WooCommerce\PayPalCommerce\WcGateway\Settings\SettingsRenderer;
41
  use WooCommerce\PayPalCommerce\Webhooks\Status\WebhooksStatusPage;
42
 
43
  return array(
44
- 'wcgateway.paypal-gateway' => static function ( $container ): PayPalGateway {
45
  $order_processor = $container->get( 'wcgateway.order-processor' );
46
  $settings_renderer = $container->get( 'wcgateway.settings.render' );
47
  $authorized_payments = $container->get( 'wcgateway.processor.authorized-payments' );
48
- $notice = $container->get( 'wcgateway.notice.authorize-order-action' );
49
  $settings = $container->get( 'wcgateway.settings' );
50
  $session_handler = $container->get( 'session.handler' );
51
  $refund_processor = $container->get( 'wcgateway.processor.refunds' );
@@ -53,12 +53,15 @@ return array(
53
  $transaction_url_provider = $container->get( 'wcgateway.transaction-url-provider' );
54
  $subscription_helper = $container->get( 'subscription.helper' );
55
  $page_id = $container->get( 'wcgateway.current-ppcp-settings-page-id' );
 
 
 
56
  $environment = $container->get( 'onboarding.environment' );
 
57
  return new PayPalGateway(
58
  $settings_renderer,
59
  $order_processor,
60
  $authorized_payments,
61
- $notice,
62
  $settings,
63
  $session_handler,
64
  $refund_processor,
@@ -66,14 +69,17 @@ return array(
66
  $transaction_url_provider,
67
  $subscription_helper,
68
  $page_id,
69
- $environment
 
 
 
 
70
  );
71
  },
72
- 'wcgateway.credit-card-gateway' => static function ( $container ): CreditCardGateway {
73
  $order_processor = $container->get( 'wcgateway.order-processor' );
74
  $settings_renderer = $container->get( 'wcgateway.settings.render' );
75
  $authorized_payments = $container->get( 'wcgateway.processor.authorized-payments' );
76
- $notice = $container->get( 'wcgateway.notice.authorize-order-action' );
77
  $settings = $container->get( 'wcgateway.settings' );
78
  $module_url = $container->get( 'wcgateway.url' );
79
  $session_handler = $container->get( 'session.handler' );
@@ -85,13 +91,13 @@ return array(
85
  $payer_factory = $container->get( 'api.factory.payer' );
86
  $order_endpoint = $container->get( 'api.endpoint.order' );
87
  $subscription_helper = $container->get( 'subscription.helper' );
 
88
  $logger = $container->get( 'woocommerce.logger.woocommerce' );
89
  $environment = $container->get( 'onboarding.environment' );
90
  return new CreditCardGateway(
91
  $settings_renderer,
92
  $order_processor,
93
  $authorized_payments,
94
- $notice,
95
  $settings,
96
  $module_url,
97
  $session_handler,
@@ -104,22 +110,23 @@ return array(
104
  $order_endpoint,
105
  $subscription_helper,
106
  $logger,
107
- $environment
 
108
  );
109
  },
110
- 'wcgateway.disabler' => static function ( $container ): DisableGateways {
111
  $session_handler = $container->get( 'session.handler' );
112
  $settings = $container->get( 'wcgateway.settings' );
113
- return new DisableGateways( $session_handler, $settings );
 
114
  },
115
-
116
- 'wcgateway.is-wc-payments-page' => static function ( $container ): bool {
117
  $page = isset( $_GET['page'] ) ? sanitize_text_field( wp_unslash( $_GET['page'] ) ) : '';
118
  $tab = isset( $_GET['tab'] ) ? sanitize_text_field( wp_unslash( $_GET['tab'] ) ) : '';
119
  return 'wc-settings' === $page && 'checkout' === $tab;
120
  },
121
 
122
- 'wcgateway.is-ppcp-settings-page' => static function ( $container ): bool {
123
  if ( ! $container->get( 'wcgateway.is-wc-payments-page' ) ) {
124
  return false;
125
  }
@@ -128,7 +135,7 @@ return array(
128
  return in_array( $section, array( PayPalGateway::ID, CreditCardGateway::ID, WebhooksStatusPage::ID ), true );
129
  },
130
 
131
- 'wcgateway.current-ppcp-settings-page-id' => static function ( $container ): string {
132
  if ( ! $container->get( 'wcgateway.is-ppcp-settings-page' ) ) {
133
  return '';
134
  }
@@ -139,15 +146,15 @@ return array(
139
  return $ppcp_tab ? $ppcp_tab : $section;
140
  },
141
 
142
- 'wcgateway.settings' => static function ( $container ): Settings {
143
  return new Settings();
144
  },
145
- 'wcgateway.notice.connect' => static function ( $container ): ConnectAdminNotice {
146
  $state = $container->get( 'onboarding.state' );
147
  $settings = $container->get( 'wcgateway.settings' );
148
  return new ConnectAdminNotice( $state, $settings );
149
  },
150
- 'wcgateway.notice.dcc-without-paypal' => static function ( $container ): DccWithoutPayPalAdminNotice {
151
  $state = $container->get( 'onboarding.state' );
152
  $settings = $container->get( 'wcgateway.settings' );
153
  $is_payments_page = $container->get( 'wcgateway.is-wc-payments-page' );
@@ -155,17 +162,17 @@ return array(
155
  return new DccWithoutPayPalAdminNotice( $state, $settings, $is_payments_page, $is_ppcp_settings_page );
156
  },
157
  'wcgateway.notice.authorize-order-action' =>
158
- static function ( $container ): AuthorizeOrderActionNotice {
159
  return new AuthorizeOrderActionNotice();
160
  },
161
- 'wcgateway.settings.sections-renderer' => static function ( $container ): SectionsRenderer {
162
  return new SectionsRenderer( $container->get( 'wcgateway.current-ppcp-settings-page-id' ) );
163
  },
164
- 'wcgateway.settings.status' => static function ( $container ): SettingsStatus {
165
  $settings = $container->get( 'wcgateway.settings' );
166
  return new SettingsStatus( $settings );
167
  },
168
- 'wcgateway.settings.render' => static function ( $container ): SettingsRenderer {
169
  $settings = $container->get( 'wcgateway.settings' );
170
  $state = $container->get( 'onboarding.state' );
171
  $fields = $container->get( 'wcgateway.settings.fields' );
@@ -185,7 +192,7 @@ return array(
185
  $page_id
186
  );
187
  },
188
- 'wcgateway.settings.listener' => static function ( $container ): SettingsListener {
189
  $settings = $container->get( 'wcgateway.settings' );
190
  $fields = $container->get( 'wcgateway.settings.fields' );
191
  $webhook_registrar = $container->get( 'webhook.registrar' );
@@ -195,7 +202,7 @@ return array(
195
  $page_id = $container->get( 'wcgateway.current-ppcp-settings-page-id' );
196
  return new SettingsListener( $settings, $fields, $webhook_registrar, $cache, $state, $bearer, $page_id );
197
  },
198
- 'wcgateway.order-processor' => static function ( $container ): OrderProcessor {
199
 
200
  $session_handler = $container->get( 'session.handler' );
201
  $order_endpoint = $container->get( 'api.endpoint.order' );
@@ -216,32 +223,33 @@ return array(
216
  $environment
217
  );
218
  },
219
- 'wcgateway.processor.refunds' => static function ( $container ): RefundProcessor {
220
  $order_endpoint = $container->get( 'api.endpoint.order' );
221
  $payments_endpoint = $container->get( 'api.endpoint.payments' );
222
  $logger = $container->get( 'woocommerce.logger.woocommerce' );
223
  return new RefundProcessor( $order_endpoint, $payments_endpoint, $logger );
224
  },
225
- 'wcgateway.processor.authorized-payments' => static function ( $container ): AuthorizedPaymentsProcessor {
226
  $order_endpoint = $container->get( 'api.endpoint.order' );
227
  $payments_endpoint = $container->get( 'api.endpoint.payments' );
228
  $logger = $container->get( 'woocommerce.logger.woocommerce' );
229
- return new AuthorizedPaymentsProcessor( $order_endpoint, $payments_endpoint, $logger );
 
230
  },
231
- 'wcgateway.admin.render-authorize-action' => static function ( $container ): RenderAuthorizeAction {
232
-
233
- return new RenderAuthorizeAction();
234
  },
235
- 'wcgateway.admin.order-payment-status' => static function ( $container ): PaymentStatusOrderDetail {
236
  $column = $container->get( 'wcgateway.admin.orders-payment-status-column' );
237
  return new PaymentStatusOrderDetail( $column );
238
  },
239
- 'wcgateway.admin.orders-payment-status-column' => static function ( $container ): OrderTablePaymentStatusColumn {
240
  $settings = $container->get( 'wcgateway.settings' );
241
  return new OrderTablePaymentStatusColumn( $settings );
242
  },
243
 
244
- 'wcgateway.settings.fields' => static function ( $container ): array {
245
 
246
  $state = $container->get( 'onboarding.state' );
247
  $messages_disclaimers = $container->get( 'button.helper.messages-disclaimers' );
@@ -1961,28 +1969,28 @@ return array(
1961
  return $fields;
1962
  },
1963
 
1964
- 'wcgateway.checkout.address-preset' => static function( $container ): CheckoutPayPalAddressPreset {
1965
 
1966
  return new CheckoutPayPalAddressPreset(
1967
  $container->get( 'session.handler' )
1968
  );
1969
  },
1970
- 'wcgateway.url' => static function ( $container ): string {
1971
  return plugins_url(
1972
  $container->get( 'wcgateway.relative-path' ),
1973
  dirname( __FILE__, 3 ) . '/woocommerce-paypal-payments.php'
1974
  );
1975
  },
1976
- 'wcgateway.relative-path' => static function( $container ): string {
1977
  return 'modules/ppcp-wc-gateway/';
1978
  },
1979
- 'wcgateway.absolute-path' => static function( $container ): string {
1980
  return plugin_dir_path(
1981
  dirname( __FILE__, 3 ) . '/woocommerce-paypal-payments.php'
1982
  ) .
1983
  $container->get( 'wcgateway.relative-path' );
1984
  },
1985
- 'wcgateway.endpoint.return-url' => static function ( $container ) : ReturnUrlEndpoint {
1986
  $gateway = $container->get( 'wcgateway.paypal-gateway' );
1987
  $endpoint = $container->get( 'api.endpoint.order' );
1988
  $prefix = $container->get( 'api.prefix' );
@@ -1993,29 +2001,29 @@ return array(
1993
  );
1994
  },
1995
 
1996
- 'wcgateway.transaction-url-sandbox' => static function ( $container ): string {
1997
  return 'https://www.sandbox.paypal.com/cgi-bin/webscr?cmd=_view-a-trans&id=%s';
1998
  },
1999
 
2000
- 'wcgateway.transaction-url-live' => static function ( $container ): string {
2001
  return 'https://www.paypal.com/cgi-bin/webscr?cmd=_view-a-trans&id=%s';
2002
  },
2003
 
2004
- 'wcgateway.transaction-url-provider' => static function ( $container ): TransactionUrlProvider {
2005
  $sandbox_url_base = $container->get( 'wcgateway.transaction-url-sandbox' );
2006
  $live_url_base = $container->get( 'wcgateway.transaction-url-live' );
2007
 
2008
  return new TransactionUrlProvider( $sandbox_url_base, $live_url_base );
2009
  },
2010
 
2011
- 'wcgateway.helper.dcc-product-status' => static function ( $container ) : DccProductStatus {
2012
 
2013
  $settings = $container->get( 'wcgateway.settings' );
2014
  $partner_endpoint = $container->get( 'api.endpoint.partners' );
2015
- return new DccProductStatus( $settings, $partner_endpoint );
2016
  },
2017
 
2018
- 'button.helper.messages-disclaimers' => static function ( $container ): MessagesDisclaimers {
2019
  return new MessagesDisclaimers();
2020
  },
2021
  );
11
 
12
  namespace WooCommerce\PayPalCommerce\WcGateway;
13
 
14
+ use Psr\Container\ContainerInterface;
15
  use WooCommerce\PayPalCommerce\ApiClient\Entity\ApplicationContext;
16
  use WooCommerce\PayPalCommerce\ApiClient\Helper\Cache;
17
  use WooCommerce\PayPalCommerce\ApiClient\Helper\DccApplies;
27
  use WooCommerce\PayPalCommerce\WcGateway\Gateway\CreditCardGateway;
28
  use WooCommerce\PayPalCommerce\WcGateway\Gateway\PayPalGateway;
29
  use WooCommerce\PayPalCommerce\WcGateway\Gateway\TransactionUrlProvider;
30
+ use WooCommerce\PayPalCommerce\WcGateway\Helper\DCCProductStatus;
31
+ use WooCommerce\PayPalCommerce\WcGateway\Helper\SettingsStatus;
32
  use WooCommerce\PayPalCommerce\WcGateway\Notice\AuthorizeOrderActionNotice;
33
  use WooCommerce\PayPalCommerce\WcGateway\Notice\ConnectAdminNotice;
34
  use WooCommerce\PayPalCommerce\WcGateway\Notice\DccWithoutPayPalAdminNotice;
42
  use WooCommerce\PayPalCommerce\Webhooks\Status\WebhooksStatusPage;
43
 
44
  return array(
45
+ 'wcgateway.paypal-gateway' => static function ( ContainerInterface $container ): PayPalGateway {
46
  $order_processor = $container->get( 'wcgateway.order-processor' );
47
  $settings_renderer = $container->get( 'wcgateway.settings.render' );
48
  $authorized_payments = $container->get( 'wcgateway.processor.authorized-payments' );
 
49
  $settings = $container->get( 'wcgateway.settings' );
50
  $session_handler = $container->get( 'session.handler' );
51
  $refund_processor = $container->get( 'wcgateway.processor.refunds' );
53
  $transaction_url_provider = $container->get( 'wcgateway.transaction-url-provider' );
54
  $subscription_helper = $container->get( 'subscription.helper' );
55
  $page_id = $container->get( 'wcgateway.current-ppcp-settings-page-id' );
56
+ $payment_token_repository = $container->get( 'vaulting.repository.payment-token' );
57
+ $payments_endpoint = $container->get( 'api.endpoint.payments' );
58
+ $order_endpoint = $container->get( 'api.endpoint.order' );
59
  $environment = $container->get( 'onboarding.environment' );
60
+ $logger = $container->get( 'woocommerce.logger.woocommerce' );
61
  return new PayPalGateway(
62
  $settings_renderer,
63
  $order_processor,
64
  $authorized_payments,
 
65
  $settings,
66
  $session_handler,
67
  $refund_processor,
69
  $transaction_url_provider,
70
  $subscription_helper,
71
  $page_id,
72
+ $environment,
73
+ $payment_token_repository,
74
+ $logger,
75
+ $payments_endpoint,
76
+ $order_endpoint
77
  );
78
  },
79
+ 'wcgateway.credit-card-gateway' => static function ( ContainerInterface $container ): CreditCardGateway {
80
  $order_processor = $container->get( 'wcgateway.order-processor' );
81
  $settings_renderer = $container->get( 'wcgateway.settings.render' );
82
  $authorized_payments = $container->get( 'wcgateway.processor.authorized-payments' );
 
83
  $settings = $container->get( 'wcgateway.settings' );
84
  $module_url = $container->get( 'wcgateway.url' );
85
  $session_handler = $container->get( 'session.handler' );
91
  $payer_factory = $container->get( 'api.factory.payer' );
92
  $order_endpoint = $container->get( 'api.endpoint.order' );
93
  $subscription_helper = $container->get( 'subscription.helper' );
94
+ $payments_endpoint = $container->get( 'api.endpoint.payments' );
95
  $logger = $container->get( 'woocommerce.logger.woocommerce' );
96
  $environment = $container->get( 'onboarding.environment' );
97
  return new CreditCardGateway(
98
  $settings_renderer,
99
  $order_processor,
100
  $authorized_payments,
 
101
  $settings,
102
  $module_url,
103
  $session_handler,
110
  $order_endpoint,
111
  $subscription_helper,
112
  $logger,
113
+ $environment,
114
+ $payments_endpoint
115
  );
116
  },
117
+ 'wcgateway.disabler' => static function ( ContainerInterface $container ): DisableGateways {
118
  $session_handler = $container->get( 'session.handler' );
119
  $settings = $container->get( 'wcgateway.settings' );
120
+ $subscription_helper = $container->get( 'subscription.helper' );
121
+ return new DisableGateways( $session_handler, $settings, $subscription_helper );
122
  },
123
+ 'wcgateway.is-wc-payments-page' => static function ( ContainerInterface $container ): bool {
 
124
  $page = isset( $_GET['page'] ) ? sanitize_text_field( wp_unslash( $_GET['page'] ) ) : '';
125
  $tab = isset( $_GET['tab'] ) ? sanitize_text_field( wp_unslash( $_GET['tab'] ) ) : '';
126
  return 'wc-settings' === $page && 'checkout' === $tab;
127
  },
128
 
129
+ 'wcgateway.is-ppcp-settings-page' => static function ( ContainerInterface $container ): bool {
130
  if ( ! $container->get( 'wcgateway.is-wc-payments-page' ) ) {
131
  return false;
132
  }
135
  return in_array( $section, array( PayPalGateway::ID, CreditCardGateway::ID, WebhooksStatusPage::ID ), true );
136
  },
137
 
138
+ 'wcgateway.current-ppcp-settings-page-id' => static function ( ContainerInterface $container ): string {
139
  if ( ! $container->get( 'wcgateway.is-ppcp-settings-page' ) ) {
140
  return '';
141
  }
146
  return $ppcp_tab ? $ppcp_tab : $section;
147
  },
148
 
149
+ 'wcgateway.settings' => static function ( ContainerInterface $container ): Settings {
150
  return new Settings();
151
  },
152
+ 'wcgateway.notice.connect' => static function ( ContainerInterface $container ): ConnectAdminNotice {
153
  $state = $container->get( 'onboarding.state' );
154
  $settings = $container->get( 'wcgateway.settings' );
155
  return new ConnectAdminNotice( $state, $settings );
156
  },
157
+ 'wcgateway.notice.dcc-without-paypal' => static function ( ContainerInterface $container ): DccWithoutPayPalAdminNotice {
158
  $state = $container->get( 'onboarding.state' );
159
  $settings = $container->get( 'wcgateway.settings' );
160
  $is_payments_page = $container->get( 'wcgateway.is-wc-payments-page' );
162
  return new DccWithoutPayPalAdminNotice( $state, $settings, $is_payments_page, $is_ppcp_settings_page );
163
  },
164
  'wcgateway.notice.authorize-order-action' =>
165
+ static function ( ContainerInterface $container ): AuthorizeOrderActionNotice {
166
  return new AuthorizeOrderActionNotice();
167
  },
168
+ 'wcgateway.settings.sections-renderer' => static function ( ContainerInterface $container ): SectionsRenderer {
169
  return new SectionsRenderer( $container->get( 'wcgateway.current-ppcp-settings-page-id' ) );
170
  },
171
+ 'wcgateway.settings.status' => static function ( ContainerInterface $container ): SettingsStatus {
172
  $settings = $container->get( 'wcgateway.settings' );
173
  return new SettingsStatus( $settings );
174
  },
175
+ 'wcgateway.settings.render' => static function ( ContainerInterface $container ): SettingsRenderer {
176
  $settings = $container->get( 'wcgateway.settings' );
177
  $state = $container->get( 'onboarding.state' );
178
  $fields = $container->get( 'wcgateway.settings.fields' );
192
  $page_id
193
  );
194
  },
195
+ 'wcgateway.settings.listener' => static function ( ContainerInterface $container ): SettingsListener {
196
  $settings = $container->get( 'wcgateway.settings' );
197
  $fields = $container->get( 'wcgateway.settings.fields' );
198
  $webhook_registrar = $container->get( 'webhook.registrar' );
202
  $page_id = $container->get( 'wcgateway.current-ppcp-settings-page-id' );
203
  return new SettingsListener( $settings, $fields, $webhook_registrar, $cache, $state, $bearer, $page_id );
204
  },
205
+ 'wcgateway.order-processor' => static function ( ContainerInterface $container ): OrderProcessor {
206
 
207
  $session_handler = $container->get( 'session.handler' );
208
  $order_endpoint = $container->get( 'api.endpoint.order' );
223
  $environment
224
  );
225
  },
226
+ 'wcgateway.processor.refunds' => static function ( ContainerInterface $container ): RefundProcessor {
227
  $order_endpoint = $container->get( 'api.endpoint.order' );
228
  $payments_endpoint = $container->get( 'api.endpoint.payments' );
229
  $logger = $container->get( 'woocommerce.logger.woocommerce' );
230
  return new RefundProcessor( $order_endpoint, $payments_endpoint, $logger );
231
  },
232
+ 'wcgateway.processor.authorized-payments' => static function ( ContainerInterface $container ): AuthorizedPaymentsProcessor {
233
  $order_endpoint = $container->get( 'api.endpoint.order' );
234
  $payments_endpoint = $container->get( 'api.endpoint.payments' );
235
  $logger = $container->get( 'woocommerce.logger.woocommerce' );
236
+ $notice = $container->get( 'wcgateway.notice.authorize-order-action' );
237
+ return new AuthorizedPaymentsProcessor( $order_endpoint, $payments_endpoint, $logger, $notice );
238
  },
239
+ 'wcgateway.admin.render-authorize-action' => static function ( ContainerInterface $container ): RenderAuthorizeAction {
240
+ $column = $container->get( 'wcgateway.admin.orders-payment-status-column' );
241
+ return new RenderAuthorizeAction( $column );
242
  },
243
+ 'wcgateway.admin.order-payment-status' => static function ( ContainerInterface $container ): PaymentStatusOrderDetail {
244
  $column = $container->get( 'wcgateway.admin.orders-payment-status-column' );
245
  return new PaymentStatusOrderDetail( $column );
246
  },
247
+ 'wcgateway.admin.orders-payment-status-column' => static function ( ContainerInterface $container ): OrderTablePaymentStatusColumn {
248
  $settings = $container->get( 'wcgateway.settings' );
249
  return new OrderTablePaymentStatusColumn( $settings );
250
  },
251
 
252
+ 'wcgateway.settings.fields' => static function ( ContainerInterface $container ): array {
253
 
254
  $state = $container->get( 'onboarding.state' );
255
  $messages_disclaimers = $container->get( 'button.helper.messages-disclaimers' );
1969
  return $fields;
1970
  },
1971
 
1972
+ 'wcgateway.checkout.address-preset' => static function( ContainerInterface $container ): CheckoutPayPalAddressPreset {
1973
 
1974
  return new CheckoutPayPalAddressPreset(
1975
  $container->get( 'session.handler' )
1976
  );
1977
  },
1978
+ 'wcgateway.url' => static function ( ContainerInterface $container ): string {
1979
  return plugins_url(
1980
  $container->get( 'wcgateway.relative-path' ),
1981
  dirname( __FILE__, 3 ) . '/woocommerce-paypal-payments.php'
1982
  );
1983
  },
1984
+ 'wcgateway.relative-path' => static function( ContainerInterface $container ): string {
1985
  return 'modules/ppcp-wc-gateway/';
1986
  },
1987
+ 'wcgateway.absolute-path' => static function( ContainerInterface $container ): string {
1988
  return plugin_dir_path(
1989
  dirname( __FILE__, 3 ) . '/woocommerce-paypal-payments.php'
1990
  ) .
1991
  $container->get( 'wcgateway.relative-path' );
1992
  },
1993
+ 'wcgateway.endpoint.return-url' => static function ( ContainerInterface $container ) : ReturnUrlEndpoint {
1994
  $gateway = $container->get( 'wcgateway.paypal-gateway' );
1995
  $endpoint = $container->get( 'api.endpoint.order' );
1996
  $prefix = $container->get( 'api.prefix' );
2001
  );
2002
  },
2003
 
2004
+ 'wcgateway.transaction-url-sandbox' => static function ( ContainerInterface $container ): string {
2005
  return 'https://www.sandbox.paypal.com/cgi-bin/webscr?cmd=_view-a-trans&id=%s';
2006
  },
2007
 
2008
+ 'wcgateway.transaction-url-live' => static function ( ContainerInterface $container ): string {
2009
  return 'https://www.paypal.com/cgi-bin/webscr?cmd=_view-a-trans&id=%s';
2010
  },
2011
 
2012
+ 'wcgateway.transaction-url-provider' => static function ( ContainerInterface $container ): TransactionUrlProvider {
2013
  $sandbox_url_base = $container->get( 'wcgateway.transaction-url-sandbox' );
2014
  $live_url_base = $container->get( 'wcgateway.transaction-url-live' );
2015
 
2016
  return new TransactionUrlProvider( $sandbox_url_base, $live_url_base );
2017
  },
2018
 
2019
+ 'wcgateway.helper.dcc-product-status' => static function ( ContainerInterface $container ) : DCCProductStatus {
2020
 
2021
  $settings = $container->get( 'wcgateway.settings' );
2022
  $partner_endpoint = $container->get( 'api.endpoint.partners' );
2023
+ return new DCCProductStatus( $settings, $partner_endpoint );
2024
  },
2025
 
2026
+ 'button.helper.messages-disclaimers' => static function ( ContainerInterface $container ): MessagesDisclaimers {
2027
  return new MessagesDisclaimers();
2028
  },
2029
  );
modules/ppcp-wc-gateway/src/Admin/{class-ordertablepaymentstatuscolumn.php → OrderTablePaymentStatusColumn.php} RENAMED
@@ -11,6 +11,7 @@ declare(strict_types=1);
11
  namespace WooCommerce\PayPalCommerce\WcGateway\Admin;
12
 
13
  use WooCommerce\PayPalCommerce\WcGateway\Gateway\PayPalGateway;
 
14
  use WooCommerce\PayPalCommerce\WcGateway\Settings\Settings;
15
 
16
  /**
@@ -102,7 +103,7 @@ class OrderTablePaymentStatusColumn {
102
  */
103
  public function should_render_for_order( \WC_Order $order ): bool {
104
  $intent = $order->get_meta( PayPalGateway::INTENT_META_KEY );
105
- $captured = $order->get_meta( PayPalGateway::CAPTURED_META_KEY );
106
  $status = $order->get_status();
107
  $not_allowed_statuses = array( 'refunded' );
108
  return ! empty( $intent ) && strtoupper( self::INTENT ) === strtoupper( $intent ) &&
@@ -118,7 +119,7 @@ class OrderTablePaymentStatusColumn {
118
  * @return bool
119
  */
120
  public function is_captured( \WC_Order $wc_order ): bool {
121
- $captured = $wc_order->get_meta( PayPalGateway::CAPTURED_META_KEY );
122
  return wc_string_to_bool( $captured );
123
  }
124
 
11
  namespace WooCommerce\PayPalCommerce\WcGateway\Admin;
12
 
13
  use WooCommerce\PayPalCommerce\WcGateway\Gateway\PayPalGateway;
14
+ use WooCommerce\PayPalCommerce\WcGateway\Processor\AuthorizedPaymentsProcessor;
15
  use WooCommerce\PayPalCommerce\WcGateway\Settings\Settings;
16
 
17
  /**
103
  */
104
  public function should_render_for_order( \WC_Order $order ): bool {
105
  $intent = $order->get_meta( PayPalGateway::INTENT_META_KEY );
106
+ $captured = $order->get_meta( AuthorizedPaymentsProcessor::CAPTURED_META_KEY );
107
  $status = $order->get_status();
108
  $not_allowed_statuses = array( 'refunded' );
109
  return ! empty( $intent ) && strtoupper( self::INTENT ) === strtoupper( $intent ) &&
119
  * @return bool
120
  */
121
  public function is_captured( \WC_Order $wc_order ): bool {
122
+ $captured = $wc_order->get_meta( AuthorizedPaymentsProcessor::CAPTURED_META_KEY );
123
  return wc_string_to_bool( $captured );
124
  }
125
 
modules/ppcp-wc-gateway/src/Admin/{class-paymentstatusorderdetail.php → PaymentStatusOrderDetail.php} RENAMED
File without changes
modules/ppcp-wc-gateway/src/Admin/{class-renderauthorizeaction.php → RenderAuthorizeAction.php} RENAMED
@@ -10,11 +10,27 @@ declare( strict_types=1 );
10
  namespace WooCommerce\PayPalCommerce\WcGateway\Admin;
11
 
12
  use WooCommerce\PayPalCommerce\WcGateway\Gateway\PayPalGateway;
 
13
 
14
  /**
15
  * Class RenderAuthorizeAction
16
  */
17
  class RenderAuthorizeAction {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
18
 
19
  /**
20
  * Renders the action into the $order_actions array based on the WooCommerce order.
@@ -45,7 +61,10 @@ class RenderAuthorizeAction {
45
  * @return bool
46
  */
47
  private function should_render_for_order( \WC_Order $order ) : bool {
48
- $data = $order->get_meta( PayPalGateway::CAPTURED_META_KEY );
49
- return in_array( $data, array( 'true', 'false' ), true );
 
 
 
50
  }
51
  }
10
  namespace WooCommerce\PayPalCommerce\WcGateway\Admin;
11
 
12
  use WooCommerce\PayPalCommerce\WcGateway\Gateway\PayPalGateway;
13
+ use WooCommerce\PayPalCommerce\WcGateway\Processor\AuthorizedPaymentsProcessor;
14
 
15
  /**
16
  * Class RenderAuthorizeAction
17
  */
18
  class RenderAuthorizeAction {
19
+ /**
20
+ * The capture info column.
21
+ *
22
+ * @var OrderTablePaymentStatusColumn
23
+ */
24
+ private $column;
25
+
26
+ /**
27
+ * PaymentStatusOrderDetail constructor.
28
+ *
29
+ * @param OrderTablePaymentStatusColumn $column The capture info column.
30
+ */
31
+ public function __construct( OrderTablePaymentStatusColumn $column ) {
32
+ $this->column = $column;
33
+ }
34
 
35
  /**
36
  * Renders the action into the $order_actions array based on the WooCommerce order.
61
  * @return bool
62
  */
63
  private function should_render_for_order( \WC_Order $order ) : bool {
64
+ $status = $order->get_status();
65
+ $not_allowed_statuses = array( 'refunded', 'cancelled', 'failed' );
66
+ return $this->column->should_render_for_order( $order ) &&
67
+ ! $this->column->is_captured( $order ) &&
68
+ ! in_array( $status, $not_allowed_statuses, true );
69
  }
70
  }
modules/ppcp-wc-gateway/src/Assets/{class-settingspageassets.php → SettingsPageAssets.php} RENAMED
File without changes
modules/ppcp-wc-gateway/src/Checkout/{class-checkoutpaypaladdresspreset.php → CheckoutPayPalAddressPreset.php} RENAMED
@@ -114,7 +114,6 @@ class CheckoutPayPalAddressPreset {
114
  array_key_exists( $field_id, $payer_phone_map )
115
  && $payer
116
  && $payer->phone()
117
- && $payer->phone()->phone()
118
  ) {
119
  return $payer->phone()->phone()->{$payer_phone_map[ $field_id ]}() ? $payer->phone()->phone()->{$payer_phone_map[ $field_id ]}() : null;
120
  }
114
  array_key_exists( $field_id, $payer_phone_map )
115
  && $payer
116
  && $payer->phone()
 
117
  ) {
118
  return $payer->phone()->phone()->{$payer_phone_map[ $field_id ]}() ? $payer->phone()->phone()->{$payer_phone_map[ $field_id ]}() : null;
119
  }
modules/ppcp-wc-gateway/src/Checkout/{class-disablegateways.php → DisableGateways.php} RENAMED
@@ -10,6 +10,7 @@ declare(strict_types=1);
10
  namespace WooCommerce\PayPalCommerce\WcGateway\Checkout;
11
 
12
  use WooCommerce\PayPalCommerce\Session\SessionHandler;
 
13
  use WooCommerce\PayPalCommerce\WcGateway\Gateway\CreditCardGateway;
14
  use WooCommerce\PayPalCommerce\WcGateway\Gateway\PayPalGateway;
15
  use Psr\Container\ContainerInterface;
@@ -19,7 +20,6 @@ use Psr\Container\ContainerInterface;
19
  */
20
  class DisableGateways {
21
 
22
-
23
  /**
24
  * The Session Handler.
25
  *
@@ -34,19 +34,29 @@ class DisableGateways {
34
  */
35
  private $settings;
36
 
 
 
 
 
 
 
 
37
  /**
38
  * DisableGateways constructor.
39
  *
40
  * @param SessionHandler $session_handler The Session Handler.
41
  * @param ContainerInterface $settings The Settings.
 
42
  */
43
  public function __construct(
44
  SessionHandler $session_handler,
45
- ContainerInterface $settings
 
46
  ) {
47
 
48
- $this->session_handler = $session_handler;
49
- $this->settings = $settings;
 
50
  }
51
 
52
  /**
@@ -100,6 +110,10 @@ class DisableGateways {
100
  return true;
101
  }
102
 
 
 
 
 
103
  return false;
104
  }
105
 
10
  namespace WooCommerce\PayPalCommerce\WcGateway\Checkout;
11
 
12
  use WooCommerce\PayPalCommerce\Session\SessionHandler;
13
+ use WooCommerce\PayPalCommerce\Subscription\Helper\SubscriptionHelper;
14
  use WooCommerce\PayPalCommerce\WcGateway\Gateway\CreditCardGateway;
15
  use WooCommerce\PayPalCommerce\WcGateway\Gateway\PayPalGateway;
16
  use Psr\Container\ContainerInterface;
20
  */
21
  class DisableGateways {
22
 
 
23
  /**
24
  * The Session Handler.
25
  *
34
  */
35
  private $settings;
36
 
37
+ /**
38
+ * The subscription helper
39
+ *
40
+ * @var SubscriptionHelper
41
+ */
42
+ private $subscription_helper;
43
+
44
  /**
45
  * DisableGateways constructor.
46
  *
47
  * @param SessionHandler $session_handler The Session Handler.
48
  * @param ContainerInterface $settings The Settings.
49
+ * @param SubscriptionHelper $subscription_helper The subscription helper.
50
  */
51
  public function __construct(
52
  SessionHandler $session_handler,
53
+ ContainerInterface $settings,
54
+ SubscriptionHelper $subscription_helper
55
  ) {
56
 
57
+ $this->session_handler = $session_handler;
58
+ $this->settings = $settings;
59
+ $this->subscription_helper = $subscription_helper;
60
  }
61
 
62
  /**
110
  return true;
111
  }
112
 
113
+ if ( $this->subscription_helper->cart_contains_subscription() && ! is_user_logged_in() ) {
114
+ return true;
115
+ }
116
+
117
  return false;
118
  }
119
 
modules/ppcp-wc-gateway/src/Endpoint/{class-returnurlendpoint.php → ReturnUrlEndpoint.php} RENAMED
@@ -61,9 +61,6 @@ class ReturnUrlEndpoint {
61
  $token = sanitize_text_field( wp_unslash( $_GET['token'] ) );
62
  // phpcs:enable WordPress.Security.NonceVerification.Recommended
63
  $order = $this->order_endpoint->order( $token );
64
- if ( ! $order ) {
65
- exit();
66
- }
67
 
68
  $wc_order_id = $this->sanitize_custom_id( $order->purchase_units()[0]->custom_id() );
69
  if ( ! $wc_order_id ) {
61
  $token = sanitize_text_field( wp_unslash( $_GET['token'] ) );
62
  // phpcs:enable WordPress.Security.NonceVerification.Recommended
63
  $order = $this->order_endpoint->order( $token );
 
 
 
64
 
65
  $wc_order_id = $this->sanitize_custom_id( $order->purchase_units()[0]->custom_id() );
66
  if ( ! $wc_order_id ) {
modules/ppcp-wc-gateway/src/Exception/{class-notfoundexception.php → NotFoundException.php} RENAMED
File without changes
modules/ppcp-wc-gateway/src/Gateway/{class-creditcardgateway.php → CreditCardGateway.php} RENAMED
@@ -11,6 +11,7 @@ namespace WooCommerce\PayPalCommerce\WcGateway\Gateway;
11
 
12
  use Psr\Log\LoggerInterface;
13
  use WooCommerce\PayPalCommerce\ApiClient\Endpoint\OrderEndpoint;
 
14
  use WooCommerce\PayPalCommerce\ApiClient\Factory\PayerFactory;
15
  use WooCommerce\PayPalCommerce\ApiClient\Factory\PurchaseUnitFactory;
16
  use WooCommerce\PayPalCommerce\Onboarding\Environment;
@@ -18,7 +19,6 @@ use WooCommerce\PayPalCommerce\Onboarding\State;
18
  use WooCommerce\PayPalCommerce\Session\SessionHandler;
19
  use WooCommerce\PayPalCommerce\Subscription\Helper\SubscriptionHelper;
20
  use WooCommerce\PayPalCommerce\Vaulting\PaymentTokenRepository;
21
- use WooCommerce\PayPalCommerce\WcGateway\Notice\AuthorizeOrderActionNotice;
22
  use WooCommerce\PayPalCommerce\WcGateway\Processor\AuthorizedPaymentsProcessor;
23
  use WooCommerce\PayPalCommerce\WcGateway\Processor\OrderProcessor;
24
  use WooCommerce\PayPalCommerce\WcGateway\Processor\RefundProcessor;
@@ -35,25 +35,32 @@ class CreditCardGateway extends \WC_Payment_Gateway_CC {
35
  const ID = 'ppcp-credit-card-gateway';
36
 
37
  /**
38
- * Service to get transaction url for an order.
39
  *
40
- * @var TransactionUrlProvider
41
  */
42
- protected $transaction_url_provider;
43
 
44
  /**
45
- * The subscription helper.
46
  *
47
- * @var SubscriptionHelper
48
  */
49
- protected $subscription_helper;
50
 
51
  /**
52
- * The logger.
53
  *
54
- * @var LoggerInterface
55
  */
56
- protected $logger;
 
 
 
 
 
 
 
57
 
58
  /**
59
  * The URL to the module.
@@ -62,6 +69,13 @@ class CreditCardGateway extends \WC_Payment_Gateway_CC {
62
  */
63
  private $module_url;
64
 
 
 
 
 
 
 
 
65
  /**
66
  * The refund processor.
67
  *
@@ -69,6 +83,20 @@ class CreditCardGateway extends \WC_Payment_Gateway_CC {
69
  */
70
  private $refund_processor;
71
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
72
  /**
73
  * The payment token repository.
74
  *
@@ -97,6 +125,20 @@ class CreditCardGateway extends \WC_Payment_Gateway_CC {
97
  */
98
  private $order_endpoint;
99
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
100
  /**
101
  * The environment.
102
  *
@@ -104,13 +146,19 @@ class CreditCardGateway extends \WC_Payment_Gateway_CC {
104
  */
105
  protected $environment;
106
 
 
 
 
 
 
 
 
107
  /**
108
  * CreditCardGateway constructor.
109
  *
110
  * @param SettingsRenderer $settings_renderer The Settings Renderer.
111
  * @param OrderProcessor $order_processor The Order processor.
112
  * @param AuthorizedPaymentsProcessor $authorized_payments_processor The Authorized Payments processor.
113
- * @param AuthorizeOrderActionNotice $notice The Notices.
114
  * @param ContainerInterface $config The settings.
115
  * @param string $module_url The URL to the module.
116
  * @param SessionHandler $session_handler The Session Handler.
@@ -124,12 +172,12 @@ class CreditCardGateway extends \WC_Payment_Gateway_CC {
124
  * @param SubscriptionHelper $subscription_helper The subscription helper.
125
  * @param LoggerInterface $logger The logger.
126
  * @param Environment $environment The environment.
 
127
  */
128
  public function __construct(
129
  SettingsRenderer $settings_renderer,
130
  OrderProcessor $order_processor,
131
  AuthorizedPaymentsProcessor $authorized_payments_processor,
132
- AuthorizeOrderActionNotice $notice,
133
  ContainerInterface $config,
134
  string $module_url,
135
  SessionHandler $session_handler,
@@ -142,18 +190,18 @@ class CreditCardGateway extends \WC_Payment_Gateway_CC {
142
  OrderEndpoint $order_endpoint,
143
  SubscriptionHelper $subscription_helper,
144
  LoggerInterface $logger,
145
- Environment $environment
 
146
  ) {
147
 
148
- $this->id = self::ID;
149
- $this->order_processor = $order_processor;
150
- $this->authorized_payments = $authorized_payments_processor;
151
- $this->notice = $notice;
152
- $this->settings_renderer = $settings_renderer;
153
- $this->config = $config;
154
- $this->session_handler = $session_handler;
155
- $this->refund_processor = $refund_processor;
156
- $this->environment = $environment;
157
 
158
  if ( $state->current_state() === State::STATE_ONBOARDED ) {
159
  $this->supports = array( 'refunds' );
@@ -212,6 +260,8 @@ class CreditCardGateway extends \WC_Payment_Gateway_CC {
212
  $this->transaction_url_provider = $transaction_url_provider;
213
  $this->subscription_helper = $subscription_helper;
214
  $this->logger = $logger;
 
 
215
  }
216
 
217
  /**
11
 
12
  use Psr\Log\LoggerInterface;
13
  use WooCommerce\PayPalCommerce\ApiClient\Endpoint\OrderEndpoint;
14
+ use WooCommerce\PayPalCommerce\ApiClient\Endpoint\PaymentsEndpoint;
15
  use WooCommerce\PayPalCommerce\ApiClient\Factory\PayerFactory;
16
  use WooCommerce\PayPalCommerce\ApiClient\Factory\PurchaseUnitFactory;
17
  use WooCommerce\PayPalCommerce\Onboarding\Environment;
19
  use WooCommerce\PayPalCommerce\Session\SessionHandler;
20
  use WooCommerce\PayPalCommerce\Subscription\Helper\SubscriptionHelper;
21
  use WooCommerce\PayPalCommerce\Vaulting\PaymentTokenRepository;
 
22
  use WooCommerce\PayPalCommerce\WcGateway\Processor\AuthorizedPaymentsProcessor;
23
  use WooCommerce\PayPalCommerce\WcGateway\Processor\OrderProcessor;
24
  use WooCommerce\PayPalCommerce\WcGateway\Processor\RefundProcessor;
35
  const ID = 'ppcp-credit-card-gateway';
36
 
37
  /**
38
+ * The Settings Renderer.
39
  *
40
+ * @var SettingsRenderer
41
  */
42
+ protected $settings_renderer;
43
 
44
  /**
45
+ * The processor for orders.
46
  *
47
+ * @var OrderProcessor
48
  */
49
+ protected $order_processor;
50
 
51
  /**
52
+ * The processor for authorized payments.
53
  *
54
+ * @var AuthorizedPaymentsProcessor
55
  */
56
+ protected $authorized_payments_processor;
57
+
58
+ /**
59
+ * The settings.
60
+ *
61
+ * @var ContainerInterface
62
+ */
63
+ protected $config;
64
 
65
  /**
66
  * The URL to the module.
69
  */
70
  private $module_url;
71
 
72
+ /**
73
+ * The Session Handler.
74
+ *
75
+ * @var SessionHandler
76
+ */
77
+ protected $session_handler;
78
+
79
  /**
80
  * The refund processor.
81
  *
83
  */
84
  private $refund_processor;
85
 
86
+ /**
87
+ * The state.
88
+ *
89
+ * @var State
90
+ */
91
+ protected $state;
92
+
93
+ /**
94
+ * Service to get transaction url for an order.
95
+ *
96
+ * @var TransactionUrlProvider
97
+ */
98
+ protected $transaction_url_provider;
99
+
100
  /**
101
  * The payment token repository.
102
  *
125
  */
126
  private $order_endpoint;
127
 
128
+ /**
129
+ * The subscription helper.
130
+ *
131
+ * @var SubscriptionHelper
132
+ */
133
+ protected $subscription_helper;
134
+
135
+ /**
136
+ * The logger.
137
+ *
138
+ * @var LoggerInterface
139
+ */
140
+ protected $logger;
141
+
142
  /**
143
  * The environment.
144
  *
146
  */
147
  protected $environment;
148
 
149
+ /**
150
+ * The payments endpoint
151
+ *
152
+ * @var PaymentsEndpoint
153
+ */
154
+ protected $payments_endpoint;
155
+
156
  /**
157
  * CreditCardGateway constructor.
158
  *
159
  * @param SettingsRenderer $settings_renderer The Settings Renderer.
160
  * @param OrderProcessor $order_processor The Order processor.
161
  * @param AuthorizedPaymentsProcessor $authorized_payments_processor The Authorized Payments processor.
 
162
  * @param ContainerInterface $config The settings.
163
  * @param string $module_url The URL to the module.
164
  * @param SessionHandler $session_handler The Session Handler.
172
  * @param SubscriptionHelper $subscription_helper The subscription helper.
173
  * @param LoggerInterface $logger The logger.
174
  * @param Environment $environment The environment.
175
+ * @param PaymentsEndpoint $payments_endpoint The payments endpoint.
176
  */
177
  public function __construct(
178
  SettingsRenderer $settings_renderer,
179
  OrderProcessor $order_processor,
180
  AuthorizedPaymentsProcessor $authorized_payments_processor,
 
181
  ContainerInterface $config,
182
  string $module_url,
183
  SessionHandler $session_handler,
190
  OrderEndpoint $order_endpoint,
191
  SubscriptionHelper $subscription_helper,
192
  LoggerInterface $logger,
193
+ Environment $environment,
194
+ PaymentsEndpoint $payments_endpoint
195
  ) {
196
 
197
+ $this->id = self::ID;
198
+ $this->order_processor = $order_processor;
199
+ $this->authorized_payments_processor = $authorized_payments_processor;
200
+ $this->settings_renderer = $settings_renderer;
201
+ $this->config = $config;
202
+ $this->session_handler = $session_handler;
203
+ $this->refund_processor = $refund_processor;
204
+ $this->environment = $environment;
 
205
 
206
  if ( $state->current_state() === State::STATE_ONBOARDED ) {
207
  $this->supports = array( 'refunds' );
260
  $this->transaction_url_provider = $transaction_url_provider;
261
  $this->subscription_helper = $subscription_helper;
262
  $this->logger = $logger;
263
+ $this->payments_endpoint = $payments_endpoint;
264
+ $this->state = $state;
265
  }
266
 
267
  /**
modules/ppcp-wc-gateway/src/Gateway/{class-paypalgateway.php → PayPalGateway.php} RENAMED
@@ -9,16 +9,18 @@ declare(strict_types=1);
9
 
10
  namespace WooCommerce\PayPalCommerce\WcGateway\Gateway;
11
 
 
 
 
12
  use WooCommerce\PayPalCommerce\ApiClient\Entity\CaptureStatus;
13
  use WooCommerce\PayPalCommerce\Onboarding\Environment;
14
  use WooCommerce\PayPalCommerce\Onboarding\State;
15
  use WooCommerce\PayPalCommerce\Session\SessionHandler;
16
  use WooCommerce\PayPalCommerce\Subscription\Helper\SubscriptionHelper;
17
- use WooCommerce\PayPalCommerce\WcGateway\Notice\AuthorizeOrderActionNotice;
18
  use WooCommerce\PayPalCommerce\WcGateway\Processor\AuthorizedPaymentsProcessor;
19
  use WooCommerce\PayPalCommerce\WcGateway\Processor\OrderProcessor;
20
  use WooCommerce\PayPalCommerce\WcGateway\Processor\RefundProcessor;
21
- use WooCommerce\PayPalCommerce\WcGateway\Settings\SectionsRenderer;
22
  use WooCommerce\PayPalCommerce\WcGateway\Settings\SettingsRenderer;
23
  use Psr\Container\ContainerInterface;
24
  use WooCommerce\PayPalCommerce\Webhooks\Status\WebhooksStatusPage;
@@ -31,7 +33,6 @@ class PayPalGateway extends \WC_Payment_Gateway {
31
  use ProcessPaymentTrait;
32
 
33
  const ID = 'ppcp-gateway';
34
- const CAPTURED_META_KEY = '_ppcp_paypal_captured';
35
  const INTENT_META_KEY = '_ppcp_paypal_intent';
36
  const ORDER_ID_META_KEY = '_ppcp_paypal_order_id';
37
  const ORDER_PAYMENT_MODE_META_KEY = '_ppcp_paypal_payment_mode';
@@ -44,25 +45,18 @@ class PayPalGateway extends \WC_Payment_Gateway {
44
  protected $settings_renderer;
45
 
46
  /**
47
- * The processor for authorized payments.
48
- *
49
- * @var AuthorizedPaymentsProcessor
50
- */
51
- protected $authorized_payments;
52
-
53
- /**
54
- * The Authorized Order Action Notice.
55
  *
56
- * @var AuthorizeOrderActionNotice
57
  */
58
- protected $notice;
59
 
60
  /**
61
- * The processor for orders.
62
  *
63
- * @var OrderProcessor
64
  */
65
- protected $order_processor;
66
 
67
  /**
68
  * The settings.
@@ -78,6 +72,20 @@ class PayPalGateway extends \WC_Payment_Gateway {
78
  */
79
  protected $session_handler;
80
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
81
  /**
82
  * Service able to provide transaction url for an order.
83
  *
@@ -93,11 +101,25 @@ class PayPalGateway extends \WC_Payment_Gateway {
93
  protected $subscription_helper;
94
 
95
  /**
96
- * The Refund Processor.
97
  *
98
- * @var RefundProcessor
99
  */
100
- private $refund_processor;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
101
 
102
  /**
103
  * Whether the plugin is in onboarded state.
@@ -120,13 +142,19 @@ class PayPalGateway extends \WC_Payment_Gateway {
120
  */
121
  protected $environment;
122
 
 
 
 
 
 
 
 
123
  /**
124
  * PayPalGateway constructor.
125
  *
126
  * @param SettingsRenderer $settings_renderer The Settings Renderer.
127
  * @param OrderProcessor $order_processor The Order Processor.
128
  * @param AuthorizedPaymentsProcessor $authorized_payments_processor The Authorized Payments Processor.
129
- * @param AuthorizeOrderActionNotice $notice The Order Action Notice object.
130
  * @param ContainerInterface $config The settings.
131
  * @param SessionHandler $session_handler The Session Handler.
132
  * @param RefundProcessor $refund_processor The Refund Processor.
@@ -135,12 +163,15 @@ class PayPalGateway extends \WC_Payment_Gateway {
135
  * @param SubscriptionHelper $subscription_helper The subscription helper.
136
  * @param string $page_id ID of the current PPCP gateway settings page, or empty if it is not such page.
137
  * @param Environment $environment The environment.
 
 
 
 
138
  */
139
  public function __construct(
140
  SettingsRenderer $settings_renderer,
141
  OrderProcessor $order_processor,
142
  AuthorizedPaymentsProcessor $authorized_payments_processor,
143
- AuthorizeOrderActionNotice $notice,
144
  ContainerInterface $config,
145
  SessionHandler $session_handler,
146
  RefundProcessor $refund_processor,
@@ -148,21 +179,35 @@ class PayPalGateway extends \WC_Payment_Gateway {
148
  TransactionUrlProvider $transaction_url_provider,
149
  SubscriptionHelper $subscription_helper,
150
  string $page_id,
151
- Environment $environment
 
 
 
 
152
  ) {
153
 
154
- $this->id = self::ID;
155
- $this->order_processor = $order_processor;
156
- $this->authorized_payments = $authorized_payments_processor;
157
- $this->notice = $notice;
158
- $this->settings_renderer = $settings_renderer;
159
- $this->config = $config;
160
- $this->session_handler = $session_handler;
161
- $this->refund_processor = $refund_processor;
162
- $this->transaction_url_provider = $transaction_url_provider;
163
- $this->page_id = $page_id;
164
- $this->environment = $environment;
165
- $this->onboarded = $state->current_state() === State::STATE_ONBOARDED;
 
 
 
 
 
 
 
 
 
 
166
 
167
  if ( $this->onboarded ) {
168
  $this->supports = array( 'refunds' );
@@ -206,7 +251,12 @@ class PayPalGateway extends \WC_Payment_Gateway {
206
  'process_admin_options',
207
  )
208
  );
209
- $this->subscription_helper = $subscription_helper;
 
 
 
 
 
210
  }
211
 
212
  /**
@@ -243,73 +293,6 @@ class PayPalGateway extends \WC_Payment_Gateway {
243
  }
244
  }
245
 
246
- /**
247
- * Captures an authorized payment for an WooCommerce order.
248
- *
249
- * @param \WC_Order $wc_order The WooCommerce order.
250
- *
251
- * @return bool
252
- */
253
- public function capture_authorized_payment( \WC_Order $wc_order ): bool {
254
- $result_status = $this->authorized_payments->process( $wc_order );
255
- $this->render_authorization_message_for_status( $result_status );
256
-
257
- if ( AuthorizedPaymentsProcessor::ALREADY_CAPTURED === $result_status ) {
258
- if ( $wc_order->get_status() === 'on-hold' ) {
259
- $wc_order->add_order_note(
260
- __( 'Payment successfully captured.', 'woocommerce-paypal-payments' )
261
- );
262
- }
263
-
264
- $wc_order->update_meta_data( self::CAPTURED_META_KEY, 'true' );
265
- $wc_order->save();
266
- $wc_order->payment_complete();
267
- return true;
268
- }
269
-
270
- $captures = $this->authorized_payments->captures();
271
- if ( empty( $captures ) ) {
272
- return false;
273
- }
274
-
275
- $capture = end( $captures );
276
-
277
- $this->handle_capture_status( $capture, $wc_order );
278
-
279
- if ( AuthorizedPaymentsProcessor::SUCCESSFUL === $result_status ) {
280
- if ( $capture->status()->is( CaptureStatus::COMPLETED ) ) {
281
- $wc_order->add_order_note(
282
- __( 'Payment successfully captured.', 'woocommerce-paypal-payments' )
283
- );
284
- }
285
- $wc_order->update_meta_data( self::CAPTURED_META_KEY, 'true' );
286
- $wc_order->save();
287
- return true;
288
- }
289
-
290
- return false;
291
- }
292
-
293
- /**
294
- * Displays the notice for a status.
295
- *
296
- * @param string $status The status.
297
- */
298
- private function render_authorization_message_for_status( string $status ) {
299
-
300
- $message_mapping = array(
301
- AuthorizedPaymentsProcessor::SUCCESSFUL => AuthorizeOrderActionNotice::SUCCESS,
302
- AuthorizedPaymentsProcessor::ALREADY_CAPTURED => AuthorizeOrderActionNotice::ALREADY_CAPTURED,
303
- AuthorizedPaymentsProcessor::INACCESSIBLE => AuthorizeOrderActionNotice::NO_INFO,
304
- AuthorizedPaymentsProcessor::NOT_FOUND => AuthorizeOrderActionNotice::NOT_FOUND,
305
- AuthorizedPaymentsProcessor::BAD_AUTHORIZATION => AuthorizeOrderActionNotice::BAD_AUTHORIZATION,
306
- );
307
- $display_message = ( isset( $message_mapping[ $status ] ) ) ?
308
- $message_mapping[ $status ]
309
- : AuthorizeOrderActionNotice::FAILED;
310
- $this->notice->display_message( $display_message );
311
- }
312
-
313
  /**
314
  * Renders the settings.
315
  *
9
 
10
  namespace WooCommerce\PayPalCommerce\WcGateway\Gateway;
11
 
12
+ use Psr\Log\LoggerInterface;
13
+ use WooCommerce\PayPalCommerce\ApiClient\Endpoint\OrderEndpoint;
14
+ use WooCommerce\PayPalCommerce\ApiClient\Endpoint\PaymentsEndpoint;
15
  use WooCommerce\PayPalCommerce\ApiClient\Entity\CaptureStatus;
16
  use WooCommerce\PayPalCommerce\Onboarding\Environment;
17
  use WooCommerce\PayPalCommerce\Onboarding\State;
18
  use WooCommerce\PayPalCommerce\Session\SessionHandler;
19
  use WooCommerce\PayPalCommerce\Subscription\Helper\SubscriptionHelper;
20
+ use WooCommerce\PayPalCommerce\Vaulting\PaymentTokenRepository;
21
  use WooCommerce\PayPalCommerce\WcGateway\Processor\AuthorizedPaymentsProcessor;
22
  use WooCommerce\PayPalCommerce\WcGateway\Processor\OrderProcessor;
23
  use WooCommerce\PayPalCommerce\WcGateway\Processor\RefundProcessor;
 
24
  use WooCommerce\PayPalCommerce\WcGateway\Settings\SettingsRenderer;
25
  use Psr\Container\ContainerInterface;
26
  use WooCommerce\PayPalCommerce\Webhooks\Status\WebhooksStatusPage;
33
  use ProcessPaymentTrait;
34
 
35
  const ID = 'ppcp-gateway';
 
36
  const INTENT_META_KEY = '_ppcp_paypal_intent';
37
  const ORDER_ID_META_KEY = '_ppcp_paypal_order_id';
38
  const ORDER_PAYMENT_MODE_META_KEY = '_ppcp_paypal_payment_mode';
45
  protected $settings_renderer;
46
 
47
  /**
48
+ * The processor for orders.
 
 
 
 
 
 
 
49
  *
50
+ * @var OrderProcessor
51
  */
52
+ protected $order_processor;
53
 
54
  /**
55
+ * The processor for authorized payments.
56
  *
57
+ * @var AuthorizedPaymentsProcessor
58
  */
59
+ protected $authorized_payments_processor;
60
 
61
  /**
62
  * The settings.
72
  */
73
  protected $session_handler;
74
 
75
+ /**
76
+ * The Refund Processor.
77
+ *
78
+ * @var RefundProcessor
79
+ */
80
+ private $refund_processor;
81
+
82
+ /**
83
+ * The state.
84
+ *
85
+ * @var State
86
+ */
87
+ protected $state;
88
+
89
  /**
90
  * Service able to provide transaction url for an order.
91
  *
101
  protected $subscription_helper;
102
 
103
  /**
104
+ * The payment token repository.
105
  *
106
+ * @var PaymentTokenRepository
107
  */
108
+ protected $payment_token_repository;
109
+
110
+ /**
111
+ * The payments endpoint
112
+ *
113
+ * @var PaymentsEndpoint
114
+ */
115
+ protected $payments_endpoint;
116
+
117
+ /**
118
+ * The order endpoint.
119
+ *
120
+ * @var OrderEndpoint
121
+ */
122
+ protected $order_endpoint;
123
 
124
  /**
125
  * Whether the plugin is in onboarded state.
142
  */
143
  protected $environment;
144
 
145
+ /**
146
+ * The logger.
147
+ *
148
+ * @var LoggerInterface
149
+ */
150
+ private $logger;
151
+
152
  /**
153
  * PayPalGateway constructor.
154
  *
155
  * @param SettingsRenderer $settings_renderer The Settings Renderer.
156
  * @param OrderProcessor $order_processor The Order Processor.
157
  * @param AuthorizedPaymentsProcessor $authorized_payments_processor The Authorized Payments Processor.
 
158
  * @param ContainerInterface $config The settings.
159
  * @param SessionHandler $session_handler The Session Handler.
160
  * @param RefundProcessor $refund_processor The Refund Processor.
163
  * @param SubscriptionHelper $subscription_helper The subscription helper.
164
  * @param string $page_id ID of the current PPCP gateway settings page, or empty if it is not such page.
165
  * @param Environment $environment The environment.
166
+ * @param PaymentTokenRepository $payment_token_repository The payment token repository.
167
+ * @param LoggerInterface $logger The logger.
168
+ * @param PaymentsEndpoint $payments_endpoint The payments endpoint.
169
+ * @param OrderEndpoint $order_endpoint The order endpoint.
170
  */
171
  public function __construct(
172
  SettingsRenderer $settings_renderer,
173
  OrderProcessor $order_processor,
174
  AuthorizedPaymentsProcessor $authorized_payments_processor,
 
175
  ContainerInterface $config,
176
  SessionHandler $session_handler,
177
  RefundProcessor $refund_processor,
179
  TransactionUrlProvider $transaction_url_provider,
180
  SubscriptionHelper $subscription_helper,
181
  string $page_id,
182
+ Environment $environment,
183
+ PaymentTokenRepository $payment_token_repository,
184
+ LoggerInterface $logger,
185
+ PaymentsEndpoint $payments_endpoint,
186
+ OrderEndpoint $order_endpoint
187
  ) {
188
 
189
+ $this->id = self::ID;
190
+ $this->order_processor = $order_processor;
191
+ $this->authorized_payments_processor = $authorized_payments_processor;
192
+ $this->settings_renderer = $settings_renderer;
193
+ $this->config = $config;
194
+ $this->session_handler = $session_handler;
195
+ $this->refund_processor = $refund_processor;
196
+ $this->transaction_url_provider = $transaction_url_provider;
197
+ $this->page_id = $page_id;
198
+ $this->environment = $environment;
199
+ $this->onboarded = $state->current_state() === State::STATE_ONBOARDED;
200
+ $this->id = self::ID;
201
+ $this->order_processor = $order_processor;
202
+ $this->authorized_payments = $authorized_payments_processor;
203
+ $this->settings_renderer = $settings_renderer;
204
+ $this->config = $config;
205
+ $this->session_handler = $session_handler;
206
+ $this->refund_processor = $refund_processor;
207
+ $this->transaction_url_provider = $transaction_url_provider;
208
+ $this->page_id = $page_id;
209
+ $this->environment = $environment;
210
+ $this->logger = $logger;
211
 
212
  if ( $this->onboarded ) {
213
  $this->supports = array( 'refunds' );
251
  'process_admin_options',
252
  )
253
  );
254
+ $this->subscription_helper = $subscription_helper;
255
+ $this->payment_token_repository = $payment_token_repository;
256
+ $this->logger = $logger;
257
+ $this->payments_endpoint = $payments_endpoint;
258
+ $this->order_endpoint = $order_endpoint;
259
+ $this->state = $state;
260
  }
261
 
262
  /**
293
  }
294
  }
295
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
296
  /**
297
  * Renders the settings.
298
  *
modules/ppcp-wc-gateway/src/Gateway/{class-processpaymenttrait.php → ProcessPaymentTrait.php} RENAMED
@@ -10,19 +10,23 @@ declare( strict_types=1 );
10
  namespace WooCommerce\PayPalCommerce\WcGateway\Gateway;
11
 
12
  use Exception;
 
 
13
  use WooCommerce\PayPalCommerce\ApiClient\Entity\OrderStatus;
14
  use WooCommerce\PayPalCommerce\ApiClient\Exception\PayPalApiException;
15
  use WooCommerce\PayPalCommerce\ApiClient\Exception\RuntimeException;
16
  use WooCommerce\PayPalCommerce\Onboarding\Environment;
 
17
  use WooCommerce\PayPalCommerce\WcGateway\Processor\OrderMetaTrait;
18
  use WooCommerce\PayPalCommerce\WcGateway\Processor\PaymentsStatusHandlingTrait;
 
19
 
20
  /**
21
  * Trait ProcessPaymentTrait
22
  */
23
  trait ProcessPaymentTrait {
24
 
25
- use OrderMetaTrait, PaymentsStatusHandlingTrait;
26
 
27
  /**
28
  * Process a payment for an WooCommerce order.
@@ -30,6 +34,8 @@ trait ProcessPaymentTrait {
30
  * @param int $order_id The WooCommerce order id.
31
  *
32
  * @return array
 
 
33
  */
34
  public function process_payment( $order_id ) {
35
 
@@ -99,11 +105,20 @@ trait ProcessPaymentTrait {
99
  if ( $order->intent() === 'AUTHORIZE' ) {
100
  $order = $this->order_endpoint->authorize( $order );
101
 
102
- $wc_order->update_meta_data( PayPalGateway::CAPTURED_META_KEY, 'false' );
 
 
 
 
 
103
  }
104
 
105
  $this->handle_new_order_status( $order, $wc_order );
106
 
 
 
 
 
107
  $this->session_handler->destroy_session_data();
108
  return array(
109
  'result' => 'success',
@@ -156,7 +171,101 @@ trait ProcessPaymentTrait {
156
 
157
  try {
158
  if ( $this->order_processor->process( $wc_order ) ) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
159
  $this->session_handler->destroy_session_data();
 
160
  return array(
161
  'result' => 'success',
162
  'redirect' => $this->get_return_url( $wc_order ),
10
  namespace WooCommerce\PayPalCommerce\WcGateway\Gateway;
11
 
12
  use Exception;
13
+ use WooCommerce\PayPalCommerce\ApiClient\Entity\Authorization;
14
+ use WooCommerce\PayPalCommerce\ApiClient\Entity\AuthorizationStatus;
15
  use WooCommerce\PayPalCommerce\ApiClient\Entity\OrderStatus;
16
  use WooCommerce\PayPalCommerce\ApiClient\Exception\PayPalApiException;
17
  use WooCommerce\PayPalCommerce\ApiClient\Exception\RuntimeException;
18
  use WooCommerce\PayPalCommerce\Onboarding\Environment;
19
+ use WooCommerce\PayPalCommerce\WcGateway\Processor\AuthorizedPaymentsProcessor;
20
  use WooCommerce\PayPalCommerce\WcGateway\Processor\OrderMetaTrait;
21
  use WooCommerce\PayPalCommerce\WcGateway\Processor\PaymentsStatusHandlingTrait;
22
+ use WooCommerce\PayPalCommerce\WcGateway\Processor\TransactionIdHandlingTrait;
23
 
24
  /**
25
  * Trait ProcessPaymentTrait
26
  */
27
  trait ProcessPaymentTrait {
28
 
29
+ use OrderMetaTrait, PaymentsStatusHandlingTrait, TransactionIdHandlingTrait;
30
 
31
  /**
32
  * Process a payment for an WooCommerce order.
34
  * @param int $order_id The WooCommerce order id.
35
  *
36
  * @return array
37
+ *
38
+ * @throws RuntimeException When processing payment fails.
39
  */
40
  public function process_payment( $order_id ) {
41
 
105
  if ( $order->intent() === 'AUTHORIZE' ) {
106
  $order = $this->order_endpoint->authorize( $order );
107
 
108
+ $wc_order->update_meta_data( AuthorizedPaymentsProcessor::CAPTURED_META_KEY, 'false' );
109
+ }
110
+
111
+ $transaction_id = $this->get_paypal_order_transaction_id( $order );
112
+ if ( $transaction_id ) {
113
+ $this->update_transaction_id( $transaction_id, $wc_order );
114
  }
115
 
116
  $this->handle_new_order_status( $order, $wc_order );
117
 
118
+ if ( $this->config->has( 'intent' ) && strtoupper( (string) $this->config->get( 'intent' ) ) === 'CAPTURE' ) {
119
+ $this->authorized_payments_processor->capture_authorized_payment( $wc_order );
120
+ }
121
+
122
  $this->session_handler->destroy_session_data();
123
  return array(
124
  'result' => 'success',
171
 
172
  try {
173
  if ( $this->order_processor->process( $wc_order ) ) {
174
+
175
+ if ( $this->subscription_helper->has_subscription( $order_id ) ) {
176
+ $this->logger->info( "Trying to save payment for subscription parent order #{$order_id}." );
177
+
178
+ $tokens = $this->payment_token_repository->all_for_user_id( $wc_order->get_customer_id() );
179
+ if ( $tokens ) {
180
+ $this->logger->info( "Payment for subscription parent order #{$order_id} was saved correctly." );
181
+
182
+ if ( $this->config->has( 'intent' ) && strtoupper( (string) $this->config->get( 'intent' ) ) === 'CAPTURE' ) {
183
+ $this->authorized_payments_processor->capture_authorized_payment( $wc_order );
184
+ }
185
+
186
+ $this->session_handler->destroy_session_data();
187
+
188
+ return array(
189
+ 'result' => 'success',
190
+ 'redirect' => $this->get_return_url( $wc_order ),
191
+ );
192
+ }
193
+
194
+ $this->logger->error( "Payment for subscription parent order #{$order_id} was not saved." );
195
+
196
+ $paypal_order_id = $wc_order->get_meta( PayPalGateway::ORDER_ID_META_KEY );
197
+ if ( ! $paypal_order_id ) {
198
+ throw new RuntimeException( 'PayPal order ID not found in meta.' );
199
+ }
200
+ $order = $this->order_endpoint->order( $paypal_order_id );
201
+
202
+ $purchase_units = $order->purchase_units();
203
+ if ( ! $purchase_units ) {
204
+ throw new RuntimeException( 'No purchase units.' );
205
+ }
206
+
207
+ $payments = $purchase_units[0]->payments();
208
+ if ( ! $payments ) {
209
+ throw new RuntimeException( 'No payments.' );
210
+ }
211
+
212
+ $this->logger->debug(
213
+ sprintf(
214
+ 'Trying to void order %1$s, payments: %2$s.',
215
+ $order->id(),
216
+ wp_json_encode( $payments->to_array() )
217
+ )
218
+ );
219
+
220
+ $voidable_authorizations = array_filter(
221
+ $payments->authorizations(),
222
+ function ( Authorization $authorization ): bool {
223
+ return $authorization->is_voidable();
224
+ }
225
+ );
226
+ if ( ! $voidable_authorizations ) {
227
+ throw new RuntimeException( 'No voidable authorizations.' );
228
+ }
229
+
230
+ foreach ( $voidable_authorizations as $authorization ) {
231
+ $this->payments_endpoint->void( $authorization );
232
+ }
233
+
234
+ $this->logger->debug(
235
+ sprintf(
236
+ 'Order %1$s voided successfully.',
237
+ $order->id()
238
+ )
239
+ );
240
+
241
+ $error_message = __( 'Could not process order because it was not possible to save the payment.', 'woocommerce-paypal-payments' );
242
+ $wc_order->update_status( 'failed', $error_message );
243
+
244
+ $subscriptions = wcs_get_subscriptions_for_order( $order_id );
245
+ foreach ( $subscriptions as $key => $subscription ) {
246
+ if ( $subscription->get_parent_id() === $order_id ) {
247
+ try {
248
+ $subscription->update_status( 'cancelled' );
249
+ break;
250
+ } catch ( Exception $exception ) {
251
+ $this->logger->error( "Could not update cancelled status on subscription #{$subscription->get_id()} " . $exception->getMessage() );
252
+ }
253
+ }
254
+ }
255
+
256
+ // Adds retry counter meta to avoid duplicate invoice id error on consequent tries.
257
+ $wc_order->update_meta_data( 'ppcp-retry', (int) $wc_order->get_meta( 'ppcp-retry' ) + 1 );
258
+ $wc_order->save_meta_data();
259
+
260
+ $this->session_handler->destroy_session_data();
261
+ wc_add_notice( $error_message, 'error' );
262
+
263
+ return $failure_data;
264
+ }
265
+
266
+ WC()->cart->empty_cart();
267
  $this->session_handler->destroy_session_data();
268
+
269
  return array(
270
  'result' => 'success',
271
  'redirect' => $this->get_return_url( $wc_order ),
modules/ppcp-wc-gateway/src/Gateway/{class-transactionurlprovider.php → TransactionUrlProvider.php} RENAMED
File without changes
modules/ppcp-wc-gateway/src/Helper/{class-dccproductstatus.php → DCCProductStatus.php} RENAMED
@@ -2,12 +2,12 @@
2
  /**
3
  * Manage the Seller status.
4
  *
5
- * @package Woocommerce\PayPalCommerce\WcGateway\Helper
6
  */
7
 
8
  declare( strict_types=1 );
9
 
10
- namespace Woocommerce\PayPalCommerce\WcGateway\Helper;
11
 
12
  use WooCommerce\PayPalCommerce\ApiClient\Endpoint\PartnersEndpoint;
13
  use WooCommerce\PayPalCommerce\ApiClient\Entity\SellerStatusProduct;
@@ -17,7 +17,7 @@ use WooCommerce\PayPalCommerce\WcGateway\Settings\Settings;
17
  /**
18
  * Class DccProductStatus
19
  */
20
- class DccProductStatus {
21
 
22
  /**
23
  * Caches the status for the current load.
2
  /**
3
  * Manage the Seller status.
4
  *
5
+ * @package WooCommerce\PayPalCommerce\WcGateway\Helper
6
  */
7
 
8
  declare( strict_types=1 );
9
 
10
+ namespace WooCommerce\PayPalCommerce\WcGateway\Helper;
11
 
12
  use WooCommerce\PayPalCommerce\ApiClient\Endpoint\PartnersEndpoint;
13
  use WooCommerce\PayPalCommerce\ApiClient\Entity\SellerStatusProduct;
17
  /**
18
  * Class DccProductStatus
19
  */
20
+ class DCCProductStatus {
21
 
22
  /**
23
  * Caches the status for the current load.
modules/ppcp-wc-gateway/src/Helper/{class-settingsstatus.php → SettingsStatus.php} RENAMED
@@ -2,12 +2,12 @@
2
  /**
3
  * Helper to get settings status.
4
  *
5
- * @package Woocommerce\PayPalCommerce\WcGateway\Helper
6
  */
7
 
8
  declare(strict_types=1);
9
 
10
- namespace Woocommerce\PayPalCommerce\WcGateway\Helper;
11
 
12
  use WooCommerce\PayPalCommerce\WcGateway\Settings\Settings;
13
 
2
  /**
3
  * Helper to get settings status.
4
  *
5
+ * @package WooCommerce\PayPalCommerce\WcGateway\Helper
6
  */
7
 
8
  declare(strict_types=1);
9
 
10
+ namespace WooCommerce\PayPalCommerce\WcGateway\Helper;
11
 
12
  use WooCommerce\PayPalCommerce\WcGateway\Settings\Settings;
13
 
modules/ppcp-wc-gateway/src/Notice/{class-authorizeorderactionnotice.php → AuthorizeOrderActionNotice.php} RENAMED
File without changes
modules/ppcp-wc-gateway/src/Notice/{class-connectadminnotice.php → ConnectAdminNotice.php} RENAMED
File without changes
modules/ppcp-wc-gateway/src/Notice/{class-dccwithoutpaypaladminnotice.php → DccWithoutPayPalAdminNotice.php} RENAMED
File without changes
modules/ppcp-wc-gateway/src/Processor/{class-authorizedpaymentsprocessor.php → AuthorizedPaymentsProcessor.php} RENAMED
@@ -15,9 +15,11 @@ use WooCommerce\PayPalCommerce\ApiClient\Endpoint\OrderEndpoint;
15
  use WooCommerce\PayPalCommerce\ApiClient\Endpoint\PaymentsEndpoint;
16
  use WooCommerce\PayPalCommerce\ApiClient\Entity\Authorization;
17
  use WooCommerce\PayPalCommerce\ApiClient\Entity\AuthorizationStatus;
18
- use Woocommerce\PayPalCommerce\ApiClient\Entity\Capture;
 
19
  use WooCommerce\PayPalCommerce\ApiClient\Entity\Order;
20
  use WooCommerce\PayPalCommerce\WcGateway\Gateway\PayPalGateway;
 
21
 
22
  /**
23
  * Class AuthorizedPaymentsProcessor
@@ -33,6 +35,8 @@ class AuthorizedPaymentsProcessor {
33
  const NOT_FOUND = 'NOT_FOUND';
34
  const BAD_AUTHORIZATION = 'BAD_AUTHORIZATION';
35
 
 
 
36
  /**
37
  * The Order endpoint.
38
  *
@@ -61,22 +65,32 @@ class AuthorizedPaymentsProcessor {
61
  */
62
  private $captures;
63
 
 
 
 
 
 
 
 
64
  /**
65
  * AuthorizedPaymentsProcessor constructor.
66
  *
67
- * @param OrderEndpoint $order_endpoint The Order endpoint.
68
- * @param PaymentsEndpoint $payments_endpoint The Payments endpoint.
69
- * @param LoggerInterface $logger The logger.
 
70
  */
71
  public function __construct(
72
  OrderEndpoint $order_endpoint,
73
  PaymentsEndpoint $payments_endpoint,
74
- LoggerInterface $logger
 
75
  ) {
76
 
77
  $this->order_endpoint = $order_endpoint;
78
  $this->payments_endpoint = $payments_endpoint;
79
  $this->logger = $logger;
 
80
  }
81
 
82
  /**
@@ -127,6 +141,73 @@ class AuthorizedPaymentsProcessor {
127
  return $this->captures;
128
  }
129
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
130
  /**
131
  * Returns the PayPal order from a given WooCommerce order.
132
  *
15
  use WooCommerce\PayPalCommerce\ApiClient\Endpoint\PaymentsEndpoint;
16
  use WooCommerce\PayPalCommerce\ApiClient\Entity\Authorization;
17
  use WooCommerce\PayPalCommerce\ApiClient\Entity\AuthorizationStatus;
18
+ use WooCommerce\PayPalCommerce\ApiClient\Entity\Capture;
19
+ use WooCommerce\PayPalCommerce\ApiClient\Entity\CaptureStatus;
20
  use WooCommerce\PayPalCommerce\ApiClient\Entity\Order;
21
  use WooCommerce\PayPalCommerce\WcGateway\Gateway\PayPalGateway;
22
+ use WooCommerce\PayPalCommerce\WcGateway\Notice\AuthorizeOrderActionNotice;
23
 
24
  /**
25
  * Class AuthorizedPaymentsProcessor
35
  const NOT_FOUND = 'NOT_FOUND';
36
  const BAD_AUTHORIZATION = 'BAD_AUTHORIZATION';
37
 
38
+ const CAPTURED_META_KEY = '_ppcp_paypal_captured';
39
+
40
  /**
41
  * The Order endpoint.
42
  *
65
  */
66
  private $captures;
67
 
68
+ /**
69
+ * The notice.
70
+ *
71
+ * @var AuthorizeOrderActionNotice
72
+ */
73
+ private $notice;
74
+
75
  /**
76
  * AuthorizedPaymentsProcessor constructor.
77
  *
78
+ * @param OrderEndpoint $order_endpoint The Order endpoint.
79
+ * @param PaymentsEndpoint $payments_endpoint The Payments endpoint.
80
+ * @param LoggerInterface $logger The logger.
81
+ * @param AuthorizeOrderActionNotice $notice The notice.
82
  */
83
  public function __construct(
84
  OrderEndpoint $order_endpoint,
85
  PaymentsEndpoint $payments_endpoint,
86
+ LoggerInterface $logger,
87
+ AuthorizeOrderActionNotice $notice
88
  ) {
89
 
90
  $this->order_endpoint = $order_endpoint;
91
  $this->payments_endpoint = $payments_endpoint;
92
  $this->logger = $logger;
93
+ $this->notice = $notice;
94
  }
95
 
96
  /**
141
  return $this->captures;
142
  }
143
 
144
+ /**
145
+ * Captures an authorized payment for an WooCommerce order.
146
+ *
147
+ * @param \WC_Order $wc_order The WooCommerce order.
148
+ *
149
+ * @return bool
150
+ */
151
+ public function capture_authorized_payment( \WC_Order $wc_order ): bool {
152
+ $result_status = $this->process( $wc_order );
153
+ $this->render_authorization_message_for_status( $result_status );
154
+
155
+ if ( self::ALREADY_CAPTURED === $result_status ) {
156
+ if ( $wc_order->get_status() === 'on-hold' ) {
157
+ $wc_order->add_order_note(
158
+ __( 'Payment successfully captured.', 'woocommerce-paypal-payments' )
159
+ );
160
+ }
161
+
162
+ $wc_order->update_meta_data( self::CAPTURED_META_KEY, 'true' );
163
+ $wc_order->save();
164
+ $wc_order->payment_complete();
165
+ return true;
166
+ }
167
+
168
+ $captures = $this->captures();
169
+ if ( empty( $captures ) ) {
170
+ return false;
171
+ }
172
+
173
+ $capture = end( $captures );
174
+
175
+ $this->handle_capture_status( $capture, $wc_order );
176
+
177
+ if ( self::SUCCESSFUL === $result_status ) {
178
+ if ( $capture->status()->is( CaptureStatus::COMPLETED ) ) {
179
+ $wc_order->add_order_note(
180
+ __( 'Payment successfully captured.', 'woocommerce-paypal-payments' )
181
+ );
182
+ }
183
+ $wc_order->update_meta_data( self::CAPTURED_META_KEY, 'true' );
184
+ $wc_order->save();
185
+ return true;
186
+ }
187
+
188
+ return false;
189
+ }
190
+
191
+ /**
192
+ * Displays the notice for a status.
193
+ *
194
+ * @param string $status The status.
195
+ */
196
+ private function render_authorization_message_for_status( string $status ): void {
197
+
198
+ $message_mapping = array(
199
+ self::SUCCESSFUL => AuthorizeOrderActionNotice::SUCCESS,
200
+ self::ALREADY_CAPTURED => AuthorizeOrderActionNotice::ALREADY_CAPTURED,
201
+ self::INACCESSIBLE => AuthorizeOrderActionNotice::NO_INFO,
202
+ self::NOT_FOUND => AuthorizeOrderActionNotice::NOT_FOUND,
203
+ self::BAD_AUTHORIZATION => AuthorizeOrderActionNotice::BAD_AUTHORIZATION,
204
+ );
205
+ $display_message = ( isset( $message_mapping[ $status ] ) ) ?
206
+ $message_mapping[ $status ]
207
+ : AuthorizeOrderActionNotice::FAILED;
208
+ $this->notice->display_message( $display_message );
209
+ }
210
+
211
  /**
212
  * Returns the PayPal order from a given WooCommerce order.
213
  *
modules/ppcp-wc-gateway/src/Processor/{class-ordermetatrait.php → OrderMetaTrait.php} RENAMED
File without changes
modules/ppcp-wc-gateway/src/Processor/{class-orderprocessor.php → OrderProcessor.php} RENAMED
@@ -26,7 +26,7 @@ use WooCommerce\PayPalCommerce\WcGateway\Settings\Settings;
26
  */
27
  class OrderProcessor {
28
 
29
- use OrderMetaTrait, PaymentsStatusHandlingTrait;
30
 
31
  /**
32
  * The environment.
@@ -171,13 +171,13 @@ class OrderProcessor {
171
  if ( $order->intent() === 'AUTHORIZE' ) {
172
  $order = $this->order_endpoint->authorize( $order );
173
 
174
- $wc_order->update_meta_data( PayPalGateway::CAPTURED_META_KEY, 'false' );
175
  }
176
 
177
  $transaction_id = $this->get_paypal_order_transaction_id( $order );
178
 
179
- if ( '' !== $transaction_id ) {
180
- $this->set_order_transaction_id( $transaction_id, $wc_order );
181
  }
182
 
183
  $this->handle_new_order_status( $order, $wc_order );
@@ -186,64 +186,13 @@ class OrderProcessor {
186
  $wc_order->add_order_note(
187
  __( 'Payment successfully captured.', 'woocommerce-paypal-payments' )
188
  );
189
- $wc_order->update_meta_data( PayPalGateway::CAPTURED_META_KEY, 'true' );
190
  $wc_order->update_status( 'processing' );
191
  }
192
- WC()->cart->empty_cart();
193
- $this->session_handler->destroy_session_data();
194
  $this->last_error = '';
195
  return true;
196
  }
197
 
198
- /**
199
- * Set transaction id to WC order meta data.
200
- *
201
- * @param string $transaction_id Transaction id to set.
202
- * @param \WC_Order $wc_order Order to set transaction ID to.
203
- */
204
- public function set_order_transaction_id( string $transaction_id, \WC_Order $wc_order ) {
205
- try {
206
- $wc_order->set_transaction_id( $transaction_id );
207
- } catch ( \WC_Data_Exception $exception ) {
208
- $this->logger->log(
209
- 'warning',
210
- sprintf(
211
- 'Failed to set transaction ID. Exception caught when tried: %1$s',
212
- $exception->getMessage()
213
- )
214
- );
215
- }
216
- }
217
-
218
- /**
219
- * Retrieve transaction id from PayPal order.
220
- *
221
- * @param Order $order Order to get transaction id from.
222
- *
223
- * @return string
224
- */
225
- private function get_paypal_order_transaction_id( Order $order ): string {
226
- $purchase_units = $order->purchase_units();
227
-
228
- if ( ! isset( $purchase_units[0] ) ) {
229
- return '';
230
- }
231
-
232
- $payments = $purchase_units[0]->payments();
233
-
234
- if ( null === $payments ) {
235
- return '';
236
- }
237
-
238
- $captures = $payments->captures();
239
-
240
- if ( isset( $captures[0] ) ) {
241
- return $captures[0]->id();
242
- }
243
-
244
- return '';
245
- }
246
-
247
  /**
248
  * Returns if an order should be captured immediately.
249
  *
26
  */
27
  class OrderProcessor {
28
 
29
+ use OrderMetaTrait, PaymentsStatusHandlingTrait, TransactionIdHandlingTrait;
30
 
31
  /**
32
  * The environment.
171
  if ( $order->intent() === 'AUTHORIZE' ) {
172
  $order = $this->order_endpoint->authorize( $order );
173
 
174
+ $wc_order->update_meta_data( AuthorizedPaymentsProcessor::CAPTURED_META_KEY, 'false' );
175
  }
176
 
177
  $transaction_id = $this->get_paypal_order_transaction_id( $order );
178
 
179
+ if ( $transaction_id ) {
180
+ $this->update_transaction_id( $transaction_id, $wc_order );
181
  }
182
 
183
  $this->handle_new_order_status( $order, $wc_order );
186
  $wc_order->add_order_note(
187
  __( 'Payment successfully captured.', 'woocommerce-paypal-payments' )
188
  );
189
+ $wc_order->update_meta_data( AuthorizedPaymentsProcessor::CAPTURED_META_KEY, 'true' );
190
  $wc_order->update_status( 'processing' );
191
  }
 
 
192
  $this->last_error = '';
193
  return true;
194
  }
195
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
196
  /**
197
  * Returns if an order should be captured immediately.
198
  *
modules/ppcp-wc-gateway/src/Processor/{class-paymentstatushandlingtrait.php → PaymentsStatusHandlingTrait.php} RENAMED
@@ -12,7 +12,7 @@ namespace WooCommerce\PayPalCommerce\WcGateway\Processor;
12
  use WC_Order;
13
  use WooCommerce\PayPalCommerce\ApiClient\Entity\Authorization;
14
  use WooCommerce\PayPalCommerce\ApiClient\Entity\AuthorizationStatus;
15
- use Woocommerce\PayPalCommerce\ApiClient\Entity\Capture;
16
  use WooCommerce\PayPalCommerce\ApiClient\Entity\CaptureStatus;
17
  use WooCommerce\PayPalCommerce\ApiClient\Entity\Order;
18
  use WooCommerce\PayPalCommerce\ApiClient\Exception\RuntimeException;
@@ -55,8 +55,9 @@ trait PaymentsStatusHandlingTrait {
55
  ): void {
56
  $status = $capture->status();
57
 
58
- if ( $status->details() ) {
59
- $this->add_status_details_note( $wc_order, $status->name(), $status->details()->text() );
 
60
  }
61
 
62
  switch ( $status->name() ) {
@@ -95,8 +96,9 @@ trait PaymentsStatusHandlingTrait {
95
  ): void {
96
  $status = $authorization->status();
97
 
98
- if ( $status->details() ) {
99
- $this->add_status_details_note( $wc_order, $status->name(), $status->details()->text() );
 
100
  }
101
 
102
  switch ( $status->name() ) {
12
  use WC_Order;
13
  use WooCommerce\PayPalCommerce\ApiClient\Entity\Authorization;
14
  use WooCommerce\PayPalCommerce\ApiClient\Entity\AuthorizationStatus;
15
+ use WooCommerce\PayPalCommerce\ApiClient\Entity\Capture;
16
  use WooCommerce\PayPalCommerce\ApiClient\Entity\CaptureStatus;
17
  use WooCommerce\PayPalCommerce\ApiClient\Entity\Order;
18
  use WooCommerce\PayPalCommerce\ApiClient\Exception\RuntimeException;
55
  ): void {
56
  $status = $capture->status();
57
 
58
+ $details = $status->details();
59
+ if ( $details ) {
60
+ $this->add_status_details_note( $wc_order, $status->name(), $details->text() );
61
  }
62
 
63
  switch ( $status->name() ) {
96
  ): void {
97
  $status = $authorization->status();
98
 
99
+ $details = $status->details();
100
+ if ( $details ) {
101
+ $this->add_status_details_note( $wc_order, $status->name(), $details->text() );
102
  }
103
 
104
  switch ( $status->name() ) {
modules/ppcp-wc-gateway/src/Processor/{class-refundprocessor.php → RefundProcessor.php} RENAMED
@@ -127,7 +127,9 @@ class RefundProcessor {
127
  case self::REFUND_MODE_VOID:
128
  $voidable_authorizations = array_filter(
129
  $payments->authorizations(),
130
- array( $this, 'is_voidable_authorization' )
 
 
131
  );
132
  if ( ! $voidable_authorizations ) {
133
  throw new RuntimeException( 'No voidable authorizations.' );
@@ -163,7 +165,7 @@ class RefundProcessor {
163
  $authorizations = $payments->authorizations();
164
  if ( $authorizations ) {
165
  foreach ( $authorizations as $authorization ) {
166
- if ( $this->is_voidable_authorization( $authorization ) ) {
167
  return self::REFUND_MODE_VOID;
168
  }
169
  }
@@ -175,15 +177,4 @@ class RefundProcessor {
175
 
176
  return self::REFUND_MODE_UNKNOWN;
177
  }
178
-
179
- /**
180
- * Checks whether the authorization can be voided.
181
- *
182
- * @param Authorization $authorization The authorization to check.
183
- * @return bool
184
- */
185
- private function is_voidable_authorization( Authorization $authorization ): bool {
186
- return $authorization->status()->is( AuthorizationStatus::CREATED ) ||
187
- $authorization->status()->is( AuthorizationStatus::PENDING );
188
- }
189
  }
127
  case self::REFUND_MODE_VOID:
128
  $voidable_authorizations = array_filter(
129
  $payments->authorizations(),
130
+ function ( Authorization $authorization ): bool {
131
+ return $authorization->is_voidable();
132
+ }
133
  );
134
  if ( ! $voidable_authorizations ) {
135
  throw new RuntimeException( 'No voidable authorizations.' );
165
  $authorizations = $payments->authorizations();
166
  if ( $authorizations ) {
167
  foreach ( $authorizations as $authorization ) {
168
+ if ( $authorization->is_voidable() ) {
169
  return self::REFUND_MODE_VOID;
170
  }
171
  }
177
 
178
  return self::REFUND_MODE_UNKNOWN;
179
  }
 
 
 
 
 
 
 
 
 
 
 
180
  }
modules/ppcp-wc-gateway/src/Processor/TransactionIdHandlingTrait.php ADDED
@@ -0,0 +1,85 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Functions for retrieving/saving order transaction ID.
4
+ *
5
+ * @package WooCommerce\PayPalCommerce\WcGateway\Processor
6
+ */
7
+
8
+ declare(strict_types=1);
9
+
10
+ namespace WooCommerce\PayPalCommerce\WcGateway\Processor;
11
+
12
+ use Exception;
13
+ use Psr\Log\LoggerInterface;
14
+ use WC_Order;
15
+ use WooCommerce\PayPalCommerce\ApiClient\Entity\Order;
16
+
17
+ /**
18
+ * Trait PaymentsStatusHandlingTrait.
19
+ */
20
+ trait TransactionIdHandlingTrait {
21
+
22
+ /**
23
+ * Sets transaction ID to the WC order.
24
+ *
25
+ * @param string $transaction_id The transaction ID to set.
26
+ * @param WC_Order $wc_order The order to set transaction ID to.
27
+ * @param LoggerInterface|null $logger The logger to log errors.
28
+ *
29
+ * @return bool
30
+ */
31
+ protected function update_transaction_id(
32
+ string $transaction_id,
33
+ WC_Order $wc_order,
34
+ LoggerInterface $logger = null
35
+ ): bool {
36
+ try {
37
+ $wc_order->set_transaction_id( $transaction_id );
38
+ $wc_order->save();
39
+ return true;
40
+ } catch ( Exception $exception ) {
41
+ if ( $logger ) {
42
+ $logger->warning(
43
+ sprintf(
44
+ 'Failed to set transaction ID %1$s. %2$s',
45
+ $transaction_id,
46
+ $exception->getMessage()
47
+ )
48
+ );
49
+ }
50
+ return false;
51
+ }
52
+ }
53
+
54
+ /**
55
+ * Retrieves transaction id from PayPal order.
56
+ *
57
+ * @param Order $order The order to get transaction id from.
58
+ *
59
+ * @return string|null
60
+ */
61
+ protected function get_paypal_order_transaction_id( Order $order ): ?string {
62
+ $purchase_unit = $order->purchase_units()[0] ?? null;
63
+ if ( ! $purchase_unit ) {
64
+ return null;
65
+ }
66
+
67
+ $payments = $purchase_unit->payments();
68
+ if ( null === $payments ) {
69
+ return null;
70
+ }
71
+
72
+ $capture = $payments->captures()[0] ?? null;
73
+ if ( $capture ) {
74
+ return $capture->id();
75
+ }
76
+
77
+ $authorization = $payments->authorizations()[0] ?? null;
78
+ if ( $authorization ) {
79
+ return $authorization->id();
80
+ }
81
+
82
+ return null;
83
+ }
84
+
85
+ }
modules/ppcp-wc-gateway/src/Settings/{class-pagematchertrait.php → PageMatcherTrait.php} RENAMED
@@ -9,15 +9,8 @@ declare(strict_types=1);
9
 
10
  namespace WooCommerce\PayPalCommerce\WcGateway\Settings;
11
 
12
- use WooCommerce\PayPalCommerce\AdminNotices\Entity\Message;
13
- use WooCommerce\PayPalCommerce\ApiClient\Helper\DccApplies;
14
- use WooCommerce\PayPalCommerce\Button\Helper\MessagesApply;
15
- use WooCommerce\PayPalCommerce\Onboarding\State;
16
  use WooCommerce\PayPalCommerce\WcGateway\Gateway\CreditCardGateway;
17
- use Psr\Container\ContainerInterface;
18
  use WooCommerce\PayPalCommerce\WcGateway\Gateway\PayPalGateway;
19
- use Woocommerce\PayPalCommerce\WcGateway\Helper\DccProductStatus;
20
- use Woocommerce\PayPalCommerce\WcGateway\Helper\SettingsStatus;
21
  use WooCommerce\PayPalCommerce\Webhooks\Status\WebhooksStatusPage;
22
 
23
  /**
9
 
10
  namespace WooCommerce\PayPalCommerce\WcGateway\Settings;
11
 
 
 
 
 
12
  use WooCommerce\PayPalCommerce\WcGateway\Gateway\CreditCardGateway;
 
13
  use WooCommerce\PayPalCommerce\WcGateway\Gateway\PayPalGateway;
 
 
14
  use WooCommerce\PayPalCommerce\Webhooks\Status\WebhooksStatusPage;
15
 
16
  /**
modules/ppcp-wc-gateway/src/Settings/{class-sectionsrenderer.php → SectionsRenderer.php} RENAMED
File without changes
modules/ppcp-wc-gateway/src/Settings/{class-settings.php → Settings.php} RENAMED
File without changes
modules/ppcp-wc-gateway/src/Settings/{class-settingslistener.php → SettingsListener.php} RENAMED
File without changes
modules/ppcp-wc-gateway/src/Settings/{class-settingsrenderer.php → SettingsRenderer.php} RENAMED
@@ -15,9 +15,9 @@ use WooCommerce\PayPalCommerce\Button\Helper\MessagesApply;
15
  use WooCommerce\PayPalCommerce\Onboarding\State;
16
  use WooCommerce\PayPalCommerce\WcGateway\Gateway\CreditCardGateway;
17
  use Psr\Container\ContainerInterface;
 
18
  use WooCommerce\PayPalCommerce\WcGateway\Gateway\PayPalGateway;
19
- use Woocommerce\PayPalCommerce\WcGateway\Helper\DccProductStatus;
20
- use Woocommerce\PayPalCommerce\WcGateway\Helper\SettingsStatus;
21
 
22
  /**
23
  * Class SettingsRenderer
@@ -71,7 +71,7 @@ class SettingsRenderer {
71
  /**
72
  * The DCC Product Status.
73
  *
74
- * @var DccProductStatus
75
  */
76
  private $dcc_product_status;
77
 
@@ -90,7 +90,7 @@ class SettingsRenderer {
90
  * @param array $fields The setting fields.
91
  * @param DccApplies $dcc_applies Whether DCC gateway can be shown.
92
  * @param MessagesApply $messages_apply Whether messages can be shown.
93
- * @param DccProductStatus $dcc_product_status The product status.
94
  * @param SettingsStatus $settings_status The Settings status helper.
95
  * @param string $page_id ID of the current PPCP gateway settings page, or empty if it is not such page.
96
  */
@@ -100,7 +100,7 @@ class SettingsRenderer {
100
  array $fields,
101
  DccApplies $dcc_applies,
102
  MessagesApply $messages_apply,
103
- DccProductStatus $dcc_product_status,
104
  SettingsStatus $settings_status,
105
  string $page_id
106
  ) {
15
  use WooCommerce\PayPalCommerce\Onboarding\State;
16
  use WooCommerce\PayPalCommerce\WcGateway\Gateway\CreditCardGateway;
17
  use Psr\Container\ContainerInterface;
18
+ use WooCommerce\PayPalCommerce\WcGateway\Helper\DCCProductStatus;
19
  use WooCommerce\PayPalCommerce\WcGateway\Gateway\PayPalGateway;
20
+ use WooCommerce\PayPalCommerce\WcGateway\Helper\SettingsStatus;
 
21
 
22
  /**
23
  * Class SettingsRenderer
71
  /**
72
  * The DCC Product Status.
73
  *
74
+ * @var DCCProductStatus
75
  */
76
  private $dcc_product_status;
77
 
90
  * @param array $fields The setting fields.
91
  * @param DccApplies $dcc_applies Whether DCC gateway can be shown.
92
  * @param MessagesApply $messages_apply Whether messages can be shown.
93
+ * @param DCCProductStatus $dcc_product_status The product status.
94
  * @param SettingsStatus $settings_status The Settings status helper.
95
  * @param string $page_id ID of the current PPCP gateway settings page, or empty if it is not such page.
96
  */
100
  array $fields,
101
  DccApplies $dcc_applies,
102
  MessagesApply $messages_apply,
103
+ DCCProductStatus $dcc_product_status,
104
  SettingsStatus $settings_status,
105
  string $page_id
106
  ) {
modules/ppcp-wc-gateway/src/{class-wcgatewaymodule.php → WCGatewayModule.php} RENAMED
@@ -25,6 +25,7 @@ use WooCommerce\PayPalCommerce\WcGateway\Gateway\CreditCardGateway;
25
  use WooCommerce\PayPalCommerce\WcGateway\Gateway\PayPalGateway;
26
  use WooCommerce\PayPalCommerce\WcGateway\Notice\ConnectAdminNotice;
27
  use WooCommerce\PayPalCommerce\WcGateway\Notice\DccWithoutPayPalAdminNotice;
 
28
  use WooCommerce\PayPalCommerce\WcGateway\Settings\SectionsRenderer;
29
  use WooCommerce\PayPalCommerce\WcGateway\Settings\Settings;
30
  use WooCommerce\PayPalCommerce\WcGateway\Settings\SettingsListener;
@@ -35,12 +36,10 @@ use Psr\Container\ContainerInterface;
35
  /**
36
  * Class WcGatewayModule
37
  */
38
- class WcGatewayModule implements ModuleInterface {
39
 
40
  /**
41
- * Setup the module.
42
- *
43
- * @return ServiceProviderInterface
44
  */
45
  public function setup(): ServiceProviderInterface {
46
  return new ServiceProvider(
@@ -50,20 +49,18 @@ class WcGatewayModule implements ModuleInterface {
50
  }
51
 
52
  /**
53
- * Runs the module.
54
- *
55
- * @param ContainerInterface|null $container The container.
56
  */
57
- public function run( ContainerInterface $container ): void {
58
- $this->register_payment_gateways( $container );
59
- $this->register_order_functionality( $container );
60
- $this->register_columns( $container );
61
- $this->register_checkout_paypal_address_preset( $container );
62
 
63
  add_action(
64
  'woocommerce_sections_checkout',
65
- function() use ( $container ) {
66
- $section_renderer = $container->get( 'wcgateway.settings.sections-renderer' );
67
  /**
68
  * The Section Renderer.
69
  *
@@ -73,39 +70,39 @@ class WcGatewayModule implements ModuleInterface {
73
  }
74
  );
75
 
76
- if ( $container->has( 'wcgateway.url' ) ) {
77
  $assets = new SettingsPageAssets(
78
- $container->get( 'wcgateway.url' ),
79
- $container->get( 'wcgateway.absolute-path' ),
80
- $container->get( 'api.bearer' )
81
  );
82
  $assets->register_assets();
83
  }
84
 
85
  add_filter(
86
  Repository::NOTICES_FILTER,
87
- static function ( $notices ) use ( $container ): array {
88
- $notice = $container->get( 'wcgateway.notice.connect' );
89
  assert( $notice instanceof ConnectAdminNotice );
90
  $connect_message = $notice->connect_message();
91
  if ( $connect_message ) {
92
  $notices[] = $connect_message;
93
  }
94
 
95
- $dcc_without_paypal_notice = $container->get( 'wcgateway.notice.dcc-without-paypal' );
96
  assert( $dcc_without_paypal_notice instanceof DccWithoutPayPalAdminNotice );
97
  $dcc_without_paypal_message = $dcc_without_paypal_notice->message();
98
  if ( $dcc_without_paypal_message ) {
99
  $notices[] = $dcc_without_paypal_message;
100
  }
101
 
102
- $authorize_order_action = $container->get( 'wcgateway.notice.authorize-order-action' );
103
  $authorized_message = $authorize_order_action->message();
104
  if ( $authorized_message ) {
105
  $notices[] = $authorized_message;
106
  }
107
 
108
- $settings_renderer = $container->get( 'wcgateway.settings.render' );
109
  assert( $settings_renderer instanceof SettingsRenderer );
110
  $messages = $settings_renderer->messages();
111
  $notices = array_merge( $notices, $messages );
@@ -115,7 +112,7 @@ class WcGatewayModule implements ModuleInterface {
115
  );
116
  add_action(
117
  'woocommerce_paypal_commerce_gateway_deactivate',
118
- static function () use ( $container ) {
119
  delete_option( Settings::KEY );
120
  delete_option( PayPalRequestIdRepository::KEY );
121
  delete_option( 'woocommerce_' . PayPalGateway::ID . '_settings' );
@@ -125,8 +122,8 @@ class WcGatewayModule implements ModuleInterface {
125
 
126
  add_action(
127
  'wc_ajax_' . ReturnUrlEndpoint::ENDPOINT,
128
- static function () use ( $container ) {
129
- $endpoint = $container->get( 'wcgateway.endpoint.return-url' );
130
  /**
131
  * The Endpoint.
132
  *
@@ -152,9 +149,9 @@ class WcGatewayModule implements ModuleInterface {
152
  /**
153
  * Registers the payment gateways.
154
  *
155
- * @param ContainerInterface|null $container The container.
156
  */
157
- private function register_payment_gateways( ContainerInterface $container = null ) {
158
 
159
  add_filter(
160
  'woocommerce_payment_gateways',
@@ -263,13 +260,14 @@ class WcGatewayModule implements ModuleInterface {
263
  add_action(
264
  'woocommerce_order_action_ppcp_authorize_order',
265
  static function ( \WC_Order $wc_order ) use ( $container ) {
 
266
  /**
267
- * The PayPal Gateway.
268
  *
269
- * @var PayPalGateway $gateway
270
  */
271
- $gateway = $container->get( 'wcgateway.paypal-gateway' );
272
- $gateway->capture_authorized_payment( $wc_order );
273
  }
274
  );
275
  }
25
  use WooCommerce\PayPalCommerce\WcGateway\Gateway\PayPalGateway;
26
  use WooCommerce\PayPalCommerce\WcGateway\Notice\ConnectAdminNotice;
27
  use WooCommerce\PayPalCommerce\WcGateway\Notice\DccWithoutPayPalAdminNotice;
28
+ use WooCommerce\PayPalCommerce\WcGateway\Processor\AuthorizedPaymentsProcessor;
29
  use WooCommerce\PayPalCommerce\WcGateway\Settings\SectionsRenderer;
30
  use WooCommerce\PayPalCommerce\WcGateway\Settings\Settings;
31
  use WooCommerce\PayPalCommerce\WcGateway\Settings\SettingsListener;
36
  /**
37
  * Class WcGatewayModule
38
  */
39
+ class WCGatewayModule implements ModuleInterface {
40
 
41
  /**
42
+ * {@inheritDoc}
 
 
43
  */
44
  public function setup(): ServiceProviderInterface {
45
  return new ServiceProvider(
49
  }
50
 
51
  /**
52
+ * {@inheritDoc}
 
 
53
  */
54
+ public function run( ContainerInterface $c ): void {
55
+ $this->register_payment_gateways( $c );
56
+ $this->register_order_functionality( $c );
57
+ $this->register_columns( $c );
58
+ $this->register_checkout_paypal_address_preset( $c );
59
 
60
  add_action(
61
  'woocommerce_sections_checkout',
62
+ function() use ( $c ) {
63
+ $section_renderer = $c->get( 'wcgateway.settings.sections-renderer' );
64
  /**
65
  * The Section Renderer.
66
  *
70
  }
71
  );
72
 
73
+ if ( $c->has( 'wcgateway.url' ) ) {
74
  $assets = new SettingsPageAssets(
75
+ $c->get( 'wcgateway.url' ),
76
+ $c->get( 'wcgateway.absolute-path' ),
77
+ $c->get( 'api.bearer' )
78
  );
79
  $assets->register_assets();
80
  }
81
 
82
  add_filter(
83
  Repository::NOTICES_FILTER,
84
+ static function ( $notices ) use ( $c ): array {
85
+ $notice = $c->get( 'wcgateway.notice.connect' );
86
  assert( $notice instanceof ConnectAdminNotice );
87
  $connect_message = $notice->connect_message();
88
  if ( $connect_message ) {
89
  $notices[] = $connect_message;
90
  }
91
 
92
+ $dcc_without_paypal_notice = $c->get( 'wcgateway.notice.dcc-without-paypal' );
93
  assert( $dcc_without_paypal_notice instanceof DccWithoutPayPalAdminNotice );
94
  $dcc_without_paypal_message = $dcc_without_paypal_notice->message();
95
  if ( $dcc_without_paypal_message ) {
96
  $notices[] = $dcc_without_paypal_message;
97
  }
98
 
99
+ $authorize_order_action = $c->get( 'wcgateway.notice.authorize-order-action' );
100
  $authorized_message = $authorize_order_action->message();
101
  if ( $authorized_message ) {
102
  $notices[] = $authorized_message;
103
  }
104
 
105
+ $settings_renderer = $c->get( 'wcgateway.settings.render' );
106
  assert( $settings_renderer instanceof SettingsRenderer );
107
  $messages = $settings_renderer->messages();
108
  $notices = array_merge( $notices, $messages );
112
  );
113
  add_action(
114
  'woocommerce_paypal_commerce_gateway_deactivate',
115
+ static function () use ( $c ) {
116
  delete_option( Settings::KEY );
117
  delete_option( PayPalRequestIdRepository::KEY );
118
  delete_option( 'woocommerce_' . PayPalGateway::ID . '_settings' );
122
 
123
  add_action(
124
  'wc_ajax_' . ReturnUrlEndpoint::ENDPOINT,
125
+ static function () use ( $c ) {
126
+ $endpoint = $c->get( 'wcgateway.endpoint.return-url' );
127
  /**
128
  * The Endpoint.
129
  *
149
  /**
150
  * Registers the payment gateways.
151
  *
152
+ * @param ContainerInterface $container The container.
153
  */
154
+ private function register_payment_gateways( ContainerInterface $container ) {
155
 
156
  add_filter(
157
  'woocommerce_payment_gateways',
260
  add_action(
261
  'woocommerce_order_action_ppcp_authorize_order',
262
  static function ( \WC_Order $wc_order ) use ( $container ) {
263
+
264
  /**
265
+ * The authorized payments processor.
266
  *
267
+ * @var AuthorizedPaymentsProcessor $authorized_payments_processor
268
  */
269
+ $authorized_payments_processor = $container->get( 'wcgateway.processor.authorized-payments' );
270
+ $authorized_payments_processor->capture_authorized_payment( $wc_order );
271
  }
272
  );
273
  }
modules/ppcp-webhooks/composer.json ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "woocommerce/ppcp-webhooks",
3
+ "type": "dhii-mod",
4
+ "description": "Webhooks module for PPCP",
5
+ "license": "GPL-2.0",
6
+ "require": {
7
+ "php": "^7.1 | ^8.0",
8
+ "dhii/module-interface": "^0.3.0-alpha1"
9
+ },
10
+ "autoload": {
11
+ "psr-4": {
12
+ "WooCommerce\\PayPalCommerce\\Webhooks\\": "src"
13
+ }
14
+ },
15
+ "minimum-stability": "dev",
16
+ "prefer-stable": true
17
+ }
modules/ppcp-webhooks/services.php CHANGED
@@ -14,7 +14,6 @@ use Psr\Log\LoggerInterface;
14
  use WooCommerce\PayPalCommerce\ApiClient\Endpoint\WebhookEndpoint;
15
  use WooCommerce\PayPalCommerce\ApiClient\Entity\Webhook;
16
  use WooCommerce\PayPalCommerce\ApiClient\Factory\WebhookFactory;
17
- use WooCommerce\PayPalCommerce\WcGateway\Assets\WebhooksStatusPageAssets;
18
  use WooCommerce\PayPalCommerce\Webhooks\Endpoint\ResubscribeEndpoint;
19
  use WooCommerce\PayPalCommerce\Webhooks\Endpoint\SimulateEndpoint;
20
  use WooCommerce\PayPalCommerce\Webhooks\Endpoint\SimulationStateEndpoint;
@@ -24,11 +23,12 @@ use WooCommerce\PayPalCommerce\Webhooks\Handler\PaymentCaptureCompleted;
24
  use WooCommerce\PayPalCommerce\Webhooks\Handler\PaymentCaptureRefunded;
25
  use WooCommerce\PayPalCommerce\Webhooks\Handler\PaymentCaptureReversed;
26
  use Psr\Container\ContainerInterface;
 
27
  use WooCommerce\PayPalCommerce\Webhooks\Status\WebhookSimulation;
28
 
29
  return array(
30
 
31
- 'webhook.registrar' => function( $container ) : WebhookRegistrar {
32
  $factory = $container->get( 'api.factory.webhook' );
33
  $endpoint = $container->get( 'api.endpoint.webhook' );
34
  $rest_endpoint = $container->get( 'webhook.endpoint.controller' );
@@ -40,7 +40,7 @@ return array(
40
  $logger
41
  );
42
  },
43
- 'webhook.endpoint.controller' => function( $container ) : IncomingWebhookEndpoint {
44
  $webhook_endpoint = $container->get( 'api.endpoint.webhook' );
45
  $webhook = $container->get( 'webhook.current' );
46
  $handler = $container->get( 'webhook.endpoint.handler' );
@@ -59,7 +59,7 @@ return array(
59
  ... $handler
60
  );
61
  },
62
- 'webhook.endpoint.handler' => function( $container ) : array {
63
  $logger = $container->get( 'woocommerce.logger.woocommerce' );
64
  $prefix = $container->get( 'api.prefix' );
65
  $order_endpoint = $container->get( 'api.endpoint.order' );
@@ -68,11 +68,11 @@ return array(
68
  new CheckoutOrderCompleted( $logger, $prefix ),
69
  new PaymentCaptureRefunded( $logger, $prefix ),
70
  new PaymentCaptureReversed( $logger, $prefix ),
71
- new PaymentCaptureCompleted( $logger, $prefix ),
72
  );
73
  },
74
 
75
- 'webhook.current' => function( $container ) : ?Webhook {
76
  $data = (array) get_option( WebhookRegistrar::KEY, array() );
77
  if ( empty( $data ) ) {
78
  return null;
@@ -91,18 +91,18 @@ return array(
91
  }
92
  },
93
 
94
- 'webhook.is-registered' => function( $container ) : bool {
95
  return $container->get( 'webhook.current' ) !== null;
96
  },
97
 
98
- 'webhook.status.registered-webhooks' => function( $container ) : array {
99
  $endpoint = $container->get( 'api.endpoint.webhook' );
100
  assert( $endpoint instanceof WebhookEndpoint );
101
 
102
  return $endpoint->list();
103
  },
104
 
105
- 'webhook.status.registered-webhooks-data' => function( $container ) : array {
106
  $empty_placeholder = __( 'No webhooks found.', 'woocommerce-paypal-payments' );
107
 
108
  $webhooks = array();
@@ -139,7 +139,7 @@ return array(
139
  );
140
  },
141
 
142
- 'webhook.status.simulation' => function( $container ) : WebhookSimulation {
143
  $webhook_endpoint = $container->get( 'api.endpoint.webhook' );
144
  $webhook = $container->get( 'webhook.current' );
145
  return new WebhookSimulation(
@@ -150,13 +150,13 @@ return array(
150
  );
151
  },
152
 
153
- 'webhook.status.assets' => function( $container ) : WebhooksStatusPageAssets {
154
  return new WebhooksStatusPageAssets(
155
  $container->get( 'webhook.module-url' )
156
  );
157
  },
158
 
159
- 'webhook.endpoint.resubscribe' => static function ( $container ) : ResubscribeEndpoint {
160
  $registrar = $container->get( 'webhook.registrar' );
161
  $request_data = $container->get( 'button.request-data' );
162
 
@@ -166,7 +166,7 @@ return array(
166
  );
167
  },
168
 
169
- 'webhook.endpoint.simulate' => static function ( $container ) : SimulateEndpoint {
170
  $simulation = $container->get( 'webhook.status.simulation' );
171
  $request_data = $container->get( 'button.request-data' );
172
 
@@ -175,7 +175,7 @@ return array(
175
  $request_data
176
  );
177
  },
178
- 'webhook.endpoint.simulation-state' => static function ( $container ) : SimulationStateEndpoint {
179
  $simulation = $container->get( 'webhook.status.simulation' );
180
 
181
  return new SimulationStateEndpoint(
@@ -183,7 +183,7 @@ return array(
183
  );
184
  },
185
 
186
- 'webhook.module-url' => static function ( $container ): string {
187
  return plugins_url(
188
  '/modules/ppcp-webhooks/',
189
  dirname( __FILE__, 3 ) . '/woocommerce-paypal-payments.php'
14
  use WooCommerce\PayPalCommerce\ApiClient\Endpoint\WebhookEndpoint;
15
  use WooCommerce\PayPalCommerce\ApiClient\Entity\Webhook;
16
  use WooCommerce\PayPalCommerce\ApiClient\Factory\WebhookFactory;
 
17
  use WooCommerce\PayPalCommerce\Webhooks\Endpoint\ResubscribeEndpoint;
18
  use WooCommerce\PayPalCommerce\Webhooks\Endpoint\SimulateEndpoint;
19
  use WooCommerce\PayPalCommerce\Webhooks\Endpoint\SimulationStateEndpoint;
23
  use WooCommerce\PayPalCommerce\Webhooks\Handler\PaymentCaptureRefunded;
24
  use WooCommerce\PayPalCommerce\Webhooks\Handler\PaymentCaptureReversed;
25
  use Psr\Container\ContainerInterface;
26
+ use WooCommerce\PayPalCommerce\Webhooks\Status\Assets\WebhooksStatusPageAssets;
27
  use WooCommerce\PayPalCommerce\Webhooks\Status\WebhookSimulation;
28
 
29
  return array(
30
 
31
+ 'webhook.registrar' => function( ContainerInterface $container ) : WebhookRegistrar {
32
  $factory = $container->get( 'api.factory.webhook' );
33
  $endpoint = $container->get( 'api.endpoint.webhook' );
34
  $rest_endpoint = $container->get( 'webhook.endpoint.controller' );
40
  $logger
41
  );
42
  },
43
+ 'webhook.endpoint.controller' => function( ContainerInterface $container ) : IncomingWebhookEndpoint {
44
  $webhook_endpoint = $container->get( 'api.endpoint.webhook' );
45
  $webhook = $container->get( 'webhook.current' );
46
  $handler = $container->get( 'webhook.endpoint.handler' );
59
  ... $handler
60
  );
61
  },
62
+ 'webhook.endpoint.handler' => function( ContainerInterface $container ) : array {
63
  $logger = $container->get( 'woocommerce.logger.woocommerce' );
64
  $prefix = $container->get( 'api.prefix' );
65
  $order_endpoint = $container->get( 'api.endpoint.order' );
68
  new CheckoutOrderCompleted( $logger, $prefix ),
69
  new PaymentCaptureRefunded( $logger, $prefix ),
70
  new PaymentCaptureReversed( $logger, $prefix ),
71
+ new PaymentCaptureCompleted( $logger, $prefix, $order_endpoint ),
72
  );
73
  },
74
 
75
+ 'webhook.current' => function( ContainerInterface $container ) : ?Webhook {
76
  $data = (array) get_option( WebhookRegistrar::KEY, array() );
77
  if ( empty( $data ) ) {
78
  return null;
91
  }
92
  },
93
 
94
+ 'webhook.is-registered' => function( ContainerInterface $container ) : bool {
95
  return $container->get( 'webhook.current' ) !== null;
96
  },
97
 
98
+ 'webhook.status.registered-webhooks' => function( ContainerInterface $container ) : array {
99
  $endpoint = $container->get( 'api.endpoint.webhook' );
100
  assert( $endpoint instanceof WebhookEndpoint );
101
 
102
  return $endpoint->list();
103
  },
104
 
105
+ 'webhook.status.registered-webhooks-data' => function( ContainerInterface $container ) : array {
106
  $empty_placeholder = __( 'No webhooks found.', 'woocommerce-paypal-payments' );
107
 
108
  $webhooks = array();
139
  );
140
  },
141
 
142
+ 'webhook.status.simulation' => function( ContainerInterface $container ) : WebhookSimulation {
143
  $webhook_endpoint = $container->get( 'api.endpoint.webhook' );
144
  $webhook = $container->get( 'webhook.current' );
145
  return new WebhookSimulation(
150
  );
151
  },
152
 
153
+ 'webhook.status.assets' => function( ContainerInterface $container ) : WebhooksStatusPageAssets {
154
  return new WebhooksStatusPageAssets(
155
  $container->get( 'webhook.module-url' )
156
  );
157
  },
158
 
159
+ 'webhook.endpoint.resubscribe' => static function ( ContainerInterface $container ) : ResubscribeEndpoint {
160
  $registrar = $container->get( 'webhook.registrar' );
161
  $request_data = $container->get( 'button.request-data' );
162
 
166
  );
167
  },
168
 
169
+ 'webhook.endpoint.simulate' => static function ( ContainerInterface $container ) : SimulateEndpoint {
170
  $simulation = $container->get( 'webhook.status.simulation' );
171
  $request_data = $container->get( 'button.request-data' );
172
 
175
  $request_data
176
  );
177
  },
178
+ 'webhook.endpoint.simulation-state' => static function ( ContainerInterface $container ) : SimulationStateEndpoint {
179
  $simulation = $container->get( 'webhook.status.simulation' );
180
 
181
  return new SimulationStateEndpoint(
183
  );
184
  },
185
 
186
+ 'webhook.module-url' => static function ( ContainerInterface $container ): string {
187
  return plugins_url(
188
  '/modules/ppcp-webhooks/',
189
  dirname( __FILE__, 3 ) . '/woocommerce-paypal-payments.php'
modules/ppcp-webhooks/src/Endpoint/{class-resubscribeendpoint.php → ResubscribeEndpoint.php} RENAMED
File without changes
modules/ppcp-webhooks/src/Endpoint/{class-simulateendpoint.php → SimulateEndpoint.php} RENAMED
File without changes
modules/ppcp-webhooks/src/Endpoint/{class-simulationstateendpoint.php → SimulationStateEndpoint.php} RENAMED
File without changes
modules/ppcp-webhooks/src/Handler/{class-checkoutorderapproved.php → CheckoutOrderApproved.php} RENAMED
@@ -50,7 +50,7 @@ class CheckoutOrderApproved implements RequestHandler {
50
  /**
51
  * The event types a handler handles.
52
  *
53
- * @return array
54
  */
55
  public function event_types(): array {
56
  return array(
50
  /**
51
  * The event types a handler handles.
52
  *
53
+ * @return string[]
54
  */
55
  public function event_types(): array {
56
  return array(
modules/ppcp-webhooks/src/Handler/{class-checkoutordercompleted.php → CheckoutOrderCompleted.php} RENAMED
@@ -39,7 +39,7 @@ class CheckoutOrderCompleted implements RequestHandler {
39
  /**
40
  * The event types a handler handles.
41
  *
42
- * @return array
43
  */
44
  public function event_types(): array {
45
  return array(
39
  /**
40
  * The event types a handler handles.
41
  *
42
+ * @return string[]
43
  */
44
  public function event_types(): array {
45
  return array(
modules/ppcp-webhooks/src/Handler/PaymentCaptureCompleted.php ADDED
@@ -0,0 +1,160 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Handles the Webhook PAYMENT.CAPTURE.COMPLETED
4
+ *
5
+ * @package WooCommerce\PayPalCommerce\Webhooks\Handler
6
+ */
7
+
8
+ declare(strict_types=1);
9
+
10
+ namespace WooCommerce\PayPalCommerce\Webhooks\Handler;
11
+
12
+ use Exception;
13
+ use WooCommerce\PayPalCommerce\ApiClient\Endpoint\OrderEndpoint;
14
+ use WooCommerce\PayPalCommerce\WcGateway\Gateway\PayPalGateway;
15
+ use Psr\Log\LoggerInterface;
16
+ use WooCommerce\PayPalCommerce\WcGateway\Processor\AuthorizedPaymentsProcessor;
17
+ use WooCommerce\PayPalCommerce\WcGateway\Processor\TransactionIdHandlingTrait;
18
+ use WP_REST_Response;
19
+
20
+ /**
21
+ * Class PaymentCaptureCompleted
22
+ */
23
+ class PaymentCaptureCompleted implements RequestHandler {
24
+
25
+ use PrefixTrait, TransactionIdHandlingTrait;
26
+
27
+ /**
28
+ * The logger.
29
+ *
30
+ * @var LoggerInterface
31
+ */
32
+ private $logger;
33
+
34
+ /**
35
+ * The order endpoint.
36
+ *
37
+ * @var OrderEndpoint
38
+ */
39
+ private $order_endpoint;
40
+
41
+ /**
42
+ * PaymentCaptureCompleted constructor.
43
+ *
44
+ * @param LoggerInterface $logger The logger.
45
+ * @param string $prefix The prefix.
46
+ * @param OrderEndpoint $order_endpoint The order endpoint.
47
+ */
48
+ public function __construct(
49
+ LoggerInterface $logger,
50
+ string $prefix,
51
+ OrderEndpoint $order_endpoint
52
+ ) {
53
+ $this->logger = $logger;
54
+ $this->prefix = $prefix;
55
+ $this->order_endpoint = $order_endpoint;
56
+ }
57
+
58
+ /**
59
+ * The event types a handler handles.
60
+ *
61
+ * @return string[]
62
+ */
63
+ public function event_types(): array {
64
+ return array( 'PAYMENT.CAPTURE.COMPLETED' );
65
+ }
66
+
67
+ /**
68
+ * Whether a handler is responsible for a given request or not.
69
+ *
70
+ * @param \WP_REST_Request $request The request.
71
+ *
72
+ * @return bool
73
+ */
74
+ public function responsible_for_request( \WP_REST_Request $request ): bool {
75
+ return in_array( $request['event_type'], $this->event_types(), true );
76
+ }
77
+
78
+ /**
79
+ * Responsible for handling the request.
80
+ *
81
+ * @param \WP_REST_Request $request The request.
82
+ *
83
+ * @return WP_REST_Response
84
+ */
85
+ public function handle_request( \WP_REST_Request $request ): WP_REST_Response {
86
+ $response = array( 'success' => false );
87
+
88
+ $webhook_id = (string) ( $request['id'] ?? '' );
89
+
90
+ $resource = $request['resource'];
91
+ if ( ! is_array( $resource ) ) {
92
+ $message = 'Resource data not found in webhook request.';
93
+ $this->logger->warning( $message, array( 'request' => $request ) );
94
+ $response['message'] = $message;
95
+ return new WP_REST_Response( $response );
96
+ }
97
+
98
+ $wc_order_id = isset( $resource['custom_id'] ) ?
99
+ $this->sanitize_custom_id( (string) $resource['custom_id'] ) : 0;
100
+ if ( ! $wc_order_id ) {
101
+ $message = sprintf( 'No order for webhook event %s was found.', $webhook_id );
102
+ $this->logger->warning( $message, array( 'request' => $request ) );
103
+ $response['message'] = $message;
104
+ return new WP_REST_Response( $response );
105
+ }
106
+
107
+ $wc_order = wc_get_order( $wc_order_id );
108
+ if ( ! is_a( $wc_order, \WC_Order::class ) ) {
109
+ $message = sprintf( 'No order for webhook event %s was found.', $webhook_id );
110
+ $this->logger->warning( $message, array( 'request' => $request ) );
111
+ $response['message'] = $message;
112
+ return new WP_REST_Response( $response );
113
+ }
114
+
115
+ if ( $wc_order->get_status() !== 'on-hold' ) {
116
+ $response['success'] = true;
117
+ return new WP_REST_Response( $response );
118
+ }
119
+ $wc_order->add_order_note(
120
+ __( 'Payment successfully captured.', 'woocommerce-paypal-payments' )
121
+ );
122
+
123
+ $wc_order->payment_complete();
124
+ $wc_order->update_meta_data( AuthorizedPaymentsProcessor::CAPTURED_META_KEY, 'true' );
125
+ $wc_order->save();
126
+ $this->logger->log(
127
+ 'info',
128
+ sprintf(
129
+ // translators: %s is the order ID.
130
+ __(
131
+ 'Order %s has been updated through PayPal',
132
+ 'woocommerce-paypal-payments'
133
+ ),
134
+ (string) $wc_order->get_id()
135
+ ),
136
+ array(
137
+ 'request' => $request,
138
+ 'order' => $wc_order,
139
+ )
140
+ );
141
+
142
+ $order_id = $resource['supplementary_data']['related_ids']['order_id'] ?? null;
143
+
144
+ if ( $order_id ) {
145
+ try {
146
+ $order = $this->order_endpoint->order( (string) $order_id );
147
+
148
+ $transaction_id = $this->get_paypal_order_transaction_id( $order );
149
+ if ( $transaction_id ) {
150
+ $this->update_transaction_id( $transaction_id, $wc_order, $this->logger );
151
+ }
152
+ } catch ( Exception $exception ) {
153
+ $this->logger->warning( 'Failed to get transaction ID: ' . $exception->getMessage() );
154
+ }
155
+ }
156
+
157
+ $response['success'] = true;
158
+ return new WP_REST_Response( $response );
159
+ }
160
+ }
modules/ppcp-webhooks/src/Handler/{class-paymentcapturerefunded.php → PaymentCaptureRefunded.php} RENAMED
@@ -39,7 +39,7 @@ class PaymentCaptureRefunded implements RequestHandler {
39
  /**
40
  * The event types a handler handles.
41
  *
42
- * @return array
43
  */
44
  public function event_types(): array {
45
  return array( 'PAYMENT.CAPTURE.REFUNDED' );
39
  /**
40
  * The event types a handler handles.
41
  *
42
+ * @return string[]
43
  */
44
  public function event_types(): array {
45
  return array( 'PAYMENT.CAPTURE.REFUNDED' );
modules/ppcp-webhooks/src/Handler/{class-paymentcapturereversed.php → PaymentCaptureReversed.php} RENAMED
@@ -42,7 +42,7 @@ class PaymentCaptureReversed implements RequestHandler {
42
  /**
43
  * The event types a handler handles.
44
  *
45
- * @return array
46
  */
47
  public function event_types(): array {
48
  return array(
42
  /**
43
  * The event types a handler handles.
44
  *
45
+ * @return string[]
46
  */
47
  public function event_types(): array {
48
  return array(
modules/ppcp-webhooks/src/Handler/{class-prefixtrait.php → PrefixTrait.php} RENAMED
File without changes
modules/ppcp-webhooks/src/Handler/{class-requesthandler.php → RequestHandler.php} RENAMED
@@ -17,7 +17,7 @@ interface RequestHandler {
17
  /**
18
  * The event types a handler handles.
19
  *
20
- * @return array
21
  */
22
  public function event_types(): array;
23
 
17
  /**
18
  * The event types a handler handles.
19
  *
20
+ * @return string[]
21
  */
22
  public function event_types(): array;
23
 
modules/ppcp-webhooks/src/Handler/class-paymentcapturecompleted.php DELETED
@@ -1,141 +0,0 @@
1
- <?php
2
- /**
3
- * Handles the Webhook PAYMENT.CAPTURE.COMPLETED
4
- *
5
- * @package WooCommerce\PayPalCommerce\Webhooks\Handler
6
- */
7
-
8
- declare(strict_types=1);
9
-
10
- namespace WooCommerce\PayPalCommerce\Webhooks\Handler;
11
-
12
- use WooCommerce\PayPalCommerce\WcGateway\Gateway\PayPalGateway;
13
- use Psr\Log\LoggerInterface;
14
-
15
- /**
16
- * Class PaymentCaptureCompleted
17
- */
18
- class PaymentCaptureCompleted implements RequestHandler {
19
-
20
- use PrefixTrait;
21
-
22
- /**
23
- * The logger.
24
- *
25
- * @var LoggerInterface
26
- */
27
- private $logger;
28
-
29
- /**
30
- * PaymentCaptureCompleted constructor.
31
- *
32
- * @param LoggerInterface $logger The logger.
33
- * @param string $prefix The prefix.
34
- */
35
- public function __construct( LoggerInterface $logger, string $prefix ) {
36
- $this->logger = $logger;
37
- $this->prefix = $prefix;
38
- }
39
-
40
- /**
41
- * The event types a handler handles.
42
- *
43
- * @return array
44
- */
45
- public function event_types(): array {
46
- return array( 'PAYMENT.CAPTURE.COMPLETED' );
47
- }
48
-
49
- /**
50
- * Whether a handler is responsible for a given request or not.
51
- *
52
- * @param \WP_REST_Request $request The request.
53
- *
54
- * @return bool
55
- */
56
- public function responsible_for_request( \WP_REST_Request $request ): bool {
57
- return in_array( $request['event_type'], $this->event_types(), true );
58
- }
59
-
60
- /**
61
- * Responsible for handling the request.
62
- *
63
- * @param \WP_REST_Request $request The request.
64
- *
65
- * @return \WP_REST_Response
66
- */
67
- public function handle_request( \WP_REST_Request $request ): \WP_REST_Response {
68
- $response = array( 'success' => false );
69
- $order_id = isset( $request['resource']['custom_id'] ) ?
70
- $this->sanitize_custom_id( $request['resource']['custom_id'] ) : 0;
71
- if ( ! $order_id ) {
72
- $message = sprintf(
73
- // translators: %s is the PayPal webhook Id.
74
- __(
75
- 'No order for webhook event %s was found.',
76
- 'woocommerce-paypal-payments'
77
- ),
78
- isset( $request['id'] ) ? $request['id'] : ''
79
- );
80
- $this->logger->log(
81
- 'warning',
82
- $message,
83
- array(
84
- 'request' => $request,
85
- )
86
- );
87
- $response['message'] = $message;
88
- return rest_ensure_response( $response );
89
- }
90
- $wc_order = wc_get_order( $order_id );
91
-
92
- if ( ! is_a( $wc_order, \WC_Order::class ) ) {
93
- $message = sprintf(
94
- // translators: %s is the PayPal webhook Id.
95
- __(
96
- 'No order for webhook event %s was found.',
97
- 'woocommerce-paypal-payments'
98
- ),
99
- isset( $request['id'] ) ? $request['id'] : ''
100
- );
101
- $this->logger->log(
102
- 'warning',
103
- $message,
104
- array(
105
- 'request' => $request,
106
- )
107
- );
108
- $response['message'] = $message;
109
- return rest_ensure_response( $response );
110
- }
111
-
112
- if ( $wc_order->get_status() !== 'on-hold' ) {
113
- $response['success'] = true;
114
- return rest_ensure_response( $response );
115
- }
116
- $wc_order->add_order_note(
117
- __( 'Payment successfully captured.', 'woocommerce-paypal-payments' )
118
- );
119
-
120
- $wc_order->payment_complete();
121
- $wc_order->update_meta_data( PayPalGateway::CAPTURED_META_KEY, 'true' );
122
- $wc_order->save();
123
- $this->logger->log(
124
- 'info',
125
- sprintf(
126
- // translators: %s is the order ID.
127
- __(
128
- 'Order %s has been updated through PayPal',
129
- 'woocommerce-paypal-payments'
130
- ),
131
- (string) $wc_order->get_id()
132
- ),
133
- array(
134
- 'request' => $request,
135
- 'order' => $wc_order,
136
- )
137
- );
138
- $response['success'] = true;
139
- return rest_ensure_response( $response );
140
- }
141
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
modules/ppcp-webhooks/src/{class-incomingwebhookendpoint.php → IncomingWebhookEndpoint.php} RENAMED
@@ -230,13 +230,25 @@ class IncomingWebhookEndpoint {
230
  * @return string
231
  */
232
  public function url(): string {
233
- return rest_url( self::NAMESPACE . '/' . self::ROUTE );
 
 
 
 
 
 
 
 
 
 
 
 
234
  }
235
 
236
  /**
237
  * Returns the event types, which are handled by the endpoint.
238
  *
239
- * @return array
240
  */
241
  public function handled_event_types(): array {
242
  $event_types = array();
230
  * @return string
231
  */
232
  public function url(): string {
233
+ $url = rest_url( self::NAMESPACE . '/' . self::ROUTE );
234
+
235
+ $url = str_replace( 'http://', 'https://', $url );
236
+
237
+ $ngrok_host = getenv( 'NGROK_HOST' );
238
+ if ( $ngrok_host ) {
239
+ $host = wp_parse_url( $url, PHP_URL_HOST );
240
+ if ( $host ) {
241
+ $url = str_replace( $host, $ngrok_host, $url );
242
+ }
243
+ }
244
+
245
+ return $url;
246
  }
247
 
248
  /**
249
  * Returns the event types, which are handled by the endpoint.
250
  *
251
+ * @return string[]
252
  */
253
  public function handled_event_types(): array {
254
  $event_types = array();
modules/ppcp-webhooks/src/Status/Assets/{class-webhooksstatuspageassets.php → WebhooksStatusPageAssets.php} RENAMED
@@ -7,10 +7,8 @@
7
 
8
  declare(strict_types=1);
9
 
10
- namespace WooCommerce\PayPalCommerce\WcGateway\Assets;
11
 
12
- use WooCommerce\PayPalCommerce\ApiClient\Authentication\Bearer;
13
- use WooCommerce\PayPalCommerce\ApiClient\Exception\RuntimeException;
14
  use WooCommerce\PayPalCommerce\Webhooks\Endpoint\ResubscribeEndpoint;
15
  use WooCommerce\PayPalCommerce\Webhooks\Endpoint\SimulateEndpoint;
16
  use WooCommerce\PayPalCommerce\Webhooks\Endpoint\SimulationStateEndpoint;
@@ -49,14 +47,14 @@ class WebhooksStatusPageAssets {
49
  'ppcp-webhooks-status-page-style',
50
  $this->module_url . '/assets/css/status-page.css',
51
  array(),
52
- 1
53
  );
54
 
55
  wp_register_script(
56
  'ppcp-webhooks-status-page',
57
  $this->module_url . '/assets/js/status-page.js',
58
  array(),
59
- 1,
60
  true
61
  );
62
 
7
 
8
  declare(strict_types=1);
9
 
10
+ namespace WooCommerce\PayPalCommerce\Webhooks\Status\Assets;
11
 
 
 
12
  use WooCommerce\PayPalCommerce\Webhooks\Endpoint\ResubscribeEndpoint;
13
  use WooCommerce\PayPalCommerce\Webhooks\Endpoint\SimulateEndpoint;
14
  use WooCommerce\PayPalCommerce\Webhooks\Endpoint\SimulationStateEndpoint;
47
  'ppcp-webhooks-status-page-style',
48
  $this->module_url . '/assets/css/status-page.css',
49
  array(),
50
+ '1'
51
  );
52
 
53
  wp_register_script(
54
  'ppcp-webhooks-status-page',
55
  $this->module_url . '/assets/js/status-page.js',
56
  array(),
57
+ '1',
58
  true
59
  );
60
 
modules/ppcp-webhooks/src/Status/{class-webhooksimulation.php → WebhookSimulation.php} RENAMED
@@ -78,7 +78,7 @@ class WebhookSimulation {
78
  *
79
  * @throws Exception If failed to start simulation.
80
  */
81
- public function start() {
82
  if ( ! $this->webhook ) {
83
  throw new Exception( 'Webhooks not registered' );
84
  }
78
  *
79
  * @throws Exception If failed to start simulation.
80
  */
81
+ public function start(): void {
82
  if ( ! $this->webhook ) {
83
  throw new Exception( 'Webhooks not registered' );
84
  }
modules/ppcp-webhooks/src/Status/{class-webhooksstatuspage.php → WebhooksStatusPage.php} RENAMED
File without changes
modules/ppcp-webhooks/src/{class-webhookmodule.php → WebhookModule.php} RENAMED
@@ -15,10 +15,10 @@ use Exception;
15
  use Interop\Container\ServiceProviderInterface;
16
  use Psr\Container\ContainerInterface;
17
  use Psr\Log\LoggerInterface;
18
- use WooCommerce\PayPalCommerce\WcGateway\Assets\WebhooksStatusPageAssets;
19
  use WooCommerce\PayPalCommerce\Webhooks\Endpoint\ResubscribeEndpoint;
20
  use WooCommerce\PayPalCommerce\Webhooks\Endpoint\SimulateEndpoint;
21
  use WooCommerce\PayPalCommerce\Webhooks\Endpoint\SimulationStateEndpoint;
 
22
  use WooCommerce\PayPalCommerce\Webhooks\Status\WebhooksStatusPage;
23
 
24
  /**
@@ -27,9 +27,7 @@ use WooCommerce\PayPalCommerce\Webhooks\Status\WebhooksStatusPage;
27
  class WebhookModule implements ModuleInterface {
28
 
29
  /**
30
- * Setup the Webhook module.
31
- *
32
- * @return ServiceProviderInterface
33
  */
34
  public function setup(): ServiceProviderInterface {
35
  return new ServiceProvider(
@@ -39,9 +37,7 @@ class WebhookModule implements ModuleInterface {
39
  }
40
 
41
  /**
42
- * Run the Webhook module.
43
- *
44
- * @param ContainerInterface|null $container The Container.
45
  */
46
  public function run( ContainerInterface $container ): void {
47
  $logger = $container->get( 'woocommerce.logger.woocommerce' );
15
  use Interop\Container\ServiceProviderInterface;
16
  use Psr\Container\ContainerInterface;
17
  use Psr\Log\LoggerInterface;
 
18
  use WooCommerce\PayPalCommerce\Webhooks\Endpoint\ResubscribeEndpoint;
19
  use WooCommerce\PayPalCommerce\Webhooks\Endpoint\SimulateEndpoint;
20
  use WooCommerce\PayPalCommerce\Webhooks\Endpoint\SimulationStateEndpoint;
21
+ use WooCommerce\PayPalCommerce\Webhooks\Status\Assets\WebhooksStatusPageAssets;
22
  use WooCommerce\PayPalCommerce\Webhooks\Status\WebhooksStatusPage;
23
 
24
  /**
27
  class WebhookModule implements ModuleInterface {
28
 
29
  /**
30
+ * {@inheritDoc}
 
 
31
  */
32
  public function setup(): ServiceProviderInterface {
33
  return new ServiceProvider(
37
  }
38
 
39
  /**
40
+ * {@inheritDoc}
 
 
41
  */
42
  public function run( ContainerInterface $container ): void {
43
  $logger = $container->get( 'woocommerce.logger.woocommerce' );
modules/ppcp-webhooks/src/{class-webhookregistrar.php → WebhookRegistrar.php} RENAMED
File without changes
modules/woocommerce-logging/composer.json ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "woocommerce/woocommerce-logging",
3
+ "type": "dhii-mod",
4
+ "description": "WC logging module for PPCP",
5
+ "license": "GPL-2.0",
6
+ "require": {
7
+ "php": "^7.1 | ^8.0",
8
+ "dhii/module-interface": "^0.3.0-alpha1"
9
+ },
10
+ "autoload": {
11
+ "psr-4": {
12
+ "WooCommerce\\WooCommerce\\Logging\\": "src"
13
+ }
14
+ },
15
+ "minimum-stability": "dev",
16
+ "prefer-stable": true
17
+ }
modules/woocommerce-logging/src/Logger/{class-nulllogger.php → NullLogger.php} RENAMED
File without changes
modules/woocommerce-logging/src/Logger/{class-woocommercelogger.php → WooCommerceLogger.php} RENAMED
File without changes
modules/woocommerce-logging/src/{class-woocommerceloggingmodule.php → WooCommerceLoggingModule.php} RENAMED
@@ -20,9 +20,7 @@ use Psr\Container\ContainerInterface;
20
  class WooCommerceLoggingModule implements ModuleInterface {
21
 
22
  /**
23
- * Setup the module.
24
- *
25
- * @return ServiceProviderInterface
26
  */
27
  public function setup(): ServiceProviderInterface {
28
  return new ServiceProvider(
@@ -32,11 +30,9 @@ class WooCommerceLoggingModule implements ModuleInterface {
32
  }
33
 
34
  /**
35
- * Run the module.
36
- *
37
- * @param ContainerInterface $container The container.
38
  */
39
- public function run( ContainerInterface $container ): void {
40
  }
41
 
42
 
20
  class WooCommerceLoggingModule implements ModuleInterface {
21
 
22
  /**
23
+ * {@inheritDoc}
 
 
24
  */
25
  public function setup(): ServiceProviderInterface {
26
  return new ServiceProvider(
30
  }
31
 
32
  /**
33
+ * {@inheritDoc}
 
 
34
  */
35
+ public function run( ContainerInterface $c ): void {
36
  }
37
 
38
 
psalm-baseline.xml ADDED
@@ -0,0 +1,921 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <files psalm-version="4.11.2@6fba5eb554f9507b72932f9c75533d8af593688d">
3
+ <file src="modules/ppcp-api-client/services.php">
4
+ <UndefinedConstant occurrences="2">
5
+ <code>PAYPAL_API_URL</code>
6
+ <code>PAYPAL_API_URL</code>
7
+ </UndefinedConstant>
8
+ </file>
9
+ <file src="modules/ppcp-api-client/src/Authentication/PayPalBearer.php">
10
+ <UndefinedMethod occurrences="1">
11
+ <code>$response</code>
12
+ </UndefinedMethod>
13
+ </file>
14
+ <file src="modules/ppcp-api-client/src/Endpoint/IdentityToken.php">
15
+ <InvalidOperand occurrences="1">
16
+ <code>$customer_id</code>
17
+ </InvalidOperand>
18
+ <UndefinedMethod occurrences="1">
19
+ <code>$response</code>
20
+ </UndefinedMethod>
21
+ </file>
22
+ <file src="modules/ppcp-api-client/src/Endpoint/LoginSeller.php">
23
+ <UndefinedMethod occurrences="2">
24
+ <code>$response</code>
25
+ <code>$response</code>
26
+ </UndefinedMethod>
27
+ </file>
28
+ <file src="modules/ppcp-api-client/src/Endpoint/OrderEndpoint.php">
29
+ <PossiblyNullReference occurrences="2">
30
+ <code>authorizations</code>
31
+ <code>captures</code>
32
+ </PossiblyNullReference>
33
+ <RedundantCondition occurrences="2">
34
+ <code>$order-&gt;purchase_units()[0]-&gt;payments()-&gt;authorizations()[0]-&gt;status()</code>
35
+ <code>$order-&gt;purchase_units()[0]-&gt;payments()-&gt;captures()[0]-&gt;status()</code>
36
+ </RedundantCondition>
37
+ <TypeDoesNotContainNull occurrences="2">
38
+ <code>null</code>
39
+ <code>null</code>
40
+ </TypeDoesNotContainNull>
41
+ <UndefinedMethod occurrences="5">
42
+ <code>$response</code>
43
+ <code>$response</code>
44
+ <code>$response</code>
45
+ <code>$response</code>
46
+ <code>$response</code>
47
+ </UndefinedMethod>
48
+ </file>
49
+ <file src="modules/ppcp-api-client/src/Endpoint/PartnerReferrals.php">
50
+ <UndefinedMethod occurrences="1">
51
+ <code>$response</code>
52
+ </UndefinedMethod>
53
+ </file>
54
+ <file src="modules/ppcp-api-client/src/Endpoint/PaymentTokenEndpoint.php">
55
+ <InvalidOperand occurrences="1">
56
+ <code>$id</code>
57
+ </InvalidOperand>
58
+ <UndefinedMethod occurrences="1">
59
+ <code>$response</code>
60
+ </UndefinedMethod>
61
+ </file>
62
+ <file src="modules/ppcp-api-client/src/Endpoint/PaymentsEndpoint.php">
63
+ <UndefinedMethod occurrences="3">
64
+ <code>$response</code>
65
+ <code>$response</code>
66
+ <code>$response</code>
67
+ </UndefinedMethod>
68
+ </file>
69
+ <file src="modules/ppcp-api-client/src/Endpoint/RequestTrait.php">
70
+ <PossiblyInvalidOperand occurrences="3">
71
+ <code>wc_print_r( $args['body'], true )</code>
72
+ <code>wc_print_r( $response['body'], true )</code>
73
+ <code>wc_print_r( $response['response'], true )</code>
74
+ </PossiblyInvalidOperand>
75
+ <TooManyArguments occurrences="1">
76
+ <code>apply_filters( 'ppcp_request_args', $args, $url )</code>
77
+ </TooManyArguments>
78
+ </file>
79
+ <file src="modules/ppcp-api-client/src/Endpoint/WebhookEndpoint.php">
80
+ <PossiblyFalseArgument occurrences="1">
81
+ <code>file_get_contents( 'php://input' )</code>
82
+ </PossiblyFalseArgument>
83
+ <UndefinedMethod occurrences="4">
84
+ <code>$response</code>
85
+ <code>$response</code>
86
+ <code>$response</code>
87
+ <code>$response</code>
88
+ </UndefinedMethod>
89
+ </file>
90
+ <file src="modules/ppcp-api-client/src/Entity/Amount.php">
91
+ <PossiblyNullPropertyAssignmentValue occurrences="1">
92
+ <code>$breakdown</code>
93
+ </PossiblyNullPropertyAssignmentValue>
94
+ <PossiblyNullReference occurrences="2">
95
+ <code>to_array</code>
96
+ <code>to_array</code>
97
+ </PossiblyNullReference>
98
+ </file>
99
+ <file src="modules/ppcp-api-client/src/Entity/Item.php">
100
+ <PossiblyNullReference occurrences="1">
101
+ <code>to_array</code>
102
+ </PossiblyNullReference>
103
+ </file>
104
+ <file src="modules/ppcp-api-client/src/Entity/Order.php">
105
+ <PossiblyNullReference occurrences="5">
106
+ <code>format</code>
107
+ <code>format</code>
108
+ <code>to_array</code>
109
+ <code>to_array</code>
110
+ <code>to_array</code>
111
+ </PossiblyNullReference>
112
+ <RedundantConditionGivenDocblockType occurrences="1">
113
+ <code>return is_a( $unit, PurchaseUnit::class );</code>
114
+ </RedundantConditionGivenDocblockType>
115
+ </file>
116
+ <file src="modules/ppcp-api-client/src/Entity/Payer.php">
117
+ <PossiblyNullPropertyAssignmentValue occurrences="1">
118
+ <code>$address</code>
119
+ </PossiblyNullPropertyAssignmentValue>
120
+ <PossiblyNullReference occurrences="4">
121
+ <code>country_code</code>
122
+ <code>format</code>
123
+ <code>to_array</code>
124
+ <code>to_array</code>
125
+ </PossiblyNullReference>
126
+ </file>
127
+ <file src="modules/ppcp-api-client/src/Entity/PaymentSource.php">
128
+ <PossiblyNullReference occurrences="2">
129
+ <code>to_array</code>
130
+ <code>to_array</code>
131
+ </PossiblyNullReference>
132
+ </file>
133
+ <file src="modules/ppcp-api-client/src/Entity/PaymentSourceCard.php">
134
+ <PossiblyNullReference occurrences="1">
135
+ <code>to_array</code>
136
+ </PossiblyNullReference>
137
+ </file>
138
+ <file src="modules/ppcp-api-client/src/Entity/PurchaseUnit.php">
139
+ <PossiblyNullReference occurrences="3">
140
+ <code>to_array</code>
141
+ <code>to_array</code>
142
+ <code>to_array</code>
143
+ </PossiblyNullReference>
144
+ </file>
145
+ <file src="modules/ppcp-api-client/src/Entity/Refund.php">
146
+ <PossiblyNullReference occurrences="1">
147
+ <code>to_array</code>
148
+ </PossiblyNullReference>
149
+ </file>
150
+ <file src="modules/ppcp-api-client/src/Entity/SellerStatus.php">
151
+ <RedundantConditionGivenDocblockType occurrences="1">
152
+ <code>is_a( $product, SellerStatusProduct::class )</code>
153
+ </RedundantConditionGivenDocblockType>
154
+ </file>
155
+ <file src="modules/ppcp-api-client/src/Entity/SellerStatusProduct.php">
156
+ <RedundantConditionGivenDocblockType occurrences="1">
157
+ <code>is_string( $capability )</code>
158
+ </RedundantConditionGivenDocblockType>
159
+ </file>
160
+ <file src="modules/ppcp-api-client/src/Entity/Token.php">
161
+ <FalsableReturnStatement occurrences="1">
162
+ <code>wp_json_encode( $this-&gt;json )</code>
163
+ </FalsableReturnStatement>
164
+ <InvalidFalsableReturnType occurrences="1">
165
+ <code>string</code>
166
+ </InvalidFalsableReturnType>
167
+ <LessSpecificReturnStatement occurrences="1">
168
+ <code>new Token( $json )</code>
169
+ </LessSpecificReturnStatement>
170
+ <MoreSpecificReturnType occurrences="1">
171
+ <code>static</code>
172
+ </MoreSpecificReturnType>
173
+ <PropertyNotSetInConstructor occurrences="1">
174
+ <code>$created</code>
175
+ </PropertyNotSetInConstructor>
176
+ </file>
177
+ <file src="modules/ppcp-api-client/src/Entity/Webhook.php">
178
+ <InvalidPropertyAssignmentValue occurrences="1">
179
+ <code>$event_types</code>
180
+ </InvalidPropertyAssignmentValue>
181
+ <InvalidPropertyFetch occurrences="1">
182
+ <code>$event-&gt;name</code>
183
+ </InvalidPropertyFetch>
184
+ <InvalidReturnStatement occurrences="1">
185
+ <code>$this-&gt;event_types</code>
186
+ </InvalidReturnStatement>
187
+ <InvalidReturnType occurrences="1">
188
+ <code>stdClass[]</code>
189
+ </InvalidReturnType>
190
+ </file>
191
+ <file src="modules/ppcp-api-client/src/Exception/PayPalApiException.php">
192
+ <PossiblyNullArgument occurrences="1">
193
+ <code>$this-&gt;status_code</code>
194
+ </PossiblyNullArgument>
195
+ <UninitializedProperty occurrences="1">
196
+ <code>$this-&gt;status_code</code>
197
+ </UninitializedProperty>
198
+ </file>
199
+ <file src="modules/ppcp-api-client/src/Factory/AmountFactory.php">
200
+ <InvalidOperand occurrences="4">
201
+ <code>$cart-&gt;get_cart_contents_total() + $cart-&gt;get_discount_total() + $total_fees_amount</code>
202
+ <code>$item-&gt;quantity() * $item-&gt;tax()-&gt;value()</code>
203
+ <code>$item-&gt;quantity() * $item-&gt;unit_amount()-&gt;value()</code>
204
+ <code>$total_fees_amount += (float) $fee-&gt;amount</code>
205
+ </InvalidOperand>
206
+ <PossiblyInvalidIterator occurrences="1">
207
+ <code>WC()-&gt;session-&gt;get( 'ppcp_fees' )</code>
208
+ </PossiblyInvalidIterator>
209
+ <PossiblyNullReference occurrences="1">
210
+ <code>value</code>
211
+ </PossiblyNullReference>
212
+ <RedundantCast occurrences="1">
213
+ <code>(float) $item_total</code>
214
+ </RedundantCast>
215
+ <RedundantCastGivenDocblockType occurrences="8">
216
+ <code>(float) $cart-&gt;get_cart_contents_tax()</code>
217
+ <code>(float) $cart-&gt;get_discount_tax()</code>
218
+ <code>(float) $cart-&gt;get_discount_total()</code>
219
+ <code>(float) $cart-&gt;get_shipping_total()</code>
220
+ <code>(float) $cart-&gt;get_total( 'numeric' )</code>
221
+ <code>(float) $order-&gt;get_total()</code>
222
+ <code>(float) $order-&gt;get_total_discount( false )</code>
223
+ <code>(float) $order-&gt;get_total_discount( false )</code>
224
+ </RedundantCastGivenDocblockType>
225
+ </file>
226
+ <file src="modules/ppcp-api-client/src/Factory/ItemFactory.php">
227
+ <ArgumentTypeCoercion occurrences="1"/>
228
+ <PossiblyInvalidArgument occurrences="1">
229
+ <code>$fees_from_session</code>
230
+ </PossiblyInvalidArgument>
231
+ <RedundantCastGivenDocblockType occurrences="3">
232
+ <code>(float) $order-&gt;get_item_subtotal( $item, false )</code>
233
+ <code>(float) $order-&gt;get_item_subtotal( $item, true )</code>
234
+ <code>(int) $item-&gt;get_quantity()</code>
235
+ </RedundantCastGivenDocblockType>
236
+ </file>
237
+ <file src="modules/ppcp-api-client/src/Factory/PayerFactory.php">
238
+ <PossiblyNullArgument occurrences="2">
239
+ <code>$national_number</code>
240
+ <code>$national_number</code>
241
+ </PossiblyNullArgument>
242
+ <TooManyArguments occurrences="1">
243
+ <code>from_wc_order</code>
244
+ </TooManyArguments>
245
+ </file>
246
+ <file src="modules/ppcp-api-client/src/Factory/PurchaseUnitFactory.php">
247
+ <RedundantConditionGivenDocblockType occurrences="1">
248
+ <code>$this-&gt;shipping_needed( ... array_values( $items ) ) &amp;&amp; is_a( $customer, \WC_Customer::class )</code>
249
+ </RedundantConditionGivenDocblockType>
250
+ <TooManyArguments occurrences="1"/>
251
+ </file>
252
+ <file src="modules/ppcp-api-client/src/Factory/WebhookEventFactory.php">
253
+ <RedundantCondition occurrences="5">
254
+ <code>(object) $data-&gt;resource</code>
255
+ <code>(string) $data-&gt;event_version</code>
256
+ <code>(string) $data-&gt;resource_type</code>
257
+ <code>(string) $data-&gt;resource_version</code>
258
+ <code>(string) $data-&gt;summary</code>
259
+ </RedundantCondition>
260
+ <TypeDoesNotContainNull occurrences="5">
261
+ <code>''</code>
262
+ <code>''</code>
263
+ <code>''</code>
264
+ <code>''</code>
265
+ <code>new stdClass()</code>
266
+ </TypeDoesNotContainNull>
267
+ </file>
268
+ <file src="modules/ppcp-api-client/src/Helper/Cache.php">
269
+ <MissingReturnType occurrences="1">
270
+ <code>delete</code>
271
+ </MissingReturnType>
272
+ <RedundantCastGivenDocblockType occurrences="1">
273
+ <code>(bool) set_transient( $this-&gt;prefix . $key, $value )</code>
274
+ </RedundantCastGivenDocblockType>
275
+ </file>
276
+ <file src="modules/ppcp-api-client/src/Repository/ApplicationContextRepository.php">
277
+ <PossiblyFalseArgument occurrences="1">
278
+ <code>strrpos( $locale, '-' )</code>
279
+ </PossiblyFalseArgument>
280
+ <RedundantCastGivenDocblockType occurrences="2">
281
+ <code>(string) home_url( \WC_AJAX::get_endpoint( ReturnUrlEndpoint::ENDPOINT ) )</code>
282
+ <code>(string) wc_get_checkout_url()</code>
283
+ </RedundantCastGivenDocblockType>
284
+ </file>
285
+ <file src="modules/ppcp-api-client/src/Repository/PayPalRequestIdRepository.php">
286
+ <UndefinedConstant occurrences="1">
287
+ <code>DAY_IN_SECONDS</code>
288
+ </UndefinedConstant>
289
+ </file>
290
+ <file src="modules/ppcp-button/services.php">
291
+ <UndefinedConstant occurrences="2">
292
+ <code>CONNECT_WOO_CLIENT_ID</code>
293
+ <code>CONNECT_WOO_SANDBOX_CLIENT_ID</code>
294
+ </UndefinedConstant>
295
+ </file>
296
+ <file src="modules/ppcp-button/src/Assets/SmartButton.php">
297
+ <InvalidScalarArgument occurrences="1">
298
+ <code>1</code>
299
+ </InvalidScalarArgument>
300
+ <MissingClosureParamType occurrences="2">
301
+ <code>$default_fields</code>
302
+ <code>$id</code>
303
+ </MissingClosureParamType>
304
+ <MissingClosureReturnType occurrences="1">
305
+ <code>function ( $default_fields, $id ) {</code>
306
+ </MissingClosureReturnType>
307
+ <MissingReturnType occurrences="3">
308
+ <code>button_renderer</code>
309
+ <code>dcc_renderer</code>
310
+ <code>message_renderer</code>
311
+ </MissingReturnType>
312
+ <UndefinedConstant occurrences="1">
313
+ <code>PAYPAL_INTEGRATION_DATE</code>
314
+ </UndefinedConstant>
315
+ </file>
316
+ <file src="modules/ppcp-button/src/ButtonModule.php">
317
+ <MissingClosureParamType occurrences="1">
318
+ <code>$value</code>
319
+ </MissingClosureParamType>
320
+ <MissingReturnType occurrences="1">
321
+ <code>register_ajax_endpoints</code>
322
+ </MissingReturnType>
323
+ </file>
324
+ <file src="modules/ppcp-button/src/Endpoint/ApproveOrderEndpoint.php">
325
+ <PossiblyNullReference occurrences="3">
326
+ <code>brand</code>
327
+ <code>card</code>
328
+ <code>card</code>
329
+ </PossiblyNullReference>
330
+ </file>
331
+ <file src="modules/ppcp-button/src/Endpoint/CreateOrderEndpoint.php">
332
+ <MissingReturnType occurrences="2">
333
+ <code>set_bn_code</code>
334
+ <code>validate_paynow_form</code>
335
+ </MissingReturnType>
336
+ <PossiblyFalseArgument occurrences="1">
337
+ <code>wp_json_encode( $data['payer'] )</code>
338
+ </PossiblyFalseArgument>
339
+ <PossiblyInvalidArgument occurrences="3">
340
+ <code>$wc_order</code>
341
+ <code>$wc_order</code>
342
+ <code>$wc_order</code>
343
+ </PossiblyInvalidArgument>
344
+ <PossiblyNullArgument occurrences="2">
345
+ <code>$number</code>
346
+ <code>$wc_order</code>
347
+ </PossiblyNullArgument>
348
+ <PropertyNotSetInConstructor occurrences="2">
349
+ <code>$parsed_request_data</code>
350
+ <code>$purchase_units</code>
351
+ </PropertyNotSetInConstructor>
352
+ </file>
353
+ <file src="modules/ppcp-button/src/Endpoint/RequestData.php">
354
+ <MissingReturnType occurrences="2">
355
+ <code>dequeue_nonce_fix</code>
356
+ <code>enqueue_nonce_fix</code>
357
+ </MissingReturnType>
358
+ <PossiblyFalseArgument occurrences="1">
359
+ <code>$stream</code>
360
+ </PossiblyFalseArgument>
361
+ <PossiblyInvalidArgument occurrences="1">
362
+ <code>$json</code>
363
+ </PossiblyInvalidArgument>
364
+ <RedundantCast occurrences="2">
365
+ <code>(array) $assoc_array</code>
366
+ <code>(string) $raw_key</code>
367
+ </RedundantCast>
368
+ </file>
369
+ <file src="modules/ppcp-button/src/Helper/EarlyOrderHandler.php">
370
+ <MissingClosureParamType occurrences="1">
371
+ <code>$order_id</code>
372
+ </MissingClosureParamType>
373
+ <PossiblyInvalidArgument occurrences="2">
374
+ <code>$wc_order</code>
375
+ <code>wp_unslash( $_REQUEST['ppcp-resume-order'] )</code>
376
+ </PossiblyInvalidArgument>
377
+ <PossiblyInvalidMethodCall occurrences="3">
378
+ <code>save_meta_data</code>
379
+ <code>update_meta_data</code>
380
+ <code>update_meta_data</code>
381
+ </PossiblyInvalidMethodCall>
382
+ <RedundantCast occurrences="1">
383
+ <code>(int) $this-&gt;sanitize_custom_id( $purchase_unit-&gt;custom_id() )</code>
384
+ </RedundantCast>
385
+ </file>
386
+ <file src="modules/ppcp-button/src/Helper/ThreeDSecure.php">
387
+ <PossiblyInvalidOperand occurrences="1">
388
+ <code>wc_print_r( $result-&gt;to_array(), true )</code>
389
+ </PossiblyInvalidOperand>
390
+ <PossiblyNullReference occurrences="6">
391
+ <code>authentication_result</code>
392
+ <code>authentication_result</code>
393
+ <code>card</code>
394
+ <code>card</code>
395
+ <code>card</code>
396
+ <code>to_array</code>
397
+ </PossiblyNullReference>
398
+ </file>
399
+ <file src="modules/ppcp-compat/services.php">
400
+ <MissingClosureParamType occurrences="2">
401
+ <code>$container</code>
402
+ <code>$container</code>
403
+ </MissingClosureParamType>
404
+ </file>
405
+ <file src="modules/ppcp-compat/src/CompatModule.php">
406
+ <PossiblyNullReference occurrences="1">
407
+ <code>get</code>
408
+ </PossiblyNullReference>
409
+ </file>
410
+ <file src="modules/ppcp-compat/src/PPEC/DeactivateNote.php">
411
+ <UndefinedTrait occurrences="1">
412
+ <code>NoteTraits</code>
413
+ </UndefinedTrait>
414
+ </file>
415
+ <file src="modules/ppcp-compat/src/PPEC/SettingsImporter.php">
416
+ <UndefinedFunction occurrences="1">
417
+ <code>wc_gateway_ppec()</code>
418
+ </UndefinedFunction>
419
+ </file>
420
+ <file src="modules/ppcp-compat/src/PPEC/SubscriptionsHandler.php">
421
+ <PossiblyInvalidMethodCall occurrences="1">
422
+ <code>get_payment_method</code>
423
+ </PossiblyInvalidMethodCall>
424
+ <PossiblyNullPropertyFetch occurrences="2">
425
+ <code>get_current_screen()-&gt;id</code>
426
+ <code>get_current_screen()-&gt;id</code>
427
+ </PossiblyNullPropertyFetch>
428
+ <PossiblyUndefinedMethod occurrences="1">
429
+ <code>get_payment_method</code>
430
+ </PossiblyUndefinedMethod>
431
+ <UndefinedFunction occurrences="5">
432
+ <code>wcs_get_subscription( absint( $_GET['subscription_id'] ) )</code>
433
+ <code>wcs_get_subscription( absint( get_query_var( 'order-pay' ) ) )</code>
434
+ <code>wcs_get_subscription( absint( get_query_var( 'view-subscription' ) ) )</code>
435
+ <code>wcs_is_view_subscription_page()</code>
436
+ <code>wcs_order_contains_renewal( $order )</code>
437
+ </UndefinedFunction>
438
+ </file>
439
+ <file src="modules/ppcp-onboarding/services.php">
440
+ <MissingClosureParamType occurrences="1">
441
+ <code>$container</code>
442
+ </MissingClosureParamType>
443
+ <UndefinedConstant occurrences="10">
444
+ <code>CONNECT_WOO_MERCHANT_ID</code>
445
+ <code>CONNECT_WOO_SANDBOX_MERCHANT_ID</code>
446
+ <code>CONNECT_WOO_SANDBOX_URL</code>
447
+ <code>CONNECT_WOO_SANDBOX_URL</code>
448
+ <code>CONNECT_WOO_URL</code>
449
+ <code>CONNECT_WOO_URL</code>
450
+ <code>PAYPAL_API_URL</code>
451
+ <code>PAYPAL_API_URL</code>
452
+ <code>PAYPAL_SANDBOX_API_URL</code>
453
+ <code>PAYPAL_SANDBOX_API_URL</code>
454
+ </UndefinedConstant>
455
+ </file>
456
+ <file src="modules/ppcp-onboarding/src/Assets/OnboardingAssets.php">
457
+ <InvalidScalarArgument occurrences="3">
458
+ <code>1</code>
459
+ <code>1</code>
460
+ <code>1</code>
461
+ </InvalidScalarArgument>
462
+ </file>
463
+ <file src="modules/ppcp-onboarding/src/OnboardingModule.php">
464
+ <MissingClosureParamType occurrences="3">
465
+ <code>$config</code>
466
+ <code>$field</code>
467
+ <code>$key</code>
468
+ </MissingClosureParamType>
469
+ </file>
470
+ <file src="modules/ppcp-onboarding/src/OnboardingRESTController.php">
471
+ <MissingReturnType occurrences="1">
472
+ <code>register_routes</code>
473
+ </MissingReturnType>
474
+ <PossiblyNullPropertyAssignmentValue occurrences="1">
475
+ <code>null</code>
476
+ </PossiblyNullPropertyAssignmentValue>
477
+ <RedundantConditionGivenDocblockType occurrences="2">
478
+ <code>! empty( $url_args ) &amp;&amp; is_array( $url_args )</code>
479
+ <code>is_array( $url_args )</code>
480
+ </RedundantConditionGivenDocblockType>
481
+ <UndefinedDocblockClass occurrences="5">
482
+ <code>WP_Error|array</code>
483
+ <code>WP_REST_Request</code>
484
+ <code>WP_REST_Request</code>
485
+ <code>WP_REST_Request</code>
486
+ <code>WP_REST_Request</code>
487
+ </UndefinedDocblockClass>
488
+ </file>
489
+ <file src="modules/ppcp-onboarding/src/Render/OnboardingRenderer.php">
490
+ <MissingReturnType occurrences="2">
491
+ <code>render</code>
492
+ <code>render_button</code>
493
+ </MissingReturnType>
494
+ </file>
495
+ <file src="modules/ppcp-session/services.php">
496
+ <TypeDoesNotContainType occurrences="1">
497
+ <code>is_a( $result, SessionHandler::class )</code>
498
+ </TypeDoesNotContainType>
499
+ </file>
500
+ <file src="modules/ppcp-session/src/Cancellation/CancelController.php">
501
+ <InvalidOperand occurrences="1">
502
+ <code>get_current_user_id()</code>
503
+ </InvalidOperand>
504
+ <MissingReturnType occurrences="1">
505
+ <code>run</code>
506
+ </MissingReturnType>
507
+ <PossiblyInvalidArgument occurrences="1">
508
+ <code>wp_unslash( $_GET[ $param_name ] )</code>
509
+ </PossiblyInvalidArgument>
510
+ </file>
511
+ <file src="modules/ppcp-session/src/Cancellation/CancelView.php">
512
+ <MissingReturnType occurrences="1">
513
+ <code>render_session_cancellation</code>
514
+ </MissingReturnType>
515
+ </file>
516
+ <file src="modules/ppcp-session/src/SessionHandler.php">
517
+ <MissingReturnType occurrences="1">
518
+ <code>store_session</code>
519
+ </MissingReturnType>
520
+ </file>
521
+ <file src="modules/ppcp-status-report/src/StatusReportModule.php">
522
+ <MissingReturnType occurrences="1">
523
+ <code>getKey</code>
524
+ </MissingReturnType>
525
+ </file>
526
+ <file src="modules/ppcp-subscription/src/Helper/SubscriptionHelper.php">
527
+ <UndefinedClass occurrences="1">
528
+ <code>\WC_Subscriptions_Admin</code>
529
+ </UndefinedClass>
530
+ </file>
531
+ <file src="modules/ppcp-subscription/src/RenewalHandler.php">
532
+ <FalsableReturnStatement occurrences="1">
533
+ <code>current( $tokens )</code>
534
+ </FalsableReturnStatement>
535
+ <MissingReturnType occurrences="3">
536
+ <code>capture_order</code>
537
+ <code>process_order</code>
538
+ <code>renew</code>
539
+ </MissingReturnType>
540
+ <RedundantCastGivenDocblockType occurrences="6">
541
+ <code>(int) $customer-&gt;get_id()</code>
542
+ <code>(int) $customer-&gt;get_id()</code>
543
+ <code>(int) $wc_order-&gt;get_customer_id()</code>
544
+ <code>(int) $wc_order-&gt;get_id()</code>
545
+ <code>(int) $wc_order-&gt;get_id()</code>
546
+ <code>(int) $wc_order-&gt;get_id()</code>
547
+ </RedundantCastGivenDocblockType>
548
+ <TooManyArguments occurrences="1">
549
+ <code>apply_filters( 'woocommerce_paypal_payments_subscriptions_get_token_for_customer', null, $customer, $wc_order )</code>
550
+ </TooManyArguments>
551
+ </file>
552
+ <file src="modules/ppcp-subscription/src/SubscriptionModule.php">
553
+ <MissingClosureParamType occurrences="9">
554
+ <code>$amount</code>
555
+ <code>$amount</code>
556
+ <code>$default_fields</code>
557
+ <code>$description</code>
558
+ <code>$id</code>
559
+ <code>$id</code>
560
+ <code>$order</code>
561
+ <code>$order</code>
562
+ <code>$subscription</code>
563
+ </MissingClosureParamType>
564
+ <MissingReturnType occurrences="1">
565
+ <code>add_payment_token_id</code>
566
+ </MissingReturnType>
567
+ <PossiblyNullReference occurrences="1">
568
+ <code>get</code>
569
+ </PossiblyNullReference>
570
+ <UndefinedClass occurrences="1">
571
+ <code>\WC_Subscription</code>
572
+ </UndefinedClass>
573
+ </file>
574
+ <file src="modules/ppcp-vaulting/src/Assets/MyAccountPaymentsAssets.php">
575
+ <MissingReturnType occurrences="1">
576
+ <code>localize</code>
577
+ </MissingReturnType>
578
+ </file>
579
+ <file src="modules/ppcp-vaulting/src/Endpoint/DeletePaymentTokenEndpoint.php">
580
+ <MissingReturnType occurrences="1">
581
+ <code>handle_request</code>
582
+ </MissingReturnType>
583
+ </file>
584
+ <file src="modules/ppcp-vaulting/src/PaymentTokenRepository.php">
585
+ <PossiblyFalseReference occurrences="1">
586
+ <code>to_array</code>
587
+ </PossiblyFalseReference>
588
+ </file>
589
+ <file src="modules/ppcp-vaulting/src/PaymentTokensRenderer.php">
590
+ <RedundantCondition occurrences="1">
591
+ <code>$token-&gt;source()</code>
592
+ </RedundantCondition>
593
+ <TypeDoesNotContainNull occurrences="1">
594
+ <code>null</code>
595
+ </TypeDoesNotContainNull>
596
+ </file>
597
+ <file src="modules/ppcp-vaulting/src/VaultingModule.php">
598
+ <MissingClosureParamType occurrences="1">
599
+ <code>$menu_links</code>
600
+ </MissingClosureParamType>
601
+ <MissingReturnType occurrences="1">
602
+ <code>getKey</code>
603
+ </MissingReturnType>
604
+ </file>
605
+ <file src="modules/ppcp-wc-gateway/services.php">
606
+ <PossiblyInvalidArgument occurrences="5">
607
+ <code>wp_unslash( $_GET[ SectionsRenderer::KEY ] )</code>
608
+ <code>wp_unslash( $_GET['page'] )</code>
609
+ <code>wp_unslash( $_GET['section'] )</code>
610
+ <code>wp_unslash( $_GET['section'] )</code>
611
+ <code>wp_unslash( $_GET['tab'] )</code>
612
+ </PossiblyInvalidArgument>
613
+ <PossiblyNullArgument occurrences="1">
614
+ <code>$letters</code>
615
+ </PossiblyNullArgument>
616
+ </file>
617
+ <file src="modules/ppcp-wc-gateway/src/Admin/OrderTablePaymentStatusColumn.php">
618
+ <MissingReturnType occurrences="3">
619
+ <code>render</code>
620
+ <code>render_completed_status</code>
621
+ <code>render_incomplete_status</code>
622
+ </MissingReturnType>
623
+ </file>
624
+ <file src="modules/ppcp-wc-gateway/src/Admin/PaymentStatusOrderDetail.php">
625
+ <MissingReturnType occurrences="1">
626
+ <code>render</code>
627
+ </MissingReturnType>
628
+ </file>
629
+ <file src="modules/ppcp-wc-gateway/src/Assets/SettingsPageAssets.php">
630
+ <MissingReturnType occurrences="2">
631
+ <code>register_admin_assets</code>
632
+ <code>register_assets</code>
633
+ </MissingReturnType>
634
+ <PossiblyNullPropertyFetch occurrences="1">
635
+ <code>$screen-&gt;id</code>
636
+ </PossiblyNullPropertyFetch>
637
+ </file>
638
+ <file src="modules/ppcp-wc-gateway/src/Checkout/CheckoutPayPalAddressPreset.php">
639
+ <PossiblyNullReference occurrences="3">
640
+ <code>phone</code>
641
+ <code>phone</code>
642
+ <code>phone</code>
643
+ <code>purchase_units</code>
644
+ </PossiblyNullReference>
645
+ <RedundantCondition occurrences="5">
646
+ <code>null</code>
647
+ <code>null</code>
648
+ <code>null</code>
649
+ <code>null</code>
650
+ <code>null</code>
651
+ </RedundantCondition>
652
+ </file>
653
+ <file src="modules/ppcp-wc-gateway/src/Checkout/DisableGateways.php">
654
+ <PossiblyNullReference occurrences="1">
655
+ <code>card</code>
656
+ </PossiblyNullReference>
657
+ </file>
658
+ <file src="modules/ppcp-wc-gateway/src/Endpoint/ReturnUrlEndpoint.php">
659
+ <MissingClosureParamType occurrences="1">
660
+ <code>$allowed_hosts</code>
661
+ </MissingClosureParamType>
662
+ <MissingReturnType occurrences="1">
663
+ <code>handle_request</code>
664
+ </MissingReturnType>
665
+ <PossiblyInvalidArgument occurrences="1">
666
+ <code>wp_unslash( $_GET['token'] )</code>
667
+ </PossiblyInvalidArgument>
668
+ </file>
669
+ <file src="modules/ppcp-wc-gateway/src/Helper/DCCProductStatus.php">
670
+ <InvalidPropertyAssignmentValue occurrences="2">
671
+ <code>true</code>
672
+ <code>true</code>
673
+ </InvalidPropertyAssignmentValue>
674
+ <PossiblyFalsePropertyAssignmentValue occurrences="2">
675
+ <code>false</code>
676
+ <code>false</code>
677
+ </PossiblyFalsePropertyAssignmentValue>
678
+ </file>
679
+ <file src="modules/ppcp-wc-gateway/src/Notice/AuthorizeOrderActionNotice.php">
680
+ <MissingClosureParamType occurrences="1">
681
+ <code>$location</code>
682
+ </MissingClosureParamType>
683
+ <MissingReturnType occurrences="1">
684
+ <code>display_message</code>
685
+ </MissingReturnType>
686
+ <PossiblyUndefinedVariable occurrences="1">
687
+ <code>$messages</code>
688
+ </PossiblyUndefinedVariable>
689
+ </file>
690
+ <file src="modules/ppcp-wc-gateway/src/Processor/AuthorizedPaymentsProcessor.php">
691
+ <MissingReturnType occurrences="1">
692
+ <code>capture_authorizations</code>
693
+ </MissingReturnType>
694
+ <PossiblyNullReference occurrences="1">
695
+ <code>authorizations</code>
696
+ </PossiblyNullReference>
697
+ <PropertyNotSetInConstructor occurrences="1">
698
+ <code>$captures</code>
699
+ </PropertyNotSetInConstructor>
700
+ </file>
701
+ <file src="modules/ppcp-wc-gateway/src/Processor/OrderProcessor.php">
702
+ <PossiblyNullReference occurrences="1">
703
+ <code>card</code>
704
+ </PossiblyNullReference>
705
+ <PropertyNotSetInConstructor occurrences="1">
706
+ <code>$payment_token_repository</code>
707
+ </PropertyNotSetInConstructor>
708
+ </file>
709
+ <file src="modules/ppcp-wc-gateway/src/Processor/PaymentsStatusHandlingTrait.php">
710
+ <PossiblyNullReference occurrences="2">
711
+ <code>authorizations</code>
712
+ <code>captures</code>
713
+ </PossiblyNullReference>
714
+ </file>
715
+ <file src="modules/ppcp-wc-gateway/src/Processor/RefundProcessor.php">
716
+ <PossiblyFalseArgument occurrences="1">
717
+ <code>wp_json_encode( $payments-&gt;to_array() )</code>
718
+ </PossiblyFalseArgument>
719
+ <PossiblyNullArgument occurrences="1">
720
+ <code>$amount</code>
721
+ </PossiblyNullArgument>
722
+ </file>
723
+ <file src="modules/ppcp-wc-gateway/src/Settings/SectionsRenderer.php">
724
+ <MissingReturnType occurrences="1">
725
+ <code>render</code>
726
+ </MissingReturnType>
727
+ </file>
728
+ <file src="modules/ppcp-wc-gateway/src/Settings/Settings.php">
729
+ <MissingReturnType occurrences="2">
730
+ <code>persist</code>
731
+ <code>set</code>
732
+ </MissingReturnType>
733
+ </file>
734
+ <file src="modules/ppcp-wc-gateway/src/Settings/SettingsListener.php">
735
+ <MissingReturnType occurrences="3">
736
+ <code>listen</code>
737
+ <code>listen_for_merchant_id</code>
738
+ <code>listen_for_vaulting_enabled</code>
739
+ </MissingReturnType>
740
+ <PossiblyInvalidArgument occurrences="3">
741
+ <code>wp_unslash( $_GET['merchantId'] )</code>
742
+ <code>wp_unslash( $_GET['merchantIdInPayPal'] )</code>
743
+ <code>wp_unslash( $_POST['ppcp-nonce'] )</code>
744
+ </PossiblyInvalidArgument>
745
+ </file>
746
+ <file src="modules/ppcp-wc-gateway/src/Settings/SettingsRenderer.php">
747
+ <InvalidArgument occurrences="1">
748
+ <code>$value</code>
749
+ </InvalidArgument>
750
+ <InvalidOperand occurrences="3">
751
+ <code>$field</code>
752
+ <code>$field</code>
753
+ <code>$field</code>
754
+ </InvalidOperand>
755
+ <MissingReturnType occurrences="5">
756
+ <code>render</code>
757
+ <code>render_dcc_does_not_apply_info</code>
758
+ <code>render_dcc_not_active_yet</code>
759
+ <code>render_dcc_onboarding_info</code>
760
+ <code>render_text</code>
761
+ </MissingReturnType>
762
+ <RedundantCast occurrences="1">
763
+ <code>(int) $colspan</code>
764
+ </RedundantCast>
765
+ </file>
766
+ <file src="modules/ppcp-wc-gateway/src/WCGatewayModule.php">
767
+ <MissingClosureParamType occurrences="15">
768
+ <code>$args</code>
769
+ <code>$args</code>
770
+ <code>$column</code>
771
+ <code>$columns</code>
772
+ <code>$field</code>
773
+ <code>$key</code>
774
+ <code>$methods</code>
775
+ <code>$methods</code>
776
+ <code>$notices</code>
777
+ <code>$order</code>
778
+ <code>$order_actions</code>
779
+ <code>$recipient</code>
780
+ <code>$value</code>
781
+ <code>$wc_order_id</code>
782
+ <code>$wc_order_id</code>
783
+ </MissingClosureParamType>
784
+ <MissingReturnType occurrences="4">
785
+ <code>register_checkout_paypal_address_preset</code>
786
+ <code>register_columns</code>
787
+ <code>register_order_functionality</code>
788
+ <code>register_payment_gateways</code>
789
+ </MissingReturnType>
790
+ </file>
791
+ <file src="modules/ppcp-webhooks/extensions.php">
792
+ <MissingClosureParamType occurrences="1">
793
+ <code>$container</code>
794
+ </MissingClosureParamType>
795
+ </file>
796
+ <file src="modules/ppcp-webhooks/src/Endpoint/ResubscribeEndpoint.php">
797
+ <MissingReturnType occurrences="1">
798
+ <code>handle_request</code>
799
+ </MissingReturnType>
800
+ </file>
801
+ <file src="modules/ppcp-webhooks/src/Endpoint/SimulateEndpoint.php">
802
+ <MissingReturnType occurrences="1">
803
+ <code>handle_request</code>
804
+ </MissingReturnType>
805
+ </file>
806
+ <file src="modules/ppcp-webhooks/src/Endpoint/SimulationStateEndpoint.php">
807
+ <MissingReturnType occurrences="1">
808
+ <code>handle_request</code>
809
+ </MissingReturnType>
810
+ </file>
811
+ <file src="modules/ppcp-webhooks/src/Handler/CheckoutOrderApproved.php">
812
+ <InvalidReturnStatement occurrences="5">
813
+ <code>rest_ensure_response( $response )</code>
814
+ <code>rest_ensure_response( $response )</code>
815
+ <code>rest_ensure_response( $response )</code>
816
+ <code>rest_ensure_response( $response )</code>
817
+ <code>rest_ensure_response( $response )</code>
818
+ </InvalidReturnStatement>
819
+ <InvalidReturnType occurrences="1">
820
+ <code>\WP_REST_Response</code>
821
+ </InvalidReturnType>
822
+ <PossibleRawObjectIteration occurrences="1">
823
+ <code>$wc_orders</code>
824
+ </PossibleRawObjectIteration>
825
+ <PossiblyNullArgument occurrences="5">
826
+ <code>$request['resource']['id']</code>
827
+ <code>isset( $request['id'] ) ? $request['id'] : ''</code>
828
+ <code>isset( $request['id'] ) ? $request['id'] : ''</code>
829
+ <code>isset( $request['id'] ) ? $request['id'] : ''</code>
830
+ <code>isset( $request['resource']['id'] ) ? $request['resource']['id'] : ''</code>
831
+ </PossiblyNullArgument>
832
+ <PossiblyNullArrayAccess occurrences="3">
833
+ <code>$request['resource']['id']</code>
834
+ <code>$request['resource']['id']</code>
835
+ <code>$request['resource']['purchase_units']</code>
836
+ </PossiblyNullArrayAccess>
837
+ </file>
838
+ <file src="modules/ppcp-webhooks/src/Handler/CheckoutOrderCompleted.php">
839
+ <InvalidReturnStatement occurrences="3">
840
+ <code>rest_ensure_response( $response )</code>
841
+ <code>rest_ensure_response( $response )</code>
842
+ <code>rest_ensure_response( $response )</code>
843
+ </InvalidReturnStatement>
844
+ <InvalidReturnType occurrences="1">
845
+ <code>\WP_REST_Response</code>
846
+ </InvalidReturnType>
847
+ <PossibleRawObjectIteration occurrences="1">
848
+ <code>$wc_orders</code>
849
+ </PossibleRawObjectIteration>
850
+ <PossiblyNullArgument occurrences="2">
851
+ <code>isset( $request['id'] ) ? $request['id'] : ''</code>
852
+ <code>isset( $request['resource']['id'] ) ? $request['resource']['id'] : ''</code>
853
+ </PossiblyNullArgument>
854
+ <PossiblyNullArrayAccess occurrences="2">
855
+ <code>$request['resource']['id']</code>
856
+ <code>$request['resource']['purchase_units']</code>
857
+ </PossiblyNullArrayAccess>
858
+ </file>
859
+ <file src="modules/ppcp-webhooks/src/Handler/PaymentCaptureRefunded.php">
860
+ <InvalidReturnStatement occurrences="4">
861
+ <code>rest_ensure_response( $response )</code>
862
+ <code>rest_ensure_response( $response )</code>
863
+ <code>rest_ensure_response( $response )</code>
864
+ <code>rest_ensure_response( $response )</code>
865
+ </InvalidReturnStatement>
866
+ <InvalidReturnType occurrences="1">
867
+ <code>\WP_REST_Response</code>
868
+ </InvalidReturnType>
869
+ <PossiblyNullArgument occurrences="3">
870
+ <code>$request['resource']['custom_id']</code>
871
+ <code>isset( $request['id'] ) ? $request['id'] : ''</code>
872
+ <code>isset( $request['resource']['id'] ) ? $request['resource']['id'] : ''</code>
873
+ </PossiblyNullArgument>
874
+ <PossiblyNullArrayAccess occurrences="3">
875
+ <code>$request['resource']['amount']</code>
876
+ <code>$request['resource']['custom_id']</code>
877
+ <code>$request['resource']['id']</code>
878
+ </PossiblyNullArrayAccess>
879
+ <PossiblyUndefinedMethod occurrences="2">
880
+ <code>get_amount</code>
881
+ <code>get_error_message</code>
882
+ </PossiblyUndefinedMethod>
883
+ </file>
884
+ <file src="modules/ppcp-webhooks/src/Handler/PaymentCaptureReversed.php">
885
+ <InvalidReturnStatement occurrences="3">
886
+ <code>rest_ensure_response( $response )</code>
887
+ <code>rest_ensure_response( $response )</code>
888
+ <code>rest_ensure_response( $response )</code>
889
+ </InvalidReturnStatement>
890
+ <InvalidReturnType occurrences="1">
891
+ <code>\WP_REST_Response</code>
892
+ </InvalidReturnType>
893
+ <PossiblyNullArgument occurrences="3">
894
+ <code>$request['resource']['custom_id']</code>
895
+ <code>isset( $request['id'] ) ? $request['id'] : ''</code>
896
+ <code>isset( $request['resource']['id'] ) ? $request['resource']['id'] : ''</code>
897
+ </PossiblyNullArgument>
898
+ <PossiblyNullArrayAccess occurrences="2">
899
+ <code>$request['resource']['custom_id']</code>
900
+ <code>$request['resource']['id']</code>
901
+ </PossiblyNullArrayAccess>
902
+ <RedundantCastGivenDocblockType occurrences="1">
903
+ <code>(bool) $wc_order-&gt;update_status( 'cancelled' )</code>
904
+ </RedundantCastGivenDocblockType>
905
+ </file>
906
+ <file src="modules/ppcp-webhooks/src/IncomingWebhookEndpoint.php">
907
+ <InvalidReturnStatement occurrences="2">
908
+ <code>rest_ensure_response( $response )</code>
909
+ </InvalidReturnStatement>
910
+ <InvalidReturnType occurrences="1">
911
+ <code>\WP_REST_Response</code>
912
+ </InvalidReturnType>
913
+ <PossiblyFalseArgument occurrences="1">
914
+ <code>( $handler-&gt;event_types() ) ? current( $handler-&gt;event_types() ) : ''</code>
915
+ </PossiblyFalseArgument>
916
+ <PossiblyNullArgument occurrences="1">
917
+ <code>$request['event_type']</code>
918
+ </PossiblyNullArgument>
919
+ <RedundantCastGivenDocblockType occurrences="1"/>
920
+ </file>
921
+ </files>
psalm.xml.dist ADDED
@@ -0,0 +1,154 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <psalm
3
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4
+ xmlns="https://getpsalm.org/schema/config"
5
+ xsi:schemaLocation="https://getpsalm.org/schema/config vendor/vimeo/psalm/config.xsd"
6
+ xmlns:xi="http://www.w3.org/2001/XInclude"
7
+ totallyTyped="false"
8
+ useDocblockTypes="true"
9
+ usePhpDocMethodsWithoutMagicCall="false"
10
+ strictBinaryOperands="true"
11
+ rememberPropertyAssignmentsAfterCall="true"
12
+ allowPhpStormGenerics="true"
13
+ allowStringToStandInForClass="false"
14
+ memoizeMethodCallResults="false"
15
+ hoistConstants="false"
16
+ addParamDefaultToDocblockType="false"
17
+ checkForThrowsDocblock="true"
18
+ checkForThrowsInGlobalScope="false"
19
+ ignoreInternalFunctionFalseReturn="false"
20
+ ignoreInternalFunctionNullReturn="false"
21
+ throwExceptionOnError="false"
22
+ hideExternalErrors="true"
23
+ allowFileIncludes="true"
24
+ errorBaseline="psalm-baseline.xml"
25
+ >
26
+ <projectFiles>
27
+ <directory name="src"/>
28
+ <directory name="modules" />
29
+ </projectFiles>
30
+
31
+ <stubs>
32
+ <file name=".psalm/stubs.php"/>
33
+ <file name="vendor/php-stubs/wordpress-stubs/wordpress-stubs.php"/>
34
+ <file name="vendor/php-stubs/woocommerce-stubs/woocommerce-stubs.php"/>
35
+ </stubs>
36
+
37
+
38
+ <issueHandlers>
39
+ <ConflictingReferenceConstraint errorLevel="error"/>
40
+ <ContinueOutsideLoop errorLevel="error"/>
41
+ <DuplicateArrayKey errorLevel="error"/>
42
+ <DuplicateClass errorLevel="error"/>
43
+ <DuplicateFunction errorLevel="error"/>
44
+ <DuplicateMethod errorLevel="error"/>
45
+ <DuplicateParam errorLevel="error"/>
46
+ <EmptyArrayAccess errorLevel="error"/>
47
+ <FalsableReturnStatement errorLevel="error"/>
48
+ <FalseOperand errorLevel="error"/>
49
+ <ForbiddenCode errorLevel="error"/>
50
+ <ForbiddenEcho errorLevel="error"/>
51
+ <InaccessibleClassConstant errorLevel="error"/>
52
+ <InaccessibleMethod errorLevel="error"/>
53
+ <InterfaceInstantiation errorLevel="error"/>
54
+ <InaccessibleProperty errorLevel="error"/>
55
+ <InternalClass errorLevel="error"/>
56
+ <InternalMethod errorLevel="error"/>
57
+ <InternalProperty errorLevel="error"/>
58
+ <InvalidArgument errorLevel="error"/>
59
+ <InvalidArrayAccess errorLevel="error"/>
60
+ <InvalidArrayAssignment errorLevel="error"/>
61
+ <InvalidArrayOffset errorLevel="error"/>
62
+ <InvalidCast errorLevel="error"/>
63
+ <InvalidCatch errorLevel="error"/>
64
+ <InvalidClass errorLevel="error"/>
65
+ <InvalidClone errorLevel="error"/>
66
+ <InvalidFalsableReturnType errorLevel="error"/>
67
+ <InvalidThrow errorLevel="error"/>
68
+ <InvalidToString errorLevel="error"/>
69
+ <LoopInvalidation errorLevel="error"/>
70
+ <InvalidNullableReturnType errorLevel="error"/>
71
+ <LessSpecificReturnType errorLevel="error"/>
72
+ <InvalidGlobal errorLevel="error"/>
73
+ <InvalidIterator errorLevel="error"/>
74
+ <InvalidMethodCall errorLevel="error"/>
75
+ <InvalidFunctionCall errorLevel="error"/>
76
+ <ImplicitToStringCast errorLevel="error"/>
77
+ <ImplementedReturnTypeMismatch errorLevel="error"/>
78
+ <InvalidParamDefault errorLevel="error"/>
79
+ <InvalidPassByReference errorLevel="error"/>
80
+ <InvalidPropertyAssignment errorLevel="error"/>
81
+ <InvalidPropertyAssignmentValue errorLevel="error"/>
82
+ <InvalidPropertyFetch errorLevel="error"/>
83
+ <InvalidReturnStatement errorLevel="error"/>
84
+ <InvalidReturnType errorLevel="error"/>
85
+ <InvalidScalarArgument errorLevel="error"/>
86
+ <InvalidScope errorLevel="error"/>
87
+ <InvalidStaticInvocation errorLevel="error"/>
88
+ <MissingConstructor errorLevel="error"/>
89
+ <MissingDependency errorLevel="error"/>
90
+ <MissingFile errorLevel="error"/>
91
+ <MixedArgument errorLevel="error"/>
92
+ <MoreSpecificImplementedParamType errorLevel="error"/>
93
+ <MoreSpecificReturnType errorLevel="error"/>
94
+ <NoValue errorLevel="error"/>
95
+ <NoInterfaceProperties errorLevel="error"/>
96
+ <NonStaticSelfCall errorLevel="error"/>
97
+ <NullableReturnStatement errorLevel="error"/>
98
+ <NullArgument errorLevel="error"/>
99
+ <NullArrayAccess errorLevel="error"/>
100
+ <NullArrayOffset errorLevel="error"/>
101
+ <NullFunctionCall errorLevel="error"/>
102
+ <NullIterator errorLevel="error"/>
103
+ <NullOperand errorLevel="error"/>
104
+ <NullPropertyAssignment errorLevel="error"/>
105
+ <NullPropertyFetch errorLevel="error"/>
106
+ <NullReference errorLevel="error"/>
107
+ <OverriddenMethodAccess errorLevel="error"/>
108
+ <OverriddenPropertyAccess errorLevel="error"/>
109
+ <ParadoxicalCondition errorLevel="error"/>
110
+ <ParentNotFound errorLevel="error"/>
111
+ <LessSpecificImplementedReturnType errorLevel="error"/>
112
+ <MissingParamType errorLevel="error"/>
113
+ <MissingClosureParamType errorLevel="error"/>
114
+ <MissingClosureReturnType errorLevel="error"/>
115
+ <MissingPropertyType errorLevel="error"/>
116
+ <UndefinedConstant errorLevel="error"/>
117
+
118
+ <AssignmentToVoid errorLevel="info"/>
119
+ <DeprecatedClass errorLevel="info"/>
120
+ <DeprecatedConstant errorLevel="info"/>
121
+ <DeprecatedTrait errorLevel="info"/>
122
+ <DocblockTypeContradiction errorLevel="info"/>
123
+ <InvalidDocblock errorLevel="info"/>
124
+ <InvalidDocblockParamName errorLevel="info"/>
125
+ <InvalidTemplateParam errorLevel="info"/>
126
+ <DeprecatedInterface errorLevel="info"/>
127
+ <DeprecatedMethod errorLevel="info"/>
128
+ <DeprecatedProperty errorLevel="info"/>
129
+ <MethodSignatureMustOmitReturnType errorLevel="info"/>
130
+ <MismatchingDocblockParamType errorLevel="info"/>
131
+ <MismatchingDocblockReturnType errorLevel="info"/>
132
+ <MissingDocblockType errorLevel="info"/>
133
+ <MissingParamType errorLevel="info"/>
134
+ <MissingTemplateParam errorLevel="info"/>
135
+ <MissingThrowsDocblock errorLevel="info"/>
136
+ <MixedArgumentTypeCoercion errorLevel="info"/>
137
+ <MixedArrayAccess errorLevel="info"/>
138
+ <MixedArrayAssignment errorLevel="info"/>
139
+ <MixedArrayOffset errorLevel="info"/>
140
+ <MixedArrayTypeCoercion errorLevel="info"/>
141
+ <MixedAssignment errorLevel="info"/>
142
+ <MixedFunctionCall errorLevel="info"/>
143
+ <MixedInferredReturnType errorLevel="info"/>
144
+ <MixedMethodCall errorLevel="info"/>
145
+ <MixedOperand errorLevel="info"/>
146
+ <MixedPropertyAssignment errorLevel="info"/>
147
+ <MixedPropertyFetch errorLevel="info"/>
148
+ <MixedPropertyTypeCoercion errorLevel="info"/>
149
+ <MixedReturnStatement errorLevel="info"/>
150
+ <MixedReturnTypeCoercion errorLevel="info"/>
151
+ <MixedStringOffsetAssignment errorLevel="info"/>
152
+ <ParamNameMismatch errorLevel="info"/>
153
+ </issueHandlers>
154
+ </psalm>
readme.txt CHANGED
@@ -4,7 +4,7 @@ Tags: woocommerce, paypal, payments, ecommerce, e-commerce, store, sales, sell,
4
  Requires at least: 5.3
5
  Tested up to: 5.8
6
  Requires PHP: 7.1
7
- Stable tag: 1.6.1
8
  License: GPLv2
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
@@ -81,6 +81,23 @@ Follow the steps below to connect the plugin to your PayPal account:
81
 
82
  == Changelog ==
83
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
84
  = 1.6.1 =
85
  * Fix - Handle authorization capture failures #312
86
  * Fix - Handle denied payment authorization #302
4
  Requires at least: 5.3
5
  Tested up to: 5.8
6
  Requires PHP: 7.1
7
+ Stable tag: 1.6.2
8
  License: GPLv2
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
81
 
82
  == Changelog ==
83
 
84
+ = 1.6.2 =
85
+ * Fix - Order of WooCommerce checkout actions causing incompatibility with AvaTax address validation #335
86
+ * Fix - Can't checkout to certain countries with optional postcode #330
87
+ * Fix - Prevent subscription from being purchased when saving payment fails #308
88
+ * Fix - Guest users must checkout twice for subscriptions, no smart buttons loaded #342
89
+ * Fix - Failed PayPal API request causing strange error #347
90
+ * Fix - PayPal payments page empty after switching packages #350
91
+ * Fix - Could Not Validate Nonce Error #239
92
+ * Fix - Refund via PayPal dashboard does not set the WooCommerce order to "Refunded" #241
93
+ * Fix - Uncaught TypeError: round() #344
94
+ * Fix - Broken multi-level (nested) associative array values after getting submitted from checkout page #307
95
+ * Fix - Transaction id missing in some cases #328
96
+ * Fix - Payment not possible in pay for order form because of terms checkbox missing #294
97
+ * Fix - "Save your Credit Card" shouldn't be optional when paying for a subscription #368
98
+ * Fix - When paying for a subscription and vaulting fails, cart is cleared #367
99
+ * Fix - Fatal error when activating PayPal Checkout plugin #363
100
+
101
  = 1.6.1 =
102
  * Fix - Handle authorization capture failures #312
103
  * Fix - Handle denied payment authorization #302
src/{class-pluginmodule.php → PluginModule.php} RENAMED
@@ -20,18 +20,16 @@ use Psr\Container\ContainerInterface;
20
  class PluginModule implements ModuleInterface {
21
 
22
  /**
23
- * Sets the module up.
24
  */
25
  public function setup(): ServiceProviderInterface {
26
  return new ServiceProvider( array(), array() );
27
  }
28
 
29
  /**
30
- * Runs the module.
31
- *
32
- * @param ContainerInterface|null $container The Container.
33
  */
34
- public function run( ContainerInterface $container ): void {
35
  }
36
 
37
  /**
20
  class PluginModule implements ModuleInterface {
21
 
22
  /**
23
+ * {@inheritDoc}
24
  */
25
  public function setup(): ServiceProviderInterface {
26
  return new ServiceProvider( array(), array() );
27
  }
28
 
29
  /**
30
+ * {@inheritDoc}
 
 
31
  */
32
+ public function run( ContainerInterface $c ): void {
33
  }
34
 
35
  /**
vendor/autoload.php CHANGED
@@ -4,4 +4,4 @@
4
 
5
  require_once __DIR__ . '/composer/autoload_real.php';
6
 
7
- return ComposerAutoloaderInit4607be6ea28f9ff73f3cf09747918e4b::getLoader();
4
 
5
  require_once __DIR__ . '/composer/autoload_real.php';
6
 
7
+ return ComposerAutoloaderInit3acb3642cf46c3f8b0d913579e285e9c::getLoader();
vendor/composer/ClassLoader.php CHANGED
@@ -37,80 +37,26 @@ namespace Composer\Autoload;
37
  *
38
  * @author Fabien Potencier <fabien@symfony.com>
39
  * @author Jordi Boggiano <j.boggiano@seld.be>
40
- * @see https://www.php-fig.org/psr/psr-0/
41
- * @see https://www.php-fig.org/psr/psr-4/
42
  */
43
  class ClassLoader
44
  {
45
- /** @var ?string */
46
- private $vendorDir;
47
-
48
  // PSR-4
49
- /**
50
- * @var array[]
51
- * @psalm-var array<string, array<string, int>>
52
- */
53
  private $prefixLengthsPsr4 = array();
54
- /**
55
- * @var array[]
56
- * @psalm-var array<string, array<int, string>>
57
- */
58
  private $prefixDirsPsr4 = array();
59
- /**
60
- * @var array[]
61
- * @psalm-var array<string, string>
62
- */
63
  private $fallbackDirsPsr4 = array();
64
 
65
  // PSR-0
66
- /**
67
- * @var array[]
68
- * @psalm-var array<string, array<string, string[]>>
69
- */
70
  private $prefixesPsr0 = array();
71
- /**
72
- * @var array[]
73
- * @psalm-var array<string, string>
74
- */
75
  private $fallbackDirsPsr0 = array();
76
 
77
- /** @var bool */
78
  private $useIncludePath = false;
79
-
80
- /**
81
- * @var string[]
82
- * @psalm-var array<string, string>
83
- */
84
  private $classMap = array();
85
-
86
- /** @var bool */
87
  private $classMapAuthoritative = false;
88
-
89
- /**
90
- * @var bool[]
91
- * @psalm-var array<string, bool>
92
- */
93
  private $missingClasses = array();
94
-
95
- /** @var ?string */
96
  private $apcuPrefix;
97
 
98
- /**
99
- * @var self[]
100
- */
101
- private static $registeredLoaders = array();
102
-
103
- /**
104
- * @param ?string $vendorDir
105
- */
106
- public function __construct($vendorDir = null)
107
- {
108
- $this->vendorDir = $vendorDir;
109
- }
110
-
111
- /**
112
- * @return string[]
113
- */
114
  public function getPrefixes()
115
  {
116
  if (!empty($this->prefixesPsr0)) {
@@ -120,47 +66,28 @@ class ClassLoader
120
  return array();
121
  }
122
 
123
- /**
124
- * @return array[]
125
- * @psalm-return array<string, array<int, string>>
126
- */
127
  public function getPrefixesPsr4()
128
  {
129
  return $this->prefixDirsPsr4;
130
  }
131
 
132
- /**
133
- * @return array[]
134
- * @psalm-return array<string, string>
135
- */
136
  public function getFallbackDirs()
137
  {
138
  return $this->fallbackDirsPsr0;
139
  }
140
 
141
- /**
142
- * @return array[]
143
- * @psalm-return array<string, string>
144
- */
145
  public function getFallbackDirsPsr4()
146
  {
147
  return $this->fallbackDirsPsr4;
148
  }
149
 
150
- /**
151
- * @return string[] Array of classname => path
152
- * @psalm-var array<string, string>
153
- */
154
  public function getClassMap()
155
  {
156
  return $this->classMap;
157
  }
158
 
159
  /**
160
- * @param string[] $classMap Class to filename map
161
- * @psalm-param array<string, string> $classMap
162
- *
163
- * @return void
164
  */
165
  public function addClassMap(array $classMap)
166
  {
@@ -175,11 +102,9 @@ class ClassLoader
175
  * Registers a set of PSR-0 directories for a given prefix, either
176
  * appending or prepending to the ones previously set for this prefix.
177
  *
178
- * @param string $prefix The prefix
179
- * @param string[]|string $paths The PSR-0 root directories
180
- * @param bool $prepend Whether to prepend the directories
181
- *
182
- * @return void
183
  */
184
  public function add($prefix, $paths, $prepend = false)
185
  {
@@ -222,13 +147,11 @@ class ClassLoader
222
  * Registers a set of PSR-4 directories for a given namespace, either
223
  * appending or prepending to the ones previously set for this namespace.
224
  *
225
- * @param string $prefix The prefix/namespace, with trailing '\\'
226
- * @param string[]|string $paths The PSR-4 base directories
227
- * @param bool $prepend Whether to prepend the directories
228
  *
229
  * @throws \InvalidArgumentException
230
- *
231
- * @return void
232
  */
233
  public function addPsr4($prefix, $paths, $prepend = false)
234
  {
@@ -272,10 +195,8 @@ class ClassLoader
272
  * Registers a set of PSR-0 directories for a given prefix,
273
  * replacing any others previously set for this prefix.
274
  *
275
- * @param string $prefix The prefix
276
- * @param string[]|string $paths The PSR-0 base directories
277
- *
278
- * @return void
279
  */
280
  public function set($prefix, $paths)
281
  {
@@ -290,12 +211,10 @@ class ClassLoader
290
  * Registers a set of PSR-4 directories for a given namespace,
291
  * replacing any others previously set for this namespace.
292
  *
293
- * @param string $prefix The prefix/namespace, with trailing '\\'
294
- * @param string[]|string $paths The PSR-4 base directories
295
  *
296
  * @throws \InvalidArgumentException
297
- *
298
- * @return void
299
  */
300
  public function setPsr4($prefix, $paths)
301
  {
@@ -315,8 +234,6 @@ class ClassLoader
315
  * Turns on searching the include path for class files.
316
  *
317
  * @param bool $useIncludePath
318
- *
319
- * @return void
320
  */
321
  public function setUseIncludePath($useIncludePath)
322
  {
@@ -339,8 +256,6 @@ class ClassLoader
339
  * that have not been registered with the class map.
340
  *
341
  * @param bool $classMapAuthoritative
342
- *
343
- * @return void
344
  */
345
  public function setClassMapAuthoritative($classMapAuthoritative)
346
  {
@@ -361,8 +276,6 @@ class ClassLoader
361
  * APCu prefix to use to cache found/not-found classes, if the extension is enabled.
362
  *
363
  * @param string|null $apcuPrefix
364
- *
365
- * @return void
366
  */
367
  public function setApcuPrefix($apcuPrefix)
368
  {
@@ -383,44 +296,25 @@ class ClassLoader
383
  * Registers this instance as an autoloader.
384
  *
385
  * @param bool $prepend Whether to prepend the autoloader or not
386
- *
387
- * @return void
388
  */
389
  public function register($prepend = false)
390
  {
391
  spl_autoload_register(array($this, 'loadClass'), true, $prepend);
392
-
393
- if (null === $this->vendorDir) {
394
- return;
395
- }
396
-
397
- if ($prepend) {
398
- self::$registeredLoaders = array($this->vendorDir => $this) + self::$registeredLoaders;
399
- } else {
400
- unset(self::$registeredLoaders[$this->vendorDir]);
401
- self::$registeredLoaders[$this->vendorDir] = $this;
402
- }
403
  }
404
 
405
  /**
406
  * Unregisters this instance as an autoloader.
407
- *
408
- * @return void
409
  */
410
  public function unregister()
411
  {
412
  spl_autoload_unregister(array($this, 'loadClass'));
413
-
414
- if (null !== $this->vendorDir) {
415
- unset(self::$registeredLoaders[$this->vendorDir]);
416
- }
417
  }
418
 
419
  /**
420
  * Loads the given class or interface.
421
  *
422
  * @param string $class The name of the class
423
- * @return true|null True if loaded, null otherwise
424
  */
425
  public function loadClass($class)
426
  {
@@ -429,8 +323,6 @@ class ClassLoader
429
 
430
  return true;
431
  }
432
-
433
- return null;
434
  }
435
 
436
  /**
@@ -475,21 +367,6 @@ class ClassLoader
475
  return $file;
476
  }
477
 
478
- /**
479
- * Returns the currently registered loaders indexed by their corresponding vendor directories.
480
- *
481
- * @return self[]
482
- */
483
- public static function getRegisteredLoaders()
484
- {
485
- return self::$registeredLoaders;
486
- }
487
-
488
- /**
489
- * @param string $class
490
- * @param string $ext
491
- * @return string|false
492
- */
493
  private function findFileWithExtension($class, $ext)
494
  {
495
  // PSR-4 lookup
@@ -561,10 +438,6 @@ class ClassLoader
561
  * Scope isolated include.
562
  *
563
  * Prevents access to $this/self from included files.
564
- *
565
- * @param string $file
566
- * @return void
567
- * @private
568
  */
569
  function includeFile($file)
570
  {
37
  *
38
  * @author Fabien Potencier <fabien@symfony.com>
39
  * @author Jordi Boggiano <j.boggiano@seld.be>
40
+ * @see http://www.php-fig.org/psr/psr-0/
41
+ * @see http://www.php-fig.org/psr/psr-4/
42
  */
43
  class ClassLoader
44
  {
 
 
 
45
  // PSR-4
 
 
 
 
46
  private $prefixLengthsPsr4 = array();
 
 
 
 
47
  private $prefixDirsPsr4 = array();
 
 
 
 
48
  private $fallbackDirsPsr4 = array();
49
 
50
  // PSR-0
 
 
 
 
51
  private $prefixesPsr0 = array();
 
 
 
 
52
  private $fallbackDirsPsr0 = array();
53
 
 
54
  private $useIncludePath = false;
 
 
 
 
 
55
  private $classMap = array();
 
 
56
  private $classMapAuthoritative = false;
 
 
 
 
 
57
  private $missingClasses = array();
 
 
58
  private $apcuPrefix;
59
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
60
  public function getPrefixes()
61
  {
62
  if (!empty($this->prefixesPsr0)) {
66
  return array();
67
  }
68
 
 
 
 
 
69
  public function getPrefixesPsr4()
70
  {
71
  return $this->prefixDirsPsr4;
72
  }
73
 
 
 
 
 
74
  public function getFallbackDirs()
75
  {
76
  return $this->fallbackDirsPsr0;
77
  }
78
 
 
 
 
 
79
  public function getFallbackDirsPsr4()
80
  {
81
  return $this->fallbackDirsPsr4;
82
  }
83
 
 
 
 
 
84
  public function getClassMap()
85
  {
86
  return $this->classMap;
87
  }
88
 
89
  /**
90
+ * @param array $classMap Class to filename map
 
 
 
91
  */
92
  public function addClassMap(array $classMap)
93
  {
102
  * Registers a set of PSR-0 directories for a given prefix, either
103
  * appending or prepending to the ones previously set for this prefix.
104
  *
105
+ * @param string $prefix The prefix
106
+ * @param array|string $paths The PSR-0 root directories
107
+ * @param bool $prepend Whether to prepend the directories
 
 
108
  */
109
  public function add($prefix, $paths, $prepend = false)
110
  {
147
  * Registers a set of PSR-4 directories for a given namespace, either
148
  * appending or prepending to the ones previously set for this namespace.
149
  *
150
+ * @param string $prefix The prefix/namespace, with trailing '\\'
151
+ * @param array|string $paths The PSR-4 base directories
152
+ * @param bool $prepend Whether to prepend the directories
153
  *
154
  * @throws \InvalidArgumentException
 
 
155
  */
156
  public function addPsr4($prefix, $paths, $prepend = false)
157
  {
195
  * Registers a set of PSR-0 directories for a given prefix,
196
  * replacing any others previously set for this prefix.
197
  *
198
+ * @param string $prefix The prefix
199
+ * @param array|string $paths The PSR-0 base directories
 
 
200
  */
201
  public function set($prefix, $paths)
202
  {
211
  * Registers a set of PSR-4 directories for a given namespace,
212
  * replacing any others previously set for this namespace.
213
  *
214
+ * @param string $prefix The prefix/namespace, with trailing '\\'
215
+ * @param array|string $paths The PSR-4 base directories
216
  *
217
  * @throws \InvalidArgumentException
 
 
218
  */
219
  public function setPsr4($prefix, $paths)
220
  {
234
  * Turns on searching the include path for class files.
235
  *
236
  * @param bool $useIncludePath
 
 
237
  */
238
  public function setUseIncludePath($useIncludePath)
239
  {
256
  * that have not been registered with the class map.
257
  *
258
  * @param bool $classMapAuthoritative
 
 
259
  */
260
  public function setClassMapAuthoritative($classMapAuthoritative)
261
  {
276
  * APCu prefix to use to cache found/not-found classes, if the extension is enabled.
277
  *
278
  * @param string|null $apcuPrefix
 
 
279
  */
280
  public function setApcuPrefix($apcuPrefix)
281
  {
296
  * Registers this instance as an autoloader.
297
  *
298
  * @param bool $prepend Whether to prepend the autoloader or not
 
 
299
  */
300
  public function register($prepend = false)
301
  {
302
  spl_autoload_register(array($this, 'loadClass'), true, $prepend);
 
 
 
 
 
 
 
 
 
 
 
303
  }
304
 
305
  /**
306
  * Unregisters this instance as an autoloader.
 
 
307
  */
308
  public function unregister()
309
  {
310
  spl_autoload_unregister(array($this, 'loadClass'));
 
 
 
 
311
  }
312
 
313
  /**
314
  * Loads the given class or interface.
315
  *
316
  * @param string $class The name of the class
317
+ * @return bool|null True if loaded, null otherwise
318
  */
319
  public function loadClass($class)
320
  {
323
 
324
  return true;
325
  }
 
 
326
  }
327
 
328
  /**
367
  return $file;
368
  }
369
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
370
  private function findFileWithExtension($class, $ext)
371
  {
372
  // PSR-4 lookup
438
  * Scope isolated include.
439
  *
440
  * Prevents access to $this/self from included files.
 
 
 
 
441
  */
442
  function includeFile($file)
443
  {
vendor/composer/InstalledVersions.php DELETED
@@ -1,337 +0,0 @@
1
- <?php
2
-
3
- /*
4
- * This file is part of Composer.
5
- *
6
- * (c) Nils Adermann <naderman@naderman.de>
7
- * Jordi Boggiano <j.boggiano@seld.be>
8
- *
9
- * For the full copyright and license information, please view the LICENSE
10
- * file that was distributed with this source code.
11
- */
12
-
13
- namespace Composer;
14
-
15
- use Composer\Autoload\ClassLoader;
16
- use Composer\Semver\VersionParser;
17
-
18
- /**
19
- * This class is copied in every Composer installed project and available to all
20
- *
21
- * See also https://getcomposer.org/doc/07-runtime.md#installed-versions
22
- *
23
- * To require its presence, you can require `composer-runtime-api ^2.0`
24
- */
25
- class InstalledVersions
26
- {
27
- private static $installed;
28
- private static $canGetVendors;
29
- private static $installedByVendor = array();
30
-
31
- /**
32
- * Returns a list of all package names which are present, either by being installed, replaced or provided
33
- *
34
- * @return string[]
35
- * @psalm-return list<string>
36
- */
37
- public static function getInstalledPackages()
38
- {
39
- $packages = array();
40
- foreach (self::getInstalled() as $installed) {
41
- $packages[] = array_keys($installed['versions']);
42
- }
43
-
44
- if (1 === \count($packages)) {
45
- return $packages[0];
46
- }
47
-
48
- return array_keys(array_flip(\call_user_func_array('array_merge', $packages)));
49
- }
50
-
51
- /**
52
- * Returns a list of all package names with a specific type e.g. 'library'
53
- *
54
- * @param string $type
55
- * @return string[]
56
- * @psalm-return list<string>
57
- */
58
- public static function getInstalledPackagesByType($type)
59
- {
60
- $packagesByType = array();
61
-
62
- foreach (self::getInstalled() as $installed) {
63
- foreach ($installed['versions'] as $name => $package) {
64
- if (isset($package['type']) && $package['type'] === $type) {
65
- $packagesByType[] = $name;
66
- }
67
- }
68
- }
69
-
70
- return $packagesByType;
71
- }
72
-
73
- /**
74
- * Checks whether the given package is installed
75
- *
76
- * This also returns true if the package name is provided or replaced by another package
77
- *
78
- * @param string $packageName
79
- * @param bool $includeDevRequirements
80
- * @return bool
81
- */
82
- public static function isInstalled($packageName, $includeDevRequirements = true)
83
- {
84
- foreach (self::getInstalled() as $installed) {
85
- if (isset($installed['versions'][$packageName])) {
86
- return $includeDevRequirements || empty($installed['versions'][$packageName]['dev_requirement']);
87
- }
88
- }
89
-
90
- return false;
91
- }
92
-
93
- /**
94
- * Checks whether the given package satisfies a version constraint
95
- *
96
- * e.g. If you want to know whether version 2.3+ of package foo/bar is installed, you would call:
97
- *
98
- * Composer\InstalledVersions::satisfies(new VersionParser, 'foo/bar', '^2.3')
99
- *
100
- * @param VersionParser $parser Install composer/semver to have access to this class and functionality
101
- * @param string $packageName
102
- * @param string|null $constraint A version constraint to check for, if you pass one you have to make sure composer/semver is required by your package
103
- * @return bool
104
- */
105
- public static function satisfies(VersionParser $parser, $packageName, $constraint)
106
- {
107
- $constraint = $parser->parseConstraints($constraint);
108
- $provided = $parser->parseConstraints(self::getVersionRanges($packageName));
109
-
110
- return $provided->matches($constraint);
111
- }
112
-
113
- /**
114
- * Returns a version constraint representing all the range(s) which are installed for a given package
115
- *
116
- * It is easier to use this via isInstalled() with the $constraint argument if you need to check
117
- * whether a given version of a package is installed, and not just whether it exists
118
- *
119
- * @param string $packageName
120
- * @return string Version constraint usable with composer/semver
121
- */
122
- public static function getVersionRanges($packageName)
123
- {
124
- foreach (self::getInstalled() as $installed) {
125
- if (!isset($installed['versions'][$packageName])) {
126
- continue;
127
- }
128
-
129
- $ranges = array();
130
- if (isset($installed['versions'][$packageName]['pretty_version'])) {
131
- $ranges[] = $installed['versions'][$packageName]['pretty_version'];
132
- }
133
- if (array_key_exists('aliases', $installed['versions'][$packageName])) {
134
- $ranges = array_merge($ranges, $installed['versions'][$packageName]['aliases']);
135
- }
136
- if (array_key_exists('replaced', $installed['versions'][$packageName])) {
137
- $ranges = array_merge($ranges, $installed['versions'][$packageName]['replaced']);
138
- }
139
- if (array_key_exists('provided', $installed['versions'][$packageName])) {
140
- $ranges = array_merge($ranges, $installed['versions'][$packageName]['provided']);
141
- }
142
-
143
- return implode(' || ', $ranges);
144
- }
145
-
146
- throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
147
- }
148
-
149
- /**
150
- * @param string $packageName
151
- * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as version, use satisfies or getVersionRanges if you need to know if a given version is present
152
- */
153
- public static function getVersion($packageName)
154
- {
155
- foreach (self::getInstalled() as $installed) {
156
- if (!isset($installed['versions'][$packageName])) {
157
- continue;
158
- }
159
-
160
- if (!isset($installed['versions'][$packageName]['version'])) {
161
- return null;
162
- }
163
-
164
- return $installed['versions'][$packageName]['version'];
165
- }
166
-
167
- throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
168
- }
169
-
170
- /**
171
- * @param string $packageName
172
- * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as version, use satisfies or getVersionRanges if you need to know if a given version is present
173
- */
174
- public static function getPrettyVersion($packageName)
175
- {
176
- foreach (self::getInstalled() as $installed) {
177
- if (!isset($installed['versions'][$packageName])) {
178
- continue;
179
- }
180
-
181
- if (!isset($installed['versions'][$packageName]['pretty_version'])) {
182
- return null;
183
- }
184
-
185
- return $installed['versions'][$packageName]['pretty_version'];
186
- }
187
-
188
- throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
189
- }
190
-
191
- /**
192
- * @param string $packageName
193
- * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as reference
194
- */
195
- public static function getReference($packageName)
196
- {
197
- foreach (self::getInstalled() as $installed) {
198
- if (!isset($installed['versions'][$packageName])) {
199
- continue;
200
- }
201
-
202
- if (!isset($installed['versions'][$packageName]['reference'])) {
203
- return null;
204
- }
205
-
206
- return $installed['versions'][$packageName]['reference'];
207
- }
208
-
209
- throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
210
- }
211
-
212
- /**
213
- * @param string $packageName
214
- * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as install path. Packages of type metapackages also have a null install path.
215
- */
216
- public static function getInstallPath($packageName)
217
- {
218
- foreach (self::getInstalled() as $installed) {
219
- if (!isset($installed['versions'][$packageName])) {
220
- continue;
221
- }
222
-
223
- return isset($installed['versions'][$packageName]['install_path']) ? $installed['versions'][$packageName]['install_path'] : null;
224
- }
225
-
226
- throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
227
- }
228
-
229
- /**
230
- * @return array
231
- * @psalm-return array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string}
232
- */
233
- public static function getRootPackage()
234
- {
235
- $installed = self::getInstalled();
236
-
237
- return $installed[0]['root'];
238
- }
239
-
240
- /**
241
- * Returns the raw installed.php data for custom implementations
242
- *
243
- * @deprecated Use getAllRawData() instead which returns all datasets for all autoloaders present in the process. getRawData only returns the first dataset loaded, which may not be what you expect.
244
- * @return array[]
245
- * @psalm-return array{root: array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string}, versions: array<string, array{dev_requirement: bool, pretty_version?: string, version?: string, aliases?: string[], reference?: string, replaced?: string[], provided?: string[], install_path?: string, type?: string}>}
246
- */
247
- public static function getRawData()
248
- {
249
- @trigger_error('getRawData only returns the first dataset loaded, which may not be what you expect. Use getAllRawData() instead which returns all datasets for all autoloaders present in the process.', E_USER_DEPRECATED);
250
-
251
- if (null === self::$installed) {
252
- // only require the installed.php file if this file is loaded from its dumped location,
253
- // and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937
254
- if (substr(__DIR__, -8, 1) !== 'C') {
255
- self::$installed = include __DIR__ . '/installed.php';
256
- } else {
257
- self::$installed = array();
258
- }
259
- }
260
-
261
- return self::$installed;
262
- }
263
-
264
- /**
265
- * Returns the raw data of all installed.php which are currently loaded for custom implementations
266
- *
267
- * @return array[]
268
- * @psalm-return list<array{root: array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string}, versions: array<string, array{dev_requirement: bool, pretty_version?: string, version?: string, aliases?: string[], reference?: string, replaced?: string[], provided?: string[], install_path?: string, type?: string}>}>
269
- */
270
- public static function getAllRawData()
271
- {
272
- return self::getInstalled();
273
- }
274
-
275
- /**
276
- * Lets you reload the static array from another file
277
- *
278
- * This is only useful for complex integrations in which a project needs to use
279
- * this class but then also needs to execute another project's autoloader in process,
280
- * and wants to ensure both projects have access to their version of installed.php.
281
- *
282
- * A typical case would be PHPUnit, where it would need to make sure it reads all
283
- * the data it needs from this class, then call reload() with
284
- * `require $CWD/vendor/composer/installed.php` (or similar) as input to make sure
285
- * the project in which it runs can then also use this class safely, without
286
- * interference between PHPUnit's dependencies and the project's dependencies.
287
- *
288
- * @param array[] $data A vendor/composer/installed.php data set
289
- * @return void
290
- *
291
- * @psalm-param array{root: array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string}, versions: array<string, array{dev_requirement: bool, pretty_version?: string, version?: string, aliases?: string[], reference?: string, replaced?: string[], provided?: string[], install_path?: string, type?: string}>} $data
292
- */
293
- public static function reload($data)
294
- {
295
- self::$installed = $data;
296
- self::$installedByVendor = array();
297
- }
298
-
299
- /**
300
- * @return array[]
301
- * @psalm-return list<array{root: array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string}, versions: array<string, array{dev_requirement: bool, pretty_version?: string, version?: string, aliases?: string[], reference?: string, replaced?: string[], provided?: string[], install_path?: string, type?: string}>}>
302
- */
303
- private static function getInstalled()
304
- {
305
- if (null === self::$canGetVendors) {
306
- self::$canGetVendors = method_exists('Composer\Autoload\ClassLoader', 'getRegisteredLoaders');
307
- }
308
-
309
- $installed = array();
310
-
311
- if (self::$canGetVendors) {
312
- foreach (ClassLoader::getRegisteredLoaders() as $vendorDir => $loader) {
313
- if (isset(self::$installedByVendor[$vendorDir])) {
314
- $installed[] = self::$installedByVendor[$vendorDir];
315
- } elseif (is_file($vendorDir.'/composer/installed.php')) {
316
- $installed[] = self::$installedByVendor[$vendorDir] = require $vendorDir.'/composer/installed.php';
317
- if (null === self::$installed && strtr($vendorDir.'/composer', '\\', '/') === strtr(__DIR__, '\\', '/')) {
318
- self::$installed = $installed[count($installed) - 1];
319
- }
320
- }
321
- }
322
- }
323
-
324
- if (null === self::$installed) {
325
- // only require the installed.php file if this file is loaded from its dumped location,
326
- // and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937
327
- if (substr(__DIR__, -8, 1) !== 'C') {
328
- self::$installed = require __DIR__ . '/installed.php';
329
- } else {
330
- self::$installed = array();
331
- }
332
- }
333
- $installed[] = self::$installed;
334
-
335
- return $installed;
336
- }
337
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/composer/autoload_classmap.php CHANGED
@@ -6,181 +6,4 @@ $vendorDir = dirname(dirname(__FILE__));
6
  $baseDir = dirname($vendorDir);
7
 
8
  return array(
9
- 'Composer\\InstalledVersions' => $vendorDir . '/composer/InstalledVersions.php',
10
- 'WooCommerce\\PayPalCommerce\\AdminNotices\\AdminNotices' => $baseDir . '/modules/ppcp-admin-notices/src/class-adminnotices.php',
11
- 'WooCommerce\\PayPalCommerce\\AdminNotices\\Entity\\Message' => $baseDir . '/modules/ppcp-admin-notices/src/Entity/class-message.php',
12
- 'WooCommerce\\PayPalCommerce\\AdminNotices\\Renderer\\Renderer' => $baseDir . '/modules/ppcp-admin-notices/src/Renderer/class-renderer.php',
13
- 'WooCommerce\\PayPalCommerce\\AdminNotices\\Renderer\\RendererInterface' => $baseDir . '/modules/ppcp-admin-notices/src/Renderer/class-rendererinterface.php',
14
- 'WooCommerce\\PayPalCommerce\\AdminNotices\\Repository\\Repository' => $baseDir . '/modules/ppcp-admin-notices/src/Repository/class-repository.php',
15
- 'WooCommerce\\PayPalCommerce\\AdminNotices\\Repository\\RepositoryInterface' => $baseDir . '/modules/ppcp-admin-notices/src/Repository/class-repositoryinterface.php',
16
- 'WooCommerce\\PayPalCommerce\\ApiClient\\ApiModule' => $baseDir . '/modules/ppcp-api-client/src/class-apimodule.php',
17
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Authentication\\Bearer' => $baseDir . '/modules/ppcp-api-client/src/Authentication/class-bearer.php',
18
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Authentication\\ConnectBearer' => $baseDir . '/modules/ppcp-api-client/src/Authentication/class-connectbearer.php',
19
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Authentication\\PayPalBearer' => $baseDir . '/modules/ppcp-api-client/src/Authentication/class-paypalbearer.php',
20
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Endpoint\\IdentityToken' => $baseDir . '/modules/ppcp-api-client/src/Endpoint/class-identitytoken.php',
21
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Endpoint\\LoginSeller' => $baseDir . '/modules/ppcp-api-client/src/Endpoint/class-loginseller.php',
22
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Endpoint\\OrderEndpoint' => $baseDir . '/modules/ppcp-api-client/src/Endpoint/class-orderendpoint.php',
23
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Endpoint\\PartnerReferrals' => $baseDir . '/modules/ppcp-api-client/src/Endpoint/class-partnerreferrals.php',
24
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Endpoint\\PartnersEndpoint' => $baseDir . '/modules/ppcp-api-client/src/Endpoint/class-partnersendpoint.php',
25
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Endpoint\\PaymentTokenEndpoint' => $baseDir . '/modules/ppcp-api-client/src/Endpoint/class-paymenttokenendpoint.php',
26
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Endpoint\\PaymentsEndpoint' => $baseDir . '/modules/ppcp-api-client/src/Endpoint/class-paymentsendpoint.php',
27
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Endpoint\\RequestTrait' => $baseDir . '/modules/ppcp-api-client/src/Endpoint/class-requesttrait.php',
28
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Endpoint\\WebhookEndpoint' => $baseDir . '/modules/ppcp-api-client/src/Endpoint/class-webhookendpoint.php',
29
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\Address' => $baseDir . '/modules/ppcp-api-client/src/Entity/class-address.php',
30
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\Amount' => $baseDir . '/modules/ppcp-api-client/src/Entity/class-amount.php',
31
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\AmountBreakdown' => $baseDir . '/modules/ppcp-api-client/src/Entity/class-amountbreakdown.php',
32
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\ApplicationContext' => $baseDir . '/modules/ppcp-api-client/src/Entity/class-applicationcontext.php',
33
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\Authorization' => $baseDir . '/modules/ppcp-api-client/src/Entity/class-authorization.php',
34
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\AuthorizationStatus' => $baseDir . '/modules/ppcp-api-client/src/Entity/class-authorizationstatus.php',
35
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\AuthorizationStatusDetails' => $baseDir . '/modules/ppcp-api-client/src/Entity/class-authorizationstatusdetails.php',
36
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\CaptureStatus' => $baseDir . '/modules/ppcp-api-client/src/Entity/class-capturestatus.php',
37
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\CaptureStatusDetails' => $baseDir . '/modules/ppcp-api-client/src/Entity/class-capturestatusdetails.php',
38
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\CardAuthenticationResult' => $baseDir . '/modules/ppcp-api-client/src/Entity/class-cardauthenticationresult.php',
39
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\Item' => $baseDir . '/modules/ppcp-api-client/src/Entity/class-item.php',
40
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\Money' => $baseDir . '/modules/ppcp-api-client/src/Entity/class-money.php',
41
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\Order' => $baseDir . '/modules/ppcp-api-client/src/Entity/class-order.php',
42
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\OrderStatus' => $baseDir . '/modules/ppcp-api-client/src/Entity/class-orderstatus.php',
43
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\Patch' => $baseDir . '/modules/ppcp-api-client/src/Entity/class-patch.php',
44
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\PatchCollection' => $baseDir . '/modules/ppcp-api-client/src/Entity/class-patchcollection.php',
45
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\Payee' => $baseDir . '/modules/ppcp-api-client/src/Entity/class-payee.php',
46
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\Payer' => $baseDir . '/modules/ppcp-api-client/src/Entity/class-payer.php',
47
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\PayerName' => $baseDir . '/modules/ppcp-api-client/src/Entity/class-payername.php',
48
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\PayerTaxInfo' => $baseDir . '/modules/ppcp-api-client/src/Entity/class-payertaxinfo.php',
49
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\PaymentMethod' => $baseDir . '/modules/ppcp-api-client/src/Entity/class-paymentmethod.php',
50
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\PaymentSource' => $baseDir . '/modules/ppcp-api-client/src/Entity/class-paymentsource.php',
51
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\PaymentSourceCard' => $baseDir . '/modules/ppcp-api-client/src/Entity/class-paymentsourcecard.php',
52
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\PaymentSourceWallet' => $baseDir . '/modules/ppcp-api-client/src/Entity/class-paymentsourcewallet.php',
53
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\PaymentToken' => $baseDir . '/modules/ppcp-api-client/src/Entity/class-paymenttoken.php',
54
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\Payments' => $baseDir . '/modules/ppcp-api-client/src/Entity/class-payments.php',
55
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\Phone' => $baseDir . '/modules/ppcp-api-client/src/Entity/class-phone.php',
56
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\PhoneWithType' => $baseDir . '/modules/ppcp-api-client/src/Entity/class-phonewithtype.php',
57
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\PurchaseUnit' => $baseDir . '/modules/ppcp-api-client/src/Entity/class-purchaseunit.php',
58
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\Refund' => $baseDir . '/modules/ppcp-api-client/src/Entity/class-refund.php',
59
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\SellerStatus' => $baseDir . '/modules/ppcp-api-client/src/Entity/class-sellerstatus.php',
60
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\SellerStatusProduct' => $baseDir . '/modules/ppcp-api-client/src/Entity/class-sellerstatusproduct.php',
61
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\Shipping' => $baseDir . '/modules/ppcp-api-client/src/Entity/class-shipping.php',
62
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\Token' => $baseDir . '/modules/ppcp-api-client/src/Entity/class-token.php',
63
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\Webhook' => $baseDir . '/modules/ppcp-api-client/src/Entity/class-webhook.php',
64
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\WebhookEvent' => $baseDir . '/modules/ppcp-api-client/src/Entity/class-webhookevent.php',
65
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Exception\\NotFoundException' => $baseDir . '/modules/ppcp-api-client/src/Exception/class-notfoundexception.php',
66
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Exception\\PayPalApiException' => $baseDir . '/modules/ppcp-api-client/src/Exception/class-paypalapiexception.php',
67
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Exception\\RuntimeException' => $baseDir . '/modules/ppcp-api-client/src/Exception/class-runtimeexception.php',
68
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Factory\\AddressFactory' => $baseDir . '/modules/ppcp-api-client/src/Factory/class-addressfactory.php',
69
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Factory\\AmountFactory' => $baseDir . '/modules/ppcp-api-client/src/Factory/class-amountfactory.php',
70
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Factory\\ApplicationContextFactory' => $baseDir . '/modules/ppcp-api-client/src/Factory/class-applicationcontextfactory.php',
71
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Factory\\AuthorizationFactory' => $baseDir . '/modules/ppcp-api-client/src/Factory/class-authorizationfactory.php',
72
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Factory\\CaptureFactory' => $baseDir . '/modules/ppcp-api-client/src/Factory/class-capturefactory.php',
73
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Factory\\ItemFactory' => $baseDir . '/modules/ppcp-api-client/src/Factory/class-itemfactory.php',
74
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Factory\\OrderFactory' => $baseDir . '/modules/ppcp-api-client/src/Factory/class-orderfactory.php',
75
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Factory\\PatchCollectionFactory' => $baseDir . '/modules/ppcp-api-client/src/Factory/class-patchcollectionfactory.php',
76
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Factory\\PayeeFactory' => $baseDir . '/modules/ppcp-api-client/src/Factory/class-payeefactory.php',
77
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Factory\\PayerFactory' => $baseDir . '/modules/ppcp-api-client/src/Factory/class-payerfactory.php',
78
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Factory\\PaymentSourceFactory' => $baseDir . '/modules/ppcp-api-client/src/Factory/class-paymentsourcefactory.php',
79
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Factory\\PaymentTokenFactory' => $baseDir . '/modules/ppcp-api-client/src/Factory/class-paymenttokenfactory.php',
80
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Factory\\PaymentsFactory' => $baseDir . '/modules/ppcp-api-client/src/Factory/class-paymentsfactory.php',
81
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Factory\\PurchaseUnitFactory' => $baseDir . '/modules/ppcp-api-client/src/Factory/class-purchaseunitfactory.php',
82
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Factory\\SellerStatusFactory' => $baseDir . '/modules/ppcp-api-client/src/Factory/class-sellerstatusfactory.php',
83
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Factory\\ShippingFactory' => $baseDir . '/modules/ppcp-api-client/src/Factory/class-shippingfactory.php',
84
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Factory\\WebhookEventFactory' => $baseDir . '/modules/ppcp-api-client/src/Factory/class-webhookeventfactory.php',
85
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Factory\\WebhookFactory' => $baseDir . '/modules/ppcp-api-client/src/Factory/class-webhookfactory.php',
86
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Helper\\Cache' => $baseDir . '/modules/ppcp-api-client/src/Helper/class-cache.php',
87
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Helper\\DccApplies' => $baseDir . '/modules/ppcp-api-client/src/Helper/class-dccapplies.php',
88
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Helper\\ErrorResponse' => $baseDir . '/modules/ppcp-api-client/src/Helper/class-errorresponse.php',
89
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Repository\\ApplicationContextRepository' => $baseDir . '/modules/ppcp-api-client/src/Repository/class-applicationcontextrepository.php',
90
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Repository\\CartRepository' => $baseDir . '/modules/ppcp-api-client/src/Repository/class-cartrepository.php',
91
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Repository\\PartnerReferralsData' => $baseDir . '/modules/ppcp-api-client/src/Repository/class-partnerreferralsdata.php',
92
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Repository\\PayPalRequestIdRepository' => $baseDir . '/modules/ppcp-api-client/src/Repository/class-paypalrequestidrepository.php',
93
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Repository\\PayeeRepository' => $baseDir . '/modules/ppcp-api-client/src/Repository/class-payeerepository.php',
94
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Repository\\PurchaseUnitRepositoryInterface' => $baseDir . '/modules/ppcp-api-client/src/Repository/class-purchaseunitrepositoryinterface.php',
95
- 'WooCommerce\\PayPalCommerce\\Button\\Assets\\DisabledSmartButton' => $baseDir . '/modules/ppcp-button/src/Assets/class-disabledsmartbutton.php',
96
- 'WooCommerce\\PayPalCommerce\\Button\\Assets\\SmartButton' => $baseDir . '/modules/ppcp-button/src/Assets/class-smartbutton.php',
97
- 'WooCommerce\\PayPalCommerce\\Button\\Assets\\SmartButtonInterface' => $baseDir . '/modules/ppcp-button/src/Assets/class-smartbuttoninterface.php',
98
- 'WooCommerce\\PayPalCommerce\\Button\\ButtonModule' => $baseDir . '/modules/ppcp-button/src/class-buttonmodule.php',
99
- 'WooCommerce\\PayPalCommerce\\Button\\Endpoint\\ApproveOrderEndpoint' => $baseDir . '/modules/ppcp-button/src/Endpoint/class-approveorderendpoint.php',
100
- 'WooCommerce\\PayPalCommerce\\Button\\Endpoint\\ChangeCartEndpoint' => $baseDir . '/modules/ppcp-button/src/Endpoint/class-changecartendpoint.php',
101
- 'WooCommerce\\PayPalCommerce\\Button\\Endpoint\\CreateOrderEndpoint' => $baseDir . '/modules/ppcp-button/src/Endpoint/class-createorderendpoint.php',
102
- 'WooCommerce\\PayPalCommerce\\Button\\Endpoint\\DataClientIdEndpoint' => $baseDir . '/modules/ppcp-button/src/Endpoint/class-dataclientidendpoint.php',
103
- 'WooCommerce\\PayPalCommerce\\Button\\Endpoint\\EndpointInterface' => $baseDir . '/modules/ppcp-button/src/Endpoint/class-endpointinterface.php',
104
- 'WooCommerce\\PayPalCommerce\\Button\\Endpoint\\RequestData' => $baseDir . '/modules/ppcp-button/src/Endpoint/class-requestdata.php',
105
- 'WooCommerce\\PayPalCommerce\\Button\\Exception\\RuntimeException' => $baseDir . '/modules/ppcp-button/src/Exception/class-runtimeexception.php',
106
- 'WooCommerce\\PayPalCommerce\\Button\\Helper\\EarlyOrderHandler' => $baseDir . '/modules/ppcp-button/src/Helper/class-earlyorderhandler.php',
107
- 'WooCommerce\\PayPalCommerce\\Button\\Helper\\MessagesApply' => $baseDir . '/modules/ppcp-button/src/Helper/class-messagesapply.php',
108
- 'WooCommerce\\PayPalCommerce\\Button\\Helper\\MessagesDisclaimers' => $baseDir . '/modules/ppcp-button/src/Helper/class-messagesdisclaimers.php',
109
- 'WooCommerce\\PayPalCommerce\\Button\\Helper\\ThreeDSecure' => $baseDir . '/modules/ppcp-button/src/Helper/class-threedsecure.php',
110
- 'WooCommerce\\PayPalCommerce\\Compat\\CompatModule' => $baseDir . '/modules/ppcp-compat/src/class-compatmodule.php',
111
- 'WooCommerce\\PayPalCommerce\\Compat\\PPEC\\DeactivateNote' => $baseDir . '/modules/ppcp-compat/src/PPEC/class-deactivatenote.php',
112
- 'WooCommerce\\PayPalCommerce\\Compat\\PPEC\\MockGateway' => $baseDir . '/modules/ppcp-compat/src/PPEC/class-mockgateway.php',
113
- 'WooCommerce\\PayPalCommerce\\Compat\\PPEC\\PPECHelper' => $baseDir . '/modules/ppcp-compat/src/PPEC/class-ppechelper.php',
114
- 'WooCommerce\\PayPalCommerce\\Compat\\PPEC\\SettingsImporter' => $baseDir . '/modules/ppcp-compat/src/PPEC/class-settingsimporter.php',
115
- 'WooCommerce\\PayPalCommerce\\Compat\\PPEC\\SubscriptionsHandler' => $baseDir . '/modules/ppcp-compat/src/PPEC/class-subscriptionshandler.php',
116
- 'WooCommerce\\PayPalCommerce\\Onboarding\\Assets\\OnboardingAssets' => $baseDir . '/modules/ppcp-onboarding/src/Assets/class-onboardingassets.php',
117
- 'WooCommerce\\PayPalCommerce\\Onboarding\\Endpoint\\LoginSellerEndpoint' => $baseDir . '/modules/ppcp-onboarding/src/Endpoint/class-loginsellerendpoint.php',
118
- 'WooCommerce\\PayPalCommerce\\Onboarding\\Environment' => $baseDir . '/modules/ppcp-onboarding/src/class-environment.php',
119
- 'WooCommerce\\PayPalCommerce\\Onboarding\\OnboardingModule' => $baseDir . '/modules/ppcp-onboarding/src/class-onboardingmodule.php',
120
- 'WooCommerce\\PayPalCommerce\\Onboarding\\Onboarding_REST_Controller' => $baseDir . '/modules/ppcp-onboarding/src/class-onboarding-rest-controller.php',
121
- 'WooCommerce\\PayPalCommerce\\Onboarding\\Render\\OnboardingRenderer' => $baseDir . '/modules/ppcp-onboarding/src/Render/class-onboardingrenderer.php',
122
- 'WooCommerce\\PayPalCommerce\\Onboarding\\State' => $baseDir . '/modules/ppcp-onboarding/src/class-state.php',
123
- 'WooCommerce\\PayPalCommerce\\PluginModule' => $baseDir . '/src/class-pluginmodule.php',
124
- 'WooCommerce\\PayPalCommerce\\Session\\Cancellation\\CancelController' => $baseDir . '/modules/ppcp-session/src/Cancellation/class-cancelcontroller.php',
125
- 'WooCommerce\\PayPalCommerce\\Session\\Cancellation\\CancelView' => $baseDir . '/modules/ppcp-session/src/Cancellation/class-cancelview.php',
126
- 'WooCommerce\\PayPalCommerce\\Session\\SessionHandler' => $baseDir . '/modules/ppcp-session/src/class-sessionhandler.php',
127
- 'WooCommerce\\PayPalCommerce\\Session\\SessionModule' => $baseDir . '/modules/ppcp-session/src/class-sessionmodule.php',
128
- 'WooCommerce\\PayPalCommerce\\StatusReport\\Renderer' => $baseDir . '/modules/ppcp-status-report/src/class-renderer.php',
129
- 'WooCommerce\\PayPalCommerce\\StatusReport\\StatusReportModule' => $baseDir . '/modules/ppcp-status-report/src/class-statusreportmodule.php',
130
- 'WooCommerce\\PayPalCommerce\\Subscription\\Helper\\SubscriptionHelper' => $baseDir . '/modules/ppcp-subscription/src/Helper/class-subscriptionhelper.php',
131
- 'WooCommerce\\PayPalCommerce\\Subscription\\RenewalHandler' => $baseDir . '/modules/ppcp-subscription/src/class-renewalhandler.php',
132
- 'WooCommerce\\PayPalCommerce\\Subscription\\SubscriptionModule' => $baseDir . '/modules/ppcp-subscription/src/class-subscriptionmodule.php',
133
- 'WooCommerce\\PayPalCommerce\\Vaulting\\Assets\\MyAccountPaymentsAssets' => $baseDir . '/modules/ppcp-vaulting/src/Assets/class-myaccountpaymentsassets.php',
134
- 'WooCommerce\\PayPalCommerce\\Vaulting\\Endpoint\\DeletePaymentTokenEndpoint' => $baseDir . '/modules/ppcp-vaulting/src/Endpoint/class-deletepaymenttokenendpoint.php',
135
- 'WooCommerce\\PayPalCommerce\\Vaulting\\PaymentTokenRepository' => $baseDir . '/modules/ppcp-vaulting/src/class-paymenttokenrepository.php',
136
- 'WooCommerce\\PayPalCommerce\\Vaulting\\PaymentTokensRenderer' => $baseDir . '/modules/ppcp-vaulting/src/class-paymenttokensrenderer.php',
137
- 'WooCommerce\\PayPalCommerce\\Vaulting\\VaultingModule' => $baseDir . '/modules/ppcp-vaulting/src/class-vaultingmodule.php',
138
- 'WooCommerce\\PayPalCommerce\\WcGateway\\Admin\\OrderTablePaymentStatusColumn' => $baseDir . '/modules/ppcp-wc-gateway/src/Admin/class-ordertablepaymentstatuscolumn.php',
139
- 'WooCommerce\\PayPalCommerce\\WcGateway\\Admin\\PaymentStatusOrderDetail' => $baseDir . '/modules/ppcp-wc-gateway/src/Admin/class-paymentstatusorderdetail.php',
140
- 'WooCommerce\\PayPalCommerce\\WcGateway\\Admin\\RenderAuthorizeAction' => $baseDir . '/modules/ppcp-wc-gateway/src/Admin/class-renderauthorizeaction.php',
141
- 'WooCommerce\\PayPalCommerce\\WcGateway\\Assets\\SettingsPageAssets' => $baseDir . '/modules/ppcp-wc-gateway/src/Assets/class-settingspageassets.php',
142
- 'WooCommerce\\PayPalCommerce\\WcGateway\\Assets\\WebhooksStatusPageAssets' => $baseDir . '/modules/ppcp-webhooks/src/Status/Assets/class-webhooksstatuspageassets.php',
143
- 'WooCommerce\\PayPalCommerce\\WcGateway\\Checkout\\CheckoutPayPalAddressPreset' => $baseDir . '/modules/ppcp-wc-gateway/src/Checkout/class-checkoutpaypaladdresspreset.php',
144
- 'WooCommerce\\PayPalCommerce\\WcGateway\\Checkout\\DisableGateways' => $baseDir . '/modules/ppcp-wc-gateway/src/Checkout/class-disablegateways.php',
145
- 'WooCommerce\\PayPalCommerce\\WcGateway\\Endpoint\\ReturnUrlEndpoint' => $baseDir . '/modules/ppcp-wc-gateway/src/Endpoint/class-returnurlendpoint.php',
146
- 'WooCommerce\\PayPalCommerce\\WcGateway\\Exception\\NotFoundException' => $baseDir . '/modules/ppcp-wc-gateway/src/Exception/class-notfoundexception.php',
147
- 'WooCommerce\\PayPalCommerce\\WcGateway\\Gateway\\CreditCardGateway' => $baseDir . '/modules/ppcp-wc-gateway/src/Gateway/class-creditcardgateway.php',
148
- 'WooCommerce\\PayPalCommerce\\WcGateway\\Gateway\\PayPalGateway' => $baseDir . '/modules/ppcp-wc-gateway/src/Gateway/class-paypalgateway.php',
149
- 'WooCommerce\\PayPalCommerce\\WcGateway\\Gateway\\ProcessPaymentTrait' => $baseDir . '/modules/ppcp-wc-gateway/src/Gateway/class-processpaymenttrait.php',
150
- 'WooCommerce\\PayPalCommerce\\WcGateway\\Gateway\\TransactionUrlProvider' => $baseDir . '/modules/ppcp-wc-gateway/src/Gateway/class-transactionurlprovider.php',
151
- 'WooCommerce\\PayPalCommerce\\WcGateway\\Notice\\AuthorizeOrderActionNotice' => $baseDir . '/modules/ppcp-wc-gateway/src/Notice/class-authorizeorderactionnotice.php',
152
- 'WooCommerce\\PayPalCommerce\\WcGateway\\Notice\\ConnectAdminNotice' => $baseDir . '/modules/ppcp-wc-gateway/src/Notice/class-connectadminnotice.php',
153
- 'WooCommerce\\PayPalCommerce\\WcGateway\\Notice\\DccWithoutPayPalAdminNotice' => $baseDir . '/modules/ppcp-wc-gateway/src/Notice/class-dccwithoutpaypaladminnotice.php',
154
- 'WooCommerce\\PayPalCommerce\\WcGateway\\Processor\\AuthorizedPaymentsProcessor' => $baseDir . '/modules/ppcp-wc-gateway/src/Processor/class-authorizedpaymentsprocessor.php',
155
- 'WooCommerce\\PayPalCommerce\\WcGateway\\Processor\\OrderMetaTrait' => $baseDir . '/modules/ppcp-wc-gateway/src/Processor/class-ordermetatrait.php',
156
- 'WooCommerce\\PayPalCommerce\\WcGateway\\Processor\\OrderProcessor' => $baseDir . '/modules/ppcp-wc-gateway/src/Processor/class-orderprocessor.php',
157
- 'WooCommerce\\PayPalCommerce\\WcGateway\\Processor\\PaymentsStatusHandlingTrait' => $baseDir . '/modules/ppcp-wc-gateway/src/Processor/class-paymentstatushandlingtrait.php',
158
- 'WooCommerce\\PayPalCommerce\\WcGateway\\Processor\\RefundProcessor' => $baseDir . '/modules/ppcp-wc-gateway/src/Processor/class-refundprocessor.php',
159
- 'WooCommerce\\PayPalCommerce\\WcGateway\\Settings\\PageMatcherTrait' => $baseDir . '/modules/ppcp-wc-gateway/src/Settings/class-pagematchertrait.php',
160
- 'WooCommerce\\PayPalCommerce\\WcGateway\\Settings\\SectionsRenderer' => $baseDir . '/modules/ppcp-wc-gateway/src/Settings/class-sectionsrenderer.php',
161
- 'WooCommerce\\PayPalCommerce\\WcGateway\\Settings\\Settings' => $baseDir . '/modules/ppcp-wc-gateway/src/Settings/class-settings.php',
162
- 'WooCommerce\\PayPalCommerce\\WcGateway\\Settings\\SettingsListener' => $baseDir . '/modules/ppcp-wc-gateway/src/Settings/class-settingslistener.php',
163
- 'WooCommerce\\PayPalCommerce\\WcGateway\\Settings\\SettingsRenderer' => $baseDir . '/modules/ppcp-wc-gateway/src/Settings/class-settingsrenderer.php',
164
- 'WooCommerce\\PayPalCommerce\\WcGateway\\WcGatewayModule' => $baseDir . '/modules/ppcp-wc-gateway/src/class-wcgatewaymodule.php',
165
- 'WooCommerce\\PayPalCommerce\\Webhooks\\Endpoint\\ResubscribeEndpoint' => $baseDir . '/modules/ppcp-webhooks/src/Endpoint/class-resubscribeendpoint.php',
166
- 'WooCommerce\\PayPalCommerce\\Webhooks\\Endpoint\\SimulateEndpoint' => $baseDir . '/modules/ppcp-webhooks/src/Endpoint/class-simulateendpoint.php',
167
- 'WooCommerce\\PayPalCommerce\\Webhooks\\Endpoint\\SimulationStateEndpoint' => $baseDir . '/modules/ppcp-webhooks/src/Endpoint/class-simulationstateendpoint.php',
168
- 'WooCommerce\\PayPalCommerce\\Webhooks\\Handler\\CheckoutOrderApproved' => $baseDir . '/modules/ppcp-webhooks/src/Handler/class-checkoutorderapproved.php',
169
- 'WooCommerce\\PayPalCommerce\\Webhooks\\Handler\\CheckoutOrderCompleted' => $baseDir . '/modules/ppcp-webhooks/src/Handler/class-checkoutordercompleted.php',
170
- 'WooCommerce\\PayPalCommerce\\Webhooks\\Handler\\PaymentCaptureCompleted' => $baseDir . '/modules/ppcp-webhooks/src/Handler/class-paymentcapturecompleted.php',
171
- 'WooCommerce\\PayPalCommerce\\Webhooks\\Handler\\PaymentCaptureRefunded' => $baseDir . '/modules/ppcp-webhooks/src/Handler/class-paymentcapturerefunded.php',
172
- 'WooCommerce\\PayPalCommerce\\Webhooks\\Handler\\PaymentCaptureReversed' => $baseDir . '/modules/ppcp-webhooks/src/Handler/class-paymentcapturereversed.php',
173
- 'WooCommerce\\PayPalCommerce\\Webhooks\\Handler\\PrefixTrait' => $baseDir . '/modules/ppcp-webhooks/src/Handler/class-prefixtrait.php',
174
- 'WooCommerce\\PayPalCommerce\\Webhooks\\Handler\\RequestHandler' => $baseDir . '/modules/ppcp-webhooks/src/Handler/class-requesthandler.php',
175
- 'WooCommerce\\PayPalCommerce\\Webhooks\\IncomingWebhookEndpoint' => $baseDir . '/modules/ppcp-webhooks/src/class-incomingwebhookendpoint.php',
176
- 'WooCommerce\\PayPalCommerce\\Webhooks\\Status\\WebhookSimulation' => $baseDir . '/modules/ppcp-webhooks/src/Status/class-webhooksimulation.php',
177
- 'WooCommerce\\PayPalCommerce\\Webhooks\\Status\\WebhooksStatusPage' => $baseDir . '/modules/ppcp-webhooks/src/Status/class-webhooksstatuspage.php',
178
- 'WooCommerce\\PayPalCommerce\\Webhooks\\WebhookModule' => $baseDir . '/modules/ppcp-webhooks/src/class-webhookmodule.php',
179
- 'WooCommerce\\PayPalCommerce\\Webhooks\\WebhookRegistrar' => $baseDir . '/modules/ppcp-webhooks/src/class-webhookregistrar.php',
180
- 'WooCommerce\\WooCommerce\\Logging\\Logger\\NullLogger' => $baseDir . '/modules/woocommerce-logging/src/Logger/class-nulllogger.php',
181
- 'WooCommerce\\WooCommerce\\Logging\\Logger\\WooCommerceLogger' => $baseDir . '/modules/woocommerce-logging/src/Logger/class-woocommercelogger.php',
182
- 'WooCommerce\\WooCommerce\\Logging\\WooCommerceLoggingModule' => $baseDir . '/modules/woocommerce-logging/src/class-woocommerceloggingmodule.php',
183
- 'Woocommerce\\PayPalCommerce\\ApiClient\\Entity\\Capture' => $baseDir . '/modules/ppcp-api-client/src/Entity/class-capture.php',
184
- 'Woocommerce\\PayPalCommerce\\WcGateway\\Helper\\DccProductStatus' => $baseDir . '/modules/ppcp-wc-gateway/src/Helper/class-dccproductstatus.php',
185
- 'Woocommerce\\PayPalCommerce\\WcGateway\\Helper\\SettingsStatus' => $baseDir . '/modules/ppcp-wc-gateway/src/Helper/class-settingsstatus.php',
186
  );
6
  $baseDir = dirname($vendorDir);
7
 
8
  return array(
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9
  );
vendor/composer/autoload_psr4.php CHANGED
@@ -6,15 +6,24 @@ $vendorDir = dirname(dirname(__FILE__));
6
  $baseDir = dirname($vendorDir);
7
 
8
  return array(
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9
  'Psr\\Log\\' => array($vendorDir . '/psr/log/Psr/Log'),
10
  'Psr\\Container\\' => array($vendorDir . '/psr/container/src'),
11
  'Interop\\Container\\' => array($vendorDir . '/container-interop/service-provider/src'),
12
- 'Dhii\\Wp\\Containers\\' => array($vendorDir . '/dhii/wp-containers/src'),
13
- 'Dhii\\Util\\String\\' => array($vendorDir . '/dhii/stringable-interface/src'),
14
  'Dhii\\Modular\\Module\\' => array($vendorDir . '/dhii/module-interface/src'),
15
- 'Dhii\\Factory\\' => array($vendorDir . '/dhii/factory-interface/src'),
16
- 'Dhii\\Exception\\' => array($vendorDir . '/dhii/exception-interface/src'),
17
- 'Dhii\\Data\\Container\\' => array($vendorDir . '/dhii/data-container-interface/src'),
18
  'Dhii\\Container\\' => array($vendorDir . '/dhii/containers/src'),
19
  'Dhii\\Collection\\' => array($vendorDir . '/dhii/collections-interface/src'),
20
  );
6
  $baseDir = dirname($vendorDir);
7
 
8
  return array(
9
+ 'WooCommerce\\WooCommerce\\Logging\\' => array($baseDir . '/modules/woocommerce-logging/src'),
10
+ 'WooCommerce\\PayPalCommerce\\Webhooks\\' => array($baseDir . '/modules/ppcp-webhooks/src'),
11
+ 'WooCommerce\\PayPalCommerce\\WcGateway\\' => array($baseDir . '/modules/ppcp-wc-gateway/src'),
12
+ 'WooCommerce\\PayPalCommerce\\Vaulting\\' => array($baseDir . '/modules/ppcp-vaulting/src'),
13
+ 'WooCommerce\\PayPalCommerce\\Subscription\\' => array($baseDir . '/modules/ppcp-subscription/src'),
14
+ 'WooCommerce\\PayPalCommerce\\StatusReport\\' => array($baseDir . '/modules/ppcp-status-report/src'),
15
+ 'WooCommerce\\PayPalCommerce\\Session\\' => array($baseDir . '/modules/ppcp-session/src'),
16
+ 'WooCommerce\\PayPalCommerce\\Onboarding\\' => array($baseDir . '/modules/ppcp-onboarding/src'),
17
+ 'WooCommerce\\PayPalCommerce\\Compat\\' => array($baseDir . '/modules/ppcp-compat/src'),
18
+ 'WooCommerce\\PayPalCommerce\\Button\\' => array($baseDir . '/modules/ppcp-button/src'),
19
+ 'WooCommerce\\PayPalCommerce\\ApiClient\\' => array($baseDir . '/modules/ppcp-api-client/src'),
20
+ 'WooCommerce\\PayPalCommerce\\AdminNotices\\' => array($baseDir . '/modules/ppcp-admin-notices/src'),
21
+ 'WooCommerce\\PayPalCommerce\\' => array($baseDir . '/src'),
22
+ 'Wikimedia\\Composer\\' => array($vendorDir . '/wikimedia/composer-merge-plugin/src'),
23
  'Psr\\Log\\' => array($vendorDir . '/psr/log/Psr/Log'),
24
  'Psr\\Container\\' => array($vendorDir . '/psr/container/src'),
25
  'Interop\\Container\\' => array($vendorDir . '/container-interop/service-provider/src'),
 
 
26
  'Dhii\\Modular\\Module\\' => array($vendorDir . '/dhii/module-interface/src'),
 
 
 
27
  'Dhii\\Container\\' => array($vendorDir . '/dhii/containers/src'),
28
  'Dhii\\Collection\\' => array($vendorDir . '/dhii/collections-interface/src'),
29
  );
vendor/composer/autoload_real.php CHANGED
@@ -2,7 +2,7 @@
2
 
3
  // autoload_real.php @generated by Composer
4
 
5
- class ComposerAutoloaderInit4607be6ea28f9ff73f3cf09747918e4b
6
  {
7
  private static $loader;
8
 
@@ -22,17 +22,15 @@ class ComposerAutoloaderInit4607be6ea28f9ff73f3cf09747918e4b
22
  return self::$loader;
23
  }
24
 
25
- require __DIR__ . '/platform_check.php';
26
-
27
- spl_autoload_register(array('ComposerAutoloaderInit4607be6ea28f9ff73f3cf09747918e4b', 'loadClassLoader'), true, true);
28
- self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(\dirname(__FILE__)));
29
- spl_autoload_unregister(array('ComposerAutoloaderInit4607be6ea28f9ff73f3cf09747918e4b', 'loadClassLoader'));
30
 
31
  $useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());
32
  if ($useStaticLoader) {
33
- require __DIR__ . '/autoload_static.php';
34
 
35
- call_user_func(\Composer\Autoload\ComposerStaticInit4607be6ea28f9ff73f3cf09747918e4b::getInitializer($loader));
36
  } else {
37
  $map = require __DIR__ . '/autoload_namespaces.php';
38
  foreach ($map as $namespace => $path) {
@@ -53,19 +51,19 @@ class ComposerAutoloaderInit4607be6ea28f9ff73f3cf09747918e4b
53
  $loader->register(true);
54
 
55
  if ($useStaticLoader) {
56
- $includeFiles = Composer\Autoload\ComposerStaticInit4607be6ea28f9ff73f3cf09747918e4b::$files;
57
  } else {
58
  $includeFiles = require __DIR__ . '/autoload_files.php';
59
  }
60
  foreach ($includeFiles as $fileIdentifier => $file) {
61
- composerRequire4607be6ea28f9ff73f3cf09747918e4b($fileIdentifier, $file);
62
  }
63
 
64
  return $loader;
65
  }
66
  }
67
 
68
- function composerRequire4607be6ea28f9ff73f3cf09747918e4b($fileIdentifier, $file)
69
  {
70
  if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
71
  require $file;
2
 
3
  // autoload_real.php @generated by Composer
4
 
5
+ class ComposerAutoloaderInit3acb3642cf46c3f8b0d913579e285e9c
6
  {
7
  private static $loader;
8
 
22
  return self::$loader;
23
  }
24
 
25
+ spl_autoload_register(array('ComposerAutoloaderInit3acb3642cf46c3f8b0d913579e285e9c', 'loadClassLoader'), true, true);
26
+ self::$loader = $loader = new \Composer\Autoload\ClassLoader();
27
+ spl_autoload_unregister(array('ComposerAutoloaderInit3acb3642cf46c3f8b0d913579e285e9c', 'loadClassLoader'));
 
 
28
 
29
  $useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());
30
  if ($useStaticLoader) {
31
+ require_once __DIR__ . '/autoload_static.php';
32
 
33
+ call_user_func(\Composer\Autoload\ComposerStaticInit3acb3642cf46c3f8b0d913579e285e9c::getInitializer($loader));
34
  } else {
35
  $map = require __DIR__ . '/autoload_namespaces.php';
36
  foreach ($map as $namespace => $path) {
51
  $loader->register(true);
52
 
53
  if ($useStaticLoader) {
54
+ $includeFiles = Composer\Autoload\ComposerStaticInit3acb3642cf46c3f8b0d913579e285e9c::$files;
55
  } else {
56
  $includeFiles = require __DIR__ . '/autoload_files.php';
57
  }
58
  foreach ($includeFiles as $fileIdentifier => $file) {
59
+ composerRequire3acb3642cf46c3f8b0d913579e285e9c($fileIdentifier, $file);
60
  }
61
 
62
  return $loader;
63
  }
64
  }
65
 
66
+ function composerRequire3acb3642cf46c3f8b0d913579e285e9c($fileIdentifier, $file)
67
  {
68
  if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
69
  require $file;
vendor/composer/autoload_static.php CHANGED
@@ -4,13 +4,30 @@
4
 
5
  namespace Composer\Autoload;
6
 
7
- class ComposerStaticInit4607be6ea28f9ff73f3cf09747918e4b
8
  {
9
  public static $files = array (
10
  '7b11c4dc42b3b3023073cb14e519683c' => __DIR__ . '/..' . '/ralouphie/getallheaders/src/getallheaders.php',
11
  );
12
 
13
  public static $prefixLengthsPsr4 = array (
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
14
  'P' =>
15
  array (
16
  'Psr\\Log\\' => 8,
@@ -22,53 +39,84 @@ class ComposerStaticInit4607be6ea28f9ff73f3cf09747918e4b
22
  ),
23
  'D' =>
24
  array (
25
- 'Dhii\\Wp\\Containers\\' => 19,
26
- 'Dhii\\Util\\String\\' => 17,
27
  'Dhii\\Modular\\Module\\' => 20,
28
- 'Dhii\\Factory\\' => 13,
29
- 'Dhii\\Exception\\' => 15,
30
- 'Dhii\\Data\\Container\\' => 20,
31
  'Dhii\\Container\\' => 15,
32
  'Dhii\\Collection\\' => 16,
33
  ),
34
  );
35
 
36
  public static $prefixDirsPsr4 = array (
37
- 'Psr\\Log\\' =>
38
  array (
39
- 0 => __DIR__ . '/..' . '/psr/log/Psr/Log',
40
  ),
41
- 'Psr\\Container\\' =>
42
  array (
43
- 0 => __DIR__ . '/..' . '/psr/container/src',
44
  ),
45
- 'Interop\\Container\\' =>
46
  array (
47
- 0 => __DIR__ . '/..' . '/container-interop/service-provider/src',
48
  ),
49
- 'Dhii\\Wp\\Containers\\' =>
50
  array (
51
- 0 => __DIR__ . '/..' . '/dhii/wp-containers/src',
52
  ),
53
- 'Dhii\\Util\\String\\' =>
54
  array (
55
- 0 => __DIR__ . '/..' . '/dhii/stringable-interface/src',
56
  ),
57
- 'Dhii\\Modular\\Module\\' =>
58
  array (
59
- 0 => __DIR__ . '/..' . '/dhii/module-interface/src',
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
60
  ),
61
- 'Dhii\\Factory\\' =>
62
  array (
63
- 0 => __DIR__ . '/..' . '/dhii/factory-interface/src',
64
  ),
65
- 'Dhii\\Exception\\' =>
66
  array (
67
- 0 => __DIR__ . '/..' . '/dhii/exception-interface/src',
68
  ),
69
- 'Dhii\\Data\\Container\\' =>
70
  array (
71
- 0 => __DIR__ . '/..' . '/dhii/data-container-interface/src',
 
 
 
 
 
 
 
 
72
  ),
73
  'Dhii\\Container\\' =>
74
  array (
@@ -80,192 +128,11 @@ class ComposerStaticInit4607be6ea28f9ff73f3cf09747918e4b
80
  ),
81
  );
82
 
83
- public static $classMap = array (
84
- 'Composer\\InstalledVersions' => __DIR__ . '/..' . '/composer/InstalledVersions.php',
85
- 'WooCommerce\\PayPalCommerce\\AdminNotices\\AdminNotices' => __DIR__ . '/../..' . '/modules/ppcp-admin-notices/src/class-adminnotices.php',
86
- 'WooCommerce\\PayPalCommerce\\AdminNotices\\Entity\\Message' => __DIR__ . '/../..' . '/modules/ppcp-admin-notices/src/Entity/class-message.php',
87
- 'WooCommerce\\PayPalCommerce\\AdminNotices\\Renderer\\Renderer' => __DIR__ . '/../..' . '/modules/ppcp-admin-notices/src/Renderer/class-renderer.php',
88
- 'WooCommerce\\PayPalCommerce\\AdminNotices\\Renderer\\RendererInterface' => __DIR__ . '/../..' . '/modules/ppcp-admin-notices/src/Renderer/class-rendererinterface.php',
89
- 'WooCommerce\\PayPalCommerce\\AdminNotices\\Repository\\Repository' => __DIR__ . '/../..' . '/modules/ppcp-admin-notices/src/Repository/class-repository.php',
90
- 'WooCommerce\\PayPalCommerce\\AdminNotices\\Repository\\RepositoryInterface' => __DIR__ . '/../..' . '/modules/ppcp-admin-notices/src/Repository/class-repositoryinterface.php',
91
- 'WooCommerce\\PayPalCommerce\\ApiClient\\ApiModule' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/class-apimodule.php',
92
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Authentication\\Bearer' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Authentication/class-bearer.php',
93
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Authentication\\ConnectBearer' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Authentication/class-connectbearer.php',
94
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Authentication\\PayPalBearer' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Authentication/class-paypalbearer.php',
95
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Endpoint\\IdentityToken' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Endpoint/class-identitytoken.php',
96
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Endpoint\\LoginSeller' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Endpoint/class-loginseller.php',
97
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Endpoint\\OrderEndpoint' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Endpoint/class-orderendpoint.php',
98
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Endpoint\\PartnerReferrals' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Endpoint/class-partnerreferrals.php',
99
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Endpoint\\PartnersEndpoint' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Endpoint/class-partnersendpoint.php',
100
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Endpoint\\PaymentTokenEndpoint' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Endpoint/class-paymenttokenendpoint.php',
101
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Endpoint\\PaymentsEndpoint' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Endpoint/class-paymentsendpoint.php',
102
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Endpoint\\RequestTrait' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Endpoint/class-requesttrait.php',
103
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Endpoint\\WebhookEndpoint' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Endpoint/class-webhookendpoint.php',
104
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\Address' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Entity/class-address.php',
105
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\Amount' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Entity/class-amount.php',
106
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\AmountBreakdown' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Entity/class-amountbreakdown.php',
107
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\ApplicationContext' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Entity/class-applicationcontext.php',
108
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\Authorization' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Entity/class-authorization.php',
109
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\AuthorizationStatus' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Entity/class-authorizationstatus.php',
110
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\AuthorizationStatusDetails' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Entity/class-authorizationstatusdetails.php',
111
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\CaptureStatus' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Entity/class-capturestatus.php',
112
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\CaptureStatusDetails' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Entity/class-capturestatusdetails.php',
113
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\CardAuthenticationResult' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Entity/class-cardauthenticationresult.php',
114
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\Item' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Entity/class-item.php',
115
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\Money' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Entity/class-money.php',
116
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\Order' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Entity/class-order.php',
117
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\OrderStatus' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Entity/class-orderstatus.php',
118
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\Patch' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Entity/class-patch.php',
119
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\PatchCollection' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Entity/class-patchcollection.php',
120
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\Payee' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Entity/class-payee.php',
121
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\Payer' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Entity/class-payer.php',
122
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\PayerName' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Entity/class-payername.php',
123
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\PayerTaxInfo' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Entity/class-payertaxinfo.php',
124
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\PaymentMethod' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Entity/class-paymentmethod.php',
125
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\PaymentSource' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Entity/class-paymentsource.php',
126
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\PaymentSourceCard' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Entity/class-paymentsourcecard.php',
127
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\PaymentSourceWallet' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Entity/class-paymentsourcewallet.php',
128
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\PaymentToken' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Entity/class-paymenttoken.php',
129
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\Payments' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Entity/class-payments.php',
130
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\Phone' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Entity/class-phone.php',
131
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\PhoneWithType' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Entity/class-phonewithtype.php',
132
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\PurchaseUnit' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Entity/class-purchaseunit.php',
133
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\Refund' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Entity/class-refund.php',
134
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\SellerStatus' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Entity/class-sellerstatus.php',
135
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\SellerStatusProduct' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Entity/class-sellerstatusproduct.php',
136
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\Shipping' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Entity/class-shipping.php',
137
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\Token' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Entity/class-token.php',
138
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\Webhook' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Entity/class-webhook.php',
139
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\WebhookEvent' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Entity/class-webhookevent.php',
140
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Exception\\NotFoundException' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Exception/class-notfoundexception.php',
141
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Exception\\PayPalApiException' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Exception/class-paypalapiexception.php',
142
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Exception\\RuntimeException' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Exception/class-runtimeexception.php',
143
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Factory\\AddressFactory' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Factory/class-addressfactory.php',
144
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Factory\\AmountFactory' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Factory/class-amountfactory.php',
145
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Factory\\ApplicationContextFactory' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Factory/class-applicationcontextfactory.php',
146
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Factory\\AuthorizationFactory' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Factory/class-authorizationfactory.php',
147
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Factory\\CaptureFactory' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Factory/class-capturefactory.php',
148
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Factory\\ItemFactory' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Factory/class-itemfactory.php',
149
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Factory\\OrderFactory' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Factory/class-orderfactory.php',
150
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Factory\\PatchCollectionFactory' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Factory/class-patchcollectionfactory.php',
151
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Factory\\PayeeFactory' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Factory/class-payeefactory.php',
152
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Factory\\PayerFactory' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Factory/class-payerfactory.php',
153
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Factory\\PaymentSourceFactory' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Factory/class-paymentsourcefactory.php',
154
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Factory\\PaymentTokenFactory' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Factory/class-paymenttokenfactory.php',
155
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Factory\\PaymentsFactory' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Factory/class-paymentsfactory.php',
156
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Factory\\PurchaseUnitFactory' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Factory/class-purchaseunitfactory.php',
157
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Factory\\SellerStatusFactory' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Factory/class-sellerstatusfactory.php',
158
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Factory\\ShippingFactory' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Factory/class-shippingfactory.php',
159
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Factory\\WebhookEventFactory' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Factory/class-webhookeventfactory.php',
160
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Factory\\WebhookFactory' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Factory/class-webhookfactory.php',
161
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Helper\\Cache' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Helper/class-cache.php',
162
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Helper\\DccApplies' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Helper/class-dccapplies.php',
163
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Helper\\ErrorResponse' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Helper/class-errorresponse.php',
164
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Repository\\ApplicationContextRepository' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Repository/class-applicationcontextrepository.php',
165
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Repository\\CartRepository' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Repository/class-cartrepository.php',
166
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Repository\\PartnerReferralsData' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Repository/class-partnerreferralsdata.php',
167
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Repository\\PayPalRequestIdRepository' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Repository/class-paypalrequestidrepository.php',
168
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Repository\\PayeeRepository' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Repository/class-payeerepository.php',
169
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Repository\\PurchaseUnitRepositoryInterface' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Repository/class-purchaseunitrepositoryinterface.php',
170
- 'WooCommerce\\PayPalCommerce\\Button\\Assets\\DisabledSmartButton' => __DIR__ . '/../..' . '/modules/ppcp-button/src/Assets/class-disabledsmartbutton.php',
171
- 'WooCommerce\\PayPalCommerce\\Button\\Assets\\SmartButton' => __DIR__ . '/../..' . '/modules/ppcp-button/src/Assets/class-smartbutton.php',
172
- 'WooCommerce\\PayPalCommerce\\Button\\Assets\\SmartButtonInterface' => __DIR__ . '/../..' . '/modules/ppcp-button/src/Assets/class-smartbuttoninterface.php',
173
- 'WooCommerce\\PayPalCommerce\\Button\\ButtonModule' => __DIR__ . '/../..' . '/modules/ppcp-button/src/class-buttonmodule.php',
174
- 'WooCommerce\\PayPalCommerce\\Button\\Endpoint\\ApproveOrderEndpoint' => __DIR__ . '/../..' . '/modules/ppcp-button/src/Endpoint/class-approveorderendpoint.php',
175
- 'WooCommerce\\PayPalCommerce\\Button\\Endpoint\\ChangeCartEndpoint' => __DIR__ . '/../..' . '/modules/ppcp-button/src/Endpoint/class-changecartendpoint.php',
176
- 'WooCommerce\\PayPalCommerce\\Button\\Endpoint\\CreateOrderEndpoint' => __DIR__ . '/../..' . '/modules/ppcp-button/src/Endpoint/class-createorderendpoint.php',
177
- 'WooCommerce\\PayPalCommerce\\Button\\Endpoint\\DataClientIdEndpoint' => __DIR__ . '/../..' . '/modules/ppcp-button/src/Endpoint/class-dataclientidendpoint.php',
178
- 'WooCommerce\\PayPalCommerce\\Button\\Endpoint\\EndpointInterface' => __DIR__ . '/../..' . '/modules/ppcp-button/src/Endpoint/class-endpointinterface.php',
179
- 'WooCommerce\\PayPalCommerce\\Button\\Endpoint\\RequestData' => __DIR__ . '/../..' . '/modules/ppcp-button/src/Endpoint/class-requestdata.php',
180
- 'WooCommerce\\PayPalCommerce\\Button\\Exception\\RuntimeException' => __DIR__ . '/../..' . '/modules/ppcp-button/src/Exception/class-runtimeexception.php',
181
- 'WooCommerce\\PayPalCommerce\\Button\\Helper\\EarlyOrderHandler' => __DIR__ . '/../..' . '/modules/ppcp-button/src/Helper/class-earlyorderhandler.php',
182
- 'WooCommerce\\PayPalCommerce\\Button\\Helper\\MessagesApply' => __DIR__ . '/../..' . '/modules/ppcp-button/src/Helper/class-messagesapply.php',
183
- 'WooCommerce\\PayPalCommerce\\Button\\Helper\\MessagesDisclaimers' => __DIR__ . '/../..' . '/modules/ppcp-button/src/Helper/class-messagesdisclaimers.php',
184
- 'WooCommerce\\PayPalCommerce\\Button\\Helper\\ThreeDSecure' => __DIR__ . '/../..' . '/modules/ppcp-button/src/Helper/class-threedsecure.php',
185
- 'WooCommerce\\PayPalCommerce\\Compat\\CompatModule' => __DIR__ . '/../..' . '/modules/ppcp-compat/src/class-compatmodule.php',
186
- 'WooCommerce\\PayPalCommerce\\Compat\\PPEC\\DeactivateNote' => __DIR__ . '/../..' . '/modules/ppcp-compat/src/PPEC/class-deactivatenote.php',
187
- 'WooCommerce\\PayPalCommerce\\Compat\\PPEC\\MockGateway' => __DIR__ . '/../..' . '/modules/ppcp-compat/src/PPEC/class-mockgateway.php',
188
- 'WooCommerce\\PayPalCommerce\\Compat\\PPEC\\PPECHelper' => __DIR__ . '/../..' . '/modules/ppcp-compat/src/PPEC/class-ppechelper.php',
189
- 'WooCommerce\\PayPalCommerce\\Compat\\PPEC\\SettingsImporter' => __DIR__ . '/../..' . '/modules/ppcp-compat/src/PPEC/class-settingsimporter.php',
190
- 'WooCommerce\\PayPalCommerce\\Compat\\PPEC\\SubscriptionsHandler' => __DIR__ . '/../..' . '/modules/ppcp-compat/src/PPEC/class-subscriptionshandler.php',
191
- 'WooCommerce\\PayPalCommerce\\Onboarding\\Assets\\OnboardingAssets' => __DIR__ . '/../..' . '/modules/ppcp-onboarding/src/Assets/class-onboardingassets.php',
192
- 'WooCommerce\\PayPalCommerce\\Onboarding\\Endpoint\\LoginSellerEndpoint' => __DIR__ . '/../..' . '/modules/ppcp-onboarding/src/Endpoint/class-loginsellerendpoint.php',
193
- 'WooCommerce\\PayPalCommerce\\Onboarding\\Environment' => __DIR__ . '/../..' . '/modules/ppcp-onboarding/src/class-environment.php',
194
- 'WooCommerce\\PayPalCommerce\\Onboarding\\OnboardingModule' => __DIR__ . '/../..' . '/modules/ppcp-onboarding/src/class-onboardingmodule.php',
195
- 'WooCommerce\\PayPalCommerce\\Onboarding\\Onboarding_REST_Controller' => __DIR__ . '/../..' . '/modules/ppcp-onboarding/src/class-onboarding-rest-controller.php',
196
- 'WooCommerce\\PayPalCommerce\\Onboarding\\Render\\OnboardingRenderer' => __DIR__ . '/../..' . '/modules/ppcp-onboarding/src/Render/class-onboardingrenderer.php',
197
- 'WooCommerce\\PayPalCommerce\\Onboarding\\State' => __DIR__ . '/../..' . '/modules/ppcp-onboarding/src/class-state.php',
198
- 'WooCommerce\\PayPalCommerce\\PluginModule' => __DIR__ . '/../..' . '/src/class-pluginmodule.php',
199
- 'WooCommerce\\PayPalCommerce\\Session\\Cancellation\\CancelController' => __DIR__ . '/../..' . '/modules/ppcp-session/src/Cancellation/class-cancelcontroller.php',
200
- 'WooCommerce\\PayPalCommerce\\Session\\Cancellation\\CancelView' => __DIR__ . '/../..' . '/modules/ppcp-session/src/Cancellation/class-cancelview.php',
201
- 'WooCommerce\\PayPalCommerce\\Session\\SessionHandler' => __DIR__ . '/../..' . '/modules/ppcp-session/src/class-sessionhandler.php',
202
- 'WooCommerce\\PayPalCommerce\\Session\\SessionModule' => __DIR__ . '/../..' . '/modules/ppcp-session/src/class-sessionmodule.php',
203
- 'WooCommerce\\PayPalCommerce\\StatusReport\\Renderer' => __DIR__ . '/../..' . '/modules/ppcp-status-report/src/class-renderer.php',
204
- 'WooCommerce\\PayPalCommerce\\StatusReport\\StatusReportModule' => __DIR__ . '/../..' . '/modules/ppcp-status-report/src/class-statusreportmodule.php',
205
- 'WooCommerce\\PayPalCommerce\\Subscription\\Helper\\SubscriptionHelper' => __DIR__ . '/../..' . '/modules/ppcp-subscription/src/Helper/class-subscriptionhelper.php',
206
- 'WooCommerce\\PayPalCommerce\\Subscription\\RenewalHandler' => __DIR__ . '/../..' . '/modules/ppcp-subscription/src/class-renewalhandler.php',
207
- 'WooCommerce\\PayPalCommerce\\Subscription\\SubscriptionModule' => __DIR__ . '/../..' . '/modules/ppcp-subscription/src/class-subscriptionmodule.php',
208
- 'WooCommerce\\PayPalCommerce\\Vaulting\\Assets\\MyAccountPaymentsAssets' => __DIR__ . '/../..' . '/modules/ppcp-vaulting/src/Assets/class-myaccountpaymentsassets.php',
209
- 'WooCommerce\\PayPalCommerce\\Vaulting\\Endpoint\\DeletePaymentTokenEndpoint' => __DIR__ . '/../..' . '/modules/ppcp-vaulting/src/Endpoint/class-deletepaymenttokenendpoint.php',
210
- 'WooCommerce\\PayPalCommerce\\Vaulting\\PaymentTokenRepository' => __DIR__ . '/../..' . '/modules/ppcp-vaulting/src/class-paymenttokenrepository.php',
211
- 'WooCommerce\\PayPalCommerce\\Vaulting\\PaymentTokensRenderer' => __DIR__ . '/../..' . '/modules/ppcp-vaulting/src/class-paymenttokensrenderer.php',
212
- 'WooCommerce\\PayPalCommerce\\Vaulting\\VaultingModule' => __DIR__ . '/../..' . '/modules/ppcp-vaulting/src/class-vaultingmodule.php',
213
- 'WooCommerce\\PayPalCommerce\\WcGateway\\Admin\\OrderTablePaymentStatusColumn' => __DIR__ . '/../..' . '/modules/ppcp-wc-gateway/src/Admin/class-ordertablepaymentstatuscolumn.php',
214
- 'WooCommerce\\PayPalCommerce\\WcGateway\\Admin\\PaymentStatusOrderDetail' => __DIR__ . '/../..' . '/modules/ppcp-wc-gateway/src/Admin/class-paymentstatusorderdetail.php',
215
- 'WooCommerce\\PayPalCommerce\\WcGateway\\Admin\\RenderAuthorizeAction' => __DIR__ . '/../..' . '/modules/ppcp-wc-gateway/src/Admin/class-renderauthorizeaction.php',
216
- 'WooCommerce\\PayPalCommerce\\WcGateway\\Assets\\SettingsPageAssets' => __DIR__ . '/../..' . '/modules/ppcp-wc-gateway/src/Assets/class-settingspageassets.php',
217
- 'WooCommerce\\PayPalCommerce\\WcGateway\\Assets\\WebhooksStatusPageAssets' => __DIR__ . '/../..' . '/modules/ppcp-webhooks/src/Status/Assets/class-webhooksstatuspageassets.php',
218
- 'WooCommerce\\PayPalCommerce\\WcGateway\\Checkout\\CheckoutPayPalAddressPreset' => __DIR__ . '/../..' . '/modules/ppcp-wc-gateway/src/Checkout/class-checkoutpaypaladdresspreset.php',
219
- 'WooCommerce\\PayPalCommerce\\WcGateway\\Checkout\\DisableGateways' => __DIR__ . '/../..' . '/modules/ppcp-wc-gateway/src/Checkout/class-disablegateways.php',
220
- 'WooCommerce\\PayPalCommerce\\WcGateway\\Endpoint\\ReturnUrlEndpoint' => __DIR__ . '/../..' . '/modules/ppcp-wc-gateway/src/Endpoint/class-returnurlendpoint.php',
221
- 'WooCommerce\\PayPalCommerce\\WcGateway\\Exception\\NotFoundException' => __DIR__ . '/../..' . '/modules/ppcp-wc-gateway/src/Exception/class-notfoundexception.php',
222
- 'WooCommerce\\PayPalCommerce\\WcGateway\\Gateway\\CreditCardGateway' => __DIR__ . '/../..' . '/modules/ppcp-wc-gateway/src/Gateway/class-creditcardgateway.php',
223
- 'WooCommerce\\PayPalCommerce\\WcGateway\\Gateway\\PayPalGateway' => __DIR__ . '/../..' . '/modules/ppcp-wc-gateway/src/Gateway/class-paypalgateway.php',
224
- 'WooCommerce\\PayPalCommerce\\WcGateway\\Gateway\\ProcessPaymentTrait' => __DIR__ . '/../..' . '/modules/ppcp-wc-gateway/src/Gateway/class-processpaymenttrait.php',
225
- 'WooCommerce\\PayPalCommerce\\WcGateway\\Gateway\\TransactionUrlProvider' => __DIR__ . '/../..' . '/modules/ppcp-wc-gateway/src/Gateway/class-transactionurlprovider.php',
226
- 'WooCommerce\\PayPalCommerce\\WcGateway\\Notice\\AuthorizeOrderActionNotice' => __DIR__ . '/../..' . '/modules/ppcp-wc-gateway/src/Notice/class-authorizeorderactionnotice.php',
227
- 'WooCommerce\\PayPalCommerce\\WcGateway\\Notice\\ConnectAdminNotice' => __DIR__ . '/../..' . '/modules/ppcp-wc-gateway/src/Notice/class-connectadminnotice.php',
228
- 'WooCommerce\\PayPalCommerce\\WcGateway\\Notice\\DccWithoutPayPalAdminNotice' => __DIR__ . '/../..' . '/modules/ppcp-wc-gateway/src/Notice/class-dccwithoutpaypaladminnotice.php',
229
- 'WooCommerce\\PayPalCommerce\\WcGateway\\Processor\\AuthorizedPaymentsProcessor' => __DIR__ . '/../..' . '/modules/ppcp-wc-gateway/src/Processor/class-authorizedpaymentsprocessor.php',
230
- 'WooCommerce\\PayPalCommerce\\WcGateway\\Processor\\OrderMetaTrait' => __DIR__ . '/../..' . '/modules/ppcp-wc-gateway/src/Processor/class-ordermetatrait.php',
231
- 'WooCommerce\\PayPalCommerce\\WcGateway\\Processor\\OrderProcessor' => __DIR__ . '/../..' . '/modules/ppcp-wc-gateway/src/Processor/class-orderprocessor.php',
232
- 'WooCommerce\\PayPalCommerce\\WcGateway\\Processor\\PaymentsStatusHandlingTrait' => __DIR__ . '/../..' . '/modules/ppcp-wc-gateway/src/Processor/class-paymentstatushandlingtrait.php',
233
- 'WooCommerce\\PayPalCommerce\\WcGateway\\Processor\\RefundProcessor' => __DIR__ . '/../..' . '/modules/ppcp-wc-gateway/src/Processor/class-refundprocessor.php',
234
- 'WooCommerce\\PayPalCommerce\\WcGateway\\Settings\\PageMatcherTrait' => __DIR__ . '/../..' . '/modules/ppcp-wc-gateway/src/Settings/class-pagematchertrait.php',
235
- 'WooCommerce\\PayPalCommerce\\WcGateway\\Settings\\SectionsRenderer' => __DIR__ . '/../..' . '/modules/ppcp-wc-gateway/src/Settings/class-sectionsrenderer.php',
236
- 'WooCommerce\\PayPalCommerce\\WcGateway\\Settings\\Settings' => __DIR__ . '/../..' . '/modules/ppcp-wc-gateway/src/Settings/class-settings.php',
237
- 'WooCommerce\\PayPalCommerce\\WcGateway\\Settings\\SettingsListener' => __DIR__ . '/../..' . '/modules/ppcp-wc-gateway/src/Settings/class-settingslistener.php',
238
- 'WooCommerce\\PayPalCommerce\\WcGateway\\Settings\\SettingsRenderer' => __DIR__ . '/../..' . '/modules/ppcp-wc-gateway/src/Settings/class-settingsrenderer.php',
239
- 'WooCommerce\\PayPalCommerce\\WcGateway\\WcGatewayModule' => __DIR__ . '/../..' . '/modules/ppcp-wc-gateway/src/class-wcgatewaymodule.php',
240
- 'WooCommerce\\PayPalCommerce\\Webhooks\\Endpoint\\ResubscribeEndpoint' => __DIR__ . '/../..' . '/modules/ppcp-webhooks/src/Endpoint/class-resubscribeendpoint.php',
241
- 'WooCommerce\\PayPalCommerce\\Webhooks\\Endpoint\\SimulateEndpoint' => __DIR__ . '/../..' . '/modules/ppcp-webhooks/src/Endpoint/class-simulateendpoint.php',
242
- 'WooCommerce\\PayPalCommerce\\Webhooks\\Endpoint\\SimulationStateEndpoint' => __DIR__ . '/../..' . '/modules/ppcp-webhooks/src/Endpoint/class-simulationstateendpoint.php',
243
- 'WooCommerce\\PayPalCommerce\\Webhooks\\Handler\\CheckoutOrderApproved' => __DIR__ . '/../..' . '/modules/ppcp-webhooks/src/Handler/class-checkoutorderapproved.php',
244
- 'WooCommerce\\PayPalCommerce\\Webhooks\\Handler\\CheckoutOrderCompleted' => __DIR__ . '/../..' . '/modules/ppcp-webhooks/src/Handler/class-checkoutordercompleted.php',
245
- 'WooCommerce\\PayPalCommerce\\Webhooks\\Handler\\PaymentCaptureCompleted' => __DIR__ . '/../..' . '/modules/ppcp-webhooks/src/Handler/class-paymentcapturecompleted.php',
246
- 'WooCommerce\\PayPalCommerce\\Webhooks\\Handler\\PaymentCaptureRefunded' => __DIR__ . '/../..' . '/modules/ppcp-webhooks/src/Handler/class-paymentcapturerefunded.php',
247
- 'WooCommerce\\PayPalCommerce\\Webhooks\\Handler\\PaymentCaptureReversed' => __DIR__ . '/../..' . '/modules/ppcp-webhooks/src/Handler/class-paymentcapturereversed.php',
248
- 'WooCommerce\\PayPalCommerce\\Webhooks\\Handler\\PrefixTrait' => __DIR__ . '/../..' . '/modules/ppcp-webhooks/src/Handler/class-prefixtrait.php',
249
- 'WooCommerce\\PayPalCommerce\\Webhooks\\Handler\\RequestHandler' => __DIR__ . '/../..' . '/modules/ppcp-webhooks/src/Handler/class-requesthandler.php',
250
- 'WooCommerce\\PayPalCommerce\\Webhooks\\IncomingWebhookEndpoint' => __DIR__ . '/../..' . '/modules/ppcp-webhooks/src/class-incomingwebhookendpoint.php',
251
- 'WooCommerce\\PayPalCommerce\\Webhooks\\Status\\WebhookSimulation' => __DIR__ . '/../..' . '/modules/ppcp-webhooks/src/Status/class-webhooksimulation.php',
252
- 'WooCommerce\\PayPalCommerce\\Webhooks\\Status\\WebhooksStatusPage' => __DIR__ . '/../..' . '/modules/ppcp-webhooks/src/Status/class-webhooksstatuspage.php',
253
- 'WooCommerce\\PayPalCommerce\\Webhooks\\WebhookModule' => __DIR__ . '/../..' . '/modules/ppcp-webhooks/src/class-webhookmodule.php',
254
- 'WooCommerce\\PayPalCommerce\\Webhooks\\WebhookRegistrar' => __DIR__ . '/../..' . '/modules/ppcp-webhooks/src/class-webhookregistrar.php',
255
- 'WooCommerce\\WooCommerce\\Logging\\Logger\\NullLogger' => __DIR__ . '/../..' . '/modules/woocommerce-logging/src/Logger/class-nulllogger.php',
256
- 'WooCommerce\\WooCommerce\\Logging\\Logger\\WooCommerceLogger' => __DIR__ . '/../..' . '/modules/woocommerce-logging/src/Logger/class-woocommercelogger.php',
257
- 'WooCommerce\\WooCommerce\\Logging\\WooCommerceLoggingModule' => __DIR__ . '/../..' . '/modules/woocommerce-logging/src/class-woocommerceloggingmodule.php',
258
- 'Woocommerce\\PayPalCommerce\\ApiClient\\Entity\\Capture' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Entity/class-capture.php',
259
- 'Woocommerce\\PayPalCommerce\\WcGateway\\Helper\\DccProductStatus' => __DIR__ . '/../..' . '/modules/ppcp-wc-gateway/src/Helper/class-dccproductstatus.php',
260
- 'Woocommerce\\PayPalCommerce\\WcGateway\\Helper\\SettingsStatus' => __DIR__ . '/../..' . '/modules/ppcp-wc-gateway/src/Helper/class-settingsstatus.php',
261
- );
262
-
263
  public static function getInitializer(ClassLoader $loader)
264
  {
265
  return \Closure::bind(function () use ($loader) {
266
- $loader->prefixLengthsPsr4 = ComposerStaticInit4607be6ea28f9ff73f3cf09747918e4b::$prefixLengthsPsr4;
267
- $loader->prefixDirsPsr4 = ComposerStaticInit4607be6ea28f9ff73f3cf09747918e4b::$prefixDirsPsr4;
268
- $loader->classMap = ComposerStaticInit4607be6ea28f9ff73f3cf09747918e4b::$classMap;
269
 
270
  }, null, ClassLoader::class);
271
  }
4
 
5
  namespace Composer\Autoload;
6
 
7
+ class ComposerStaticInit3acb3642cf46c3f8b0d913579e285e9c
8
  {
9
  public static $files = array (
10
  '7b11c4dc42b3b3023073cb14e519683c' => __DIR__ . '/..' . '/ralouphie/getallheaders/src/getallheaders.php',
11
  );
12
 
13
  public static $prefixLengthsPsr4 = array (
14
+ 'W' =>
15
+ array (
16
+ 'WooCommerce\\WooCommerce\\Logging\\' => 32,
17
+ 'WooCommerce\\PayPalCommerce\\Webhooks\\' => 36,
18
+ 'WooCommerce\\PayPalCommerce\\WcGateway\\' => 37,
19
+ 'WooCommerce\\PayPalCommerce\\Vaulting\\' => 36,
20
+ 'WooCommerce\\PayPalCommerce\\Subscription\\' => 40,
21
+ 'WooCommerce\\PayPalCommerce\\StatusReport\\' => 40,
22
+ 'WooCommerce\\PayPalCommerce\\Session\\' => 35,
23
+ 'WooCommerce\\PayPalCommerce\\Onboarding\\' => 38,
24
+ 'WooCommerce\\PayPalCommerce\\Compat\\' => 34,
25
+ 'WooCommerce\\PayPalCommerce\\Button\\' => 34,
26
+ 'WooCommerce\\PayPalCommerce\\ApiClient\\' => 37,
27
+ 'WooCommerce\\PayPalCommerce\\AdminNotices\\' => 40,
28
+ 'WooCommerce\\PayPalCommerce\\' => 27,
29
+ 'Wikimedia\\Composer\\' => 19,
30
+ ),
31
  'P' =>
32
  array (
33
  'Psr\\Log\\' => 8,
39
  ),
40
  'D' =>
41
  array (
 
 
42
  'Dhii\\Modular\\Module\\' => 20,
 
 
 
43
  'Dhii\\Container\\' => 15,
44
  'Dhii\\Collection\\' => 16,
45
  ),
46
  );
47
 
48
  public static $prefixDirsPsr4 = array (
49
+ 'WooCommerce\\WooCommerce\\Logging\\' =>
50
  array (
51
+ 0 => __DIR__ . '/../..' . '/modules/woocommerce-logging/src',
52
  ),
53
+ 'WooCommerce\\PayPalCommerce\\Webhooks\\' =>
54
  array (
55
+ 0 => __DIR__ . '/../..' . '/modules/ppcp-webhooks/src',
56
  ),
57
+ 'WooCommerce\\PayPalCommerce\\WcGateway\\' =>
58
  array (
59
+ 0 => __DIR__ . '/../..' . '/modules/ppcp-wc-gateway/src',
60
  ),
61
+ 'WooCommerce\\PayPalCommerce\\Vaulting\\' =>
62
  array (
63
+ 0 => __DIR__ . '/../..' . '/modules/ppcp-vaulting/src',
64
  ),
65
+ 'WooCommerce\\PayPalCommerce\\Subscription\\' =>
66
  array (
67
+ 0 => __DIR__ . '/../..' . '/modules/ppcp-subscription/src',
68
  ),
69
+ 'WooCommerce\\PayPalCommerce\\StatusReport\\' =>
70
  array (
71
+ 0 => __DIR__ . '/../..' . '/modules/ppcp-status-report/src',
72
+ ),
73
+ 'WooCommerce\\PayPalCommerce\\Session\\' =>
74
+ array (
75
+ 0 => __DIR__ . '/../..' . '/modules/ppcp-session/src',
76
+ ),
77
+ 'WooCommerce\\PayPalCommerce\\Onboarding\\' =>
78
+ array (
79
+ 0 => __DIR__ . '/../..' . '/modules/ppcp-onboarding/src',
80
+ ),
81
+ 'WooCommerce\\PayPalCommerce\\Compat\\' =>
82
+ array (
83
+ 0 => __DIR__ . '/../..' . '/modules/ppcp-compat/src',
84
+ ),
85
+ 'WooCommerce\\PayPalCommerce\\Button\\' =>
86
+ array (
87
+ 0 => __DIR__ . '/../..' . '/modules/ppcp-button/src',
88
+ ),
89
+ 'WooCommerce\\PayPalCommerce\\ApiClient\\' =>
90
+ array (
91
+ 0 => __DIR__ . '/../..' . '/modules/ppcp-api-client/src',
92
+ ),
93
+ 'WooCommerce\\PayPalCommerce\\AdminNotices\\' =>
94
+ array (
95
+ 0 => __DIR__ . '/../..' . '/modules/ppcp-admin-notices/src',
96
+ ),
97
+ 'WooCommerce\\PayPalCommerce\\' =>
98
+ array (
99
+ 0 => __DIR__ . '/../..' . '/src',
100
  ),
101
+ 'Wikimedia\\Composer\\' =>
102
  array (
103
+ 0 => __DIR__ . '/..' . '/wikimedia/composer-merge-plugin/src',
104
  ),
105
+ 'Psr\\Log\\' =>
106
  array (
107
+ 0 => __DIR__ . '/..' . '/psr/log/Psr/Log',
108
  ),
109
+ 'Psr\\Container\\' =>
110
  array (
111
+ 0 => __DIR__ . '/..' . '/psr/container/src',
112
+ ),
113
+ 'Interop\\Container\\' =>
114
+ array (
115
+ 0 => __DIR__ . '/..' . '/container-interop/service-provider/src',
116
+ ),
117
+ 'Dhii\\Modular\\Module\\' =>
118
+ array (
119
+ 0 => __DIR__ . '/..' . '/dhii/module-interface/src',
120
  ),
121
  'Dhii\\Container\\' =>
122
  array (
128
  ),
129
  );
130
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
131
  public static function getInitializer(ClassLoader $loader)
132
  {
133
  return \Closure::bind(function () use ($loader) {
134
+ $loader->prefixLengthsPsr4 = ComposerStaticInit3acb3642cf46c3f8b0d913579e285e9c::$prefixLengthsPsr4;
135
+ $loader->prefixDirsPsr4 = ComposerStaticInit3acb3642cf46c3f8b0d913579e285e9c::$prefixDirsPsr4;
 
136
 
137
  }, null, ClassLoader::class);
138
  }
vendor/composer/installed.json CHANGED
@@ -1,661 +1,408 @@
1
- {
2
- "packages": [
3
- {
4
- "name": "container-interop/service-provider",
5
- "version": "v0.4.0",
6
- "version_normalized": "0.4.0.0",
7
- "source": {
8
- "type": "git",
9
- "url": "https://github.com/container-interop/service-provider.git",
10
- "reference": "4969b9e49460690b7430b3f1a87cab07be61418a"
11
- },
12
- "dist": {
13
- "type": "zip",
14
- "url": "https://api.github.com/repos/container-interop/service-provider/zipball/4969b9e49460690b7430b3f1a87cab07be61418a",
15
- "reference": "4969b9e49460690b7430b3f1a87cab07be61418a",
16
- "shasum": ""
17
- },
18
- "require": {
19
- "psr/container": "^1.0"
20
- },
21
- "time": "2017-09-20T14:13:36+00:00",
22
- "type": "library",
23
- "installation-source": "dist",
24
- "autoload": {
25
- "psr-4": {
26
- "Interop\\Container\\": "src/"
27
- }
28
- },
29
- "notification-url": "https://packagist.org/downloads/",
30
- "license": [
31
- "MIT"
32
- ],
33
- "description": "Promoting container interoperability through standard service providers",
34
- "homepage": "https://github.com/container-interop/service-provider",
35
- "support": {
36
- "issues": "https://github.com/container-interop/service-provider/issues",
37
- "source": "https://github.com/container-interop/service-provider/tree/master"
38
- },
39
- "install-path": "../container-interop/service-provider"
40
- },
41
- {
42
- "name": "dhii/collections-interface",
43
- "version": "v0.3.0-alpha4",
44
- "version_normalized": "0.3.0.0-alpha4",
45
- "source": {
46
- "type": "git",
47
- "url": "https://github.com/Dhii/collections-interface.git",
48
- "reference": "da334f75f6477ef7eecaf28df1d5253fe05684ee"
49
- },
50
- "dist": {
51
- "type": "zip",
52
- "url": "https://api.github.com/repos/Dhii/collections-interface/zipball/da334f75f6477ef7eecaf28df1d5253fe05684ee",
53
- "reference": "da334f75f6477ef7eecaf28df1d5253fe05684ee",
54
- "shasum": ""
55
- },
56
- "require": {
57
- "php": "^7.1 | ^8.0",
58
- "psr/container": "^1.0"
59
- },
60
- "require-dev": {
61
- "phpunit/phpunit": "^7.0 | ^8.0 | ^9.0",
62
- "slevomat/coding-standard": "^6.0",
63
- "vimeo/psalm": "^3.11.7 | ^4.0"
64
- },
65
- "time": "2021-03-09T17:36:34+00:00",
66
- "type": "library",
67
- "extra": {
68
- "branch-alias": {
69
- "dev-develop": "0.3.x-dev"
70
- }
71
- },
72
- "installation-source": "dist",
73
- "autoload": {
74
- "psr-4": {
75
- "Dhii\\Collection\\": "src"
76
- }
77
- },
78
- "notification-url": "https://packagist.org/downloads/",
79
- "license": [
80
- "MIT"
81
- ],
82
- "authors": [
83
- {
84
- "name": "Dhii Team",
85
- "email": "development@dhii.co"
86
- },
87
- {
88
- "name": "Anton Ukhanev",
89
- "email": "xedin.unknown@gmail.com"
90
- }
91
- ],
92
- "description": "A highly ISP-compliant collection of interfaces that represent maps and lists.",
93
- "support": {
94
- "issues": "https://github.com/Dhii/collections-interface/issues",
95
- "source": "https://github.com/Dhii/collections-interface/tree/v0.3.0-alpha4"
96
- },
97
- "install-path": "../dhii/collections-interface"
98
- },
99
- {
100
- "name": "dhii/containers",
101
- "version": "v0.1.0-alpha1",
102
- "version_normalized": "0.1.0.0-alpha1",
103
- "source": {
104
- "type": "git",
105
- "url": "https://github.com/Dhii/containers.git",
106
- "reference": "73eed5422e106006c81ca1fa8b7213c6be33efbc"
107
- },
108
- "dist": {
109
- "type": "zip",
110
- "url": "https://api.github.com/repos/Dhii/containers/zipball/73eed5422e106006c81ca1fa8b7213c6be33efbc",
111
- "reference": "73eed5422e106006c81ca1fa8b7213c6be33efbc",
112
- "shasum": ""
113
- },
114
- "require": {
115
- "container-interop/service-provider": "^0.4",
116
- "dhii/collections-interface": "^0.3.0-alpha1",
117
- "php": "^7.1 | ^8.0"
118
- },
119
- "require-dev": {
120
- "gmazzap/andrew": "^1.1",
121
- "phpunit/phpunit": "^7.0",
122
- "psr/container": "^1.0",
123
- "slevomat/coding-standard": "~4.0"
124
- },
125
- "time": "2020-09-14T18:27:47+00:00",
126
- "type": "library",
127
- "extra": {
128
- "branch-alias": {
129
- "dev-develop": "0.1.x-dev"
130
- }
131
- },
132
- "installation-source": "dist",
133
- "autoload": {
134
- "psr-4": {
135
- "Dhii\\Container\\": "src/"
136
- }
137
- },
138
- "notification-url": "https://packagist.org/downloads/",
139
- "license": [
140
- "MIT"
141
- ],
142
- "authors": [
143
- {
144
- "name": "Dhii Team",
145
- "email": "development@dhii.co"
146
- }
147
- ],
148
- "description": "A selection of PSR-11 containers for utility, simplicity, and ease.",
149
- "keywords": [
150
- "PSR-11",
151
- "container"
152
- ],
153
- "support": {
154
- "issues": "https://github.com/Dhii/containers/issues",
155
- "source": "https://github.com/Dhii/containers/tree/v0.1.0-alpha1"
156
- },
157
- "install-path": "../dhii/containers"
158
- },
159
- {
160
- "name": "dhii/data-container-interface",
161
- "version": "v0.2.1-alpha1",
162
- "version_normalized": "0.2.1.0-alpha1",
163
- "source": {
164
- "type": "git",
165
- "url": "https://github.com/Dhii/data-container-interface.git",
166
- "reference": "6be46e427184b95785d9dd563d6acf2e0700cc31"
167
- },
168
- "dist": {
169
- "type": "zip",
170
- "url": "https://api.github.com/repos/Dhii/data-container-interface/zipball/6be46e427184b95785d9dd563d6acf2e0700cc31",
171
- "reference": "6be46e427184b95785d9dd563d6acf2e0700cc31",
172
- "shasum": ""
173
- },
174
- "require": {
175
- "dhii/exception-interface": "^0.1 | ^0.2",
176
- "dhii/factory-interface": "^0.1-alpha1",
177
- "php": "^5.3 | ^7.0",
178
- "psr/container": "^1.0"
179
- },
180
- "require-dev": {
181
- "codeclimate/php-test-reporter": "<=0.3.2",
182
- "dhii/php-cs-fixer-config": "dev-php-5.3",
183
- "dhii/stringable-interface": "^0.1",
184
- "phpunit/phpunit": "^4.8",
185
- "ptrofimov/xpmock": "^1.1"
186
- },
187
- "suggest": {
188
- "dhii/stringable-interface": "To be able to pass Stringables as keys"
189
- },
190
- "time": "2019-05-10T14:17:29+00:00",
191
- "type": "library",
192
- "extra": {
193
- "branch-alias": {
194
- "dev-develop": "0.2.x-dev"
195
- }
196
- },
197
- "installation-source": "dist",
198
- "autoload": {
199
- "psr-4": {
200
- "Dhii\\Data\\Container\\": "src"
201
- }
202
- },
203
- "notification-url": "https://packagist.org/downloads/",
204
- "license": [
205
- "MIT"
206
- ],
207
- "authors": [
208
- {
209
- "name": "Dhii Team",
210
- "email": "development@dhii.co"
211
- }
212
- ],
213
- "description": "Interfaces for working with data containers",
214
- "support": {
215
- "issues": "https://github.com/Dhii/data-container-interface/issues",
216
- "source": "https://github.com/Dhii/data-container-interface/tree/v0.2.1-alpha1"
217
- },
218
- "abandoned": "dhii/collections-interface",
219
- "install-path": "../dhii/data-container-interface"
220
- },
221
- {
222
- "name": "dhii/exception-interface",
223
- "version": "v0.2",
224
- "version_normalized": "0.2.0.0",
225
- "source": {
226
- "type": "git",
227
- "url": "https://github.com/Dhii/exception-interface.git",
228
- "reference": "b69feebf7cb2879cd43977a03342e2393b73f7fb"
229
- },
230
- "dist": {
231
- "type": "zip",
232
- "url": "https://api.github.com/repos/Dhii/exception-interface/zipball/b69feebf7cb2879cd43977a03342e2393b73f7fb",
233
- "reference": "b69feebf7cb2879cd43977a03342e2393b73f7fb",
234
- "shasum": ""
235
- },
236
- "require": {
237
- "dhii/stringable-interface": "^0.1",
238
- "php": "^5.3 | ^7.0"
239
- },
240
- "require-dev": {
241
- "codeclimate/php-test-reporter": "<=0.3.2",
242
- "dhii/php-cs-fixer-config": "dev-php-5.3",
243
- "phpunit/phpunit": "^4.8",
244
- "ptrofimov/xpmock": "^1.1"
245
- },
246
- "time": "2018-08-29T10:42:04+00:00",
247
- "type": "library",
248
- "extra": {
249
- "branch-alias": {
250
- "dev-develop": "0.2.x-dev"
251
- }
252
- },
253
- "installation-source": "dist",
254
- "autoload": {
255
- "psr-4": {
256
- "Dhii\\Exception\\": "src"
257
- }
258
- },
259
- "notification-url": "https://packagist.org/downloads/",
260
- "license": [
261
- "MIT"
262
- ],
263
- "authors": [
264
- {
265
- "name": "Dhii Team",
266
- "email": "development@dhii.co"
267
- }
268
- ],
269
- "description": "Interfaces for most common exceptions",
270
- "support": {
271
- "issues": "https://github.com/Dhii/exception-interface/issues",
272
- "source": "https://github.com/Dhii/exception-interface/tree/develop"
273
- },
274
- "install-path": "../dhii/exception-interface"
275
- },
276
- {
277
- "name": "dhii/factory-interface",
278
- "version": "v0.1",
279
- "version_normalized": "0.1.0.0",
280
- "source": {
281
- "type": "git",
282
- "url": "https://github.com/Dhii/factory-interface.git",
283
- "reference": "b8d217aec8838e64ccaa770cb03dc164bf6f0515"
284
- },
285
- "dist": {
286
- "type": "zip",
287
- "url": "https://api.github.com/repos/Dhii/factory-interface/zipball/b8d217aec8838e64ccaa770cb03dc164bf6f0515",
288
- "reference": "b8d217aec8838e64ccaa770cb03dc164bf6f0515",
289
- "shasum": ""
290
- },
291
- "require": {
292
- "dhii/exception-interface": "^0.1|^0.2",
293
- "php": "^5.3 | ^7.0"
294
- },
295
- "require-dev": {
296
- "codeclimate/php-test-reporter": "<=0.3.2",
297
- "dhii/php-cs-fixer-config": "dev-php-5.3",
298
- "dhii/stringable-interface": "^0.1",
299
- "phpunit/phpunit": "^4.8",
300
- "psr/container": "^1.0",
301
- "ptrofimov/xpmock": "^1.1"
302
- },
303
- "time": "2018-08-29T11:15:09+00:00",
304
- "type": "library",
305
- "extra": {
306
- "branch-alias": {
307
- "dev-develop": "0.1.x-dev"
308
- }
309
- },
310
- "installation-source": "dist",
311
- "autoload": {
312
- "psr-4": {
313
- "Dhii\\Factory\\": "src"
314
- }
315
- },
316
- "notification-url": "https://packagist.org/downloads/",
317
- "license": [
318
- "MIT"
319
- ],
320
- "authors": [
321
- {
322
- "name": "Dhii Team",
323
- "email": "development@dhii.co"
324
- }
325
- ],
326
- "description": "Interfaces for working with factories.",
327
- "support": {
328
- "issues": "https://github.com/Dhii/factory-interface/issues",
329
- "source": "https://github.com/Dhii/factory-interface/tree/master"
330
- },
331
- "abandoned": true,
332
- "install-path": "../dhii/factory-interface"
333
- },
334
- {
335
- "name": "dhii/module-interface",
336
- "version": "v0.3.0-alpha2",
337
- "version_normalized": "0.3.0.0-alpha2",
338
- "source": {
339
- "type": "git",
340
- "url": "https://github.com/Dhii/module-interface.git",
341
- "reference": "0e39f167d7ed8990c82f5d2e6084159d1a502a5b"
342
- },
343
- "dist": {
344
- "type": "zip",
345
- "url": "https://api.github.com/repos/Dhii/module-interface/zipball/0e39f167d7ed8990c82f5d2e6084159d1a502a5b",
346
- "reference": "0e39f167d7ed8990c82f5d2e6084159d1a502a5b",
347
- "shasum": ""
348
- },
349
- "require": {
350
- "container-interop/service-provider": "^0.4",
351
- "php": "^7.1 | ^8.0",
352
- "psr/container": "^1.0"
353
- },
354
- "require-dev": {
355
- "phpunit/phpunit": "^7.0 | ^8.0 | ^9.0",
356
- "slevomat/coding-standard": "^6.0",
357
- "vimeo/psalm": "^3.11.7 | ^4.0"
358
- },
359
- "time": "2021-08-23T08:23:01+00:00",
360
- "type": "library",
361
- "extra": {
362
- "branch-alias": {
363
- "dev-develop": "0.3.x-dev"
364
- }
365
- },
366
- "installation-source": "dist",
367
- "autoload": {
368
- "psr-4": {
369
- "Dhii\\Modular\\Module\\": "src"
370
- }
371
- },
372
- "notification-url": "https://packagist.org/downloads/",
373
- "license": [
374
- "MIT"
375
- ],
376
- "authors": [
377
- {
378
- "name": "Dhii Team",
379
- "email": "development@dhii.co"
380
- }
381
- ],
382
- "description": "Interfaces for modules",
383
- "support": {
384
- "issues": "https://github.com/Dhii/module-interface/issues",
385
- "source": "https://github.com/Dhii/module-interface/tree/v0.3.0-alpha2"
386
- },
387
- "install-path": "../dhii/module-interface"
388
- },
389
- {
390
- "name": "dhii/stringable-interface",
391
- "version": "v0.1",
392
- "version_normalized": "0.1.0.0",
393
- "source": {
394
- "type": "git",
395
- "url": "https://github.com/Dhii/stringable-interface.git",
396
- "reference": "b6653905eef2ebf377749feb80a6d18abbe913ef"
397
- },
398
- "dist": {
399
- "type": "zip",
400
- "url": "https://api.github.com/repos/Dhii/stringable-interface/zipball/b6653905eef2ebf377749feb80a6d18abbe913ef",
401
- "reference": "b6653905eef2ebf377749feb80a6d18abbe913ef",
402
- "shasum": ""
403
- },
404
- "require": {
405
- "php": "^5.3 | ^7.0"
406
- },
407
- "require-dev": {
408
- "codeclimate/php-test-reporter": "<=0.3.2",
409
- "dhii/php-cs-fixer-config": "dev-php-5.3",
410
- "phpunit/phpunit": "^4.8",
411
- "ptrofimov/xpmock": "^1.1"
412
- },
413
- "time": "2017-01-23T15:08:20+00:00",
414
- "type": "library",
415
- "installation-source": "dist",
416
- "autoload": {
417
- "psr-4": {
418
- "Dhii\\Util\\String\\": "src/"
419
- }
420
- },
421
- "notification-url": "https://packagist.org/downloads/",
422
- "license": [
423
- "MIT"
424
- ],
425
- "authors": [
426
- {
427
- "name": "Dhii Team",
428
- "email": "development@dhii.co"
429
- }
430
- ],
431
- "description": "Interoperability interface for objects that can be cast to string",
432
- "support": {
433
- "issues": "https://github.com/Dhii/stringable-interface/issues",
434
- "source": "https://github.com/Dhii/stringable-interface/tree/master"
435
- },
436
- "abandoned": "symfony/polyfill-php80",
437
- "install-path": "../dhii/stringable-interface"
438
- },
439
- {
440
- "name": "dhii/wp-containers",
441
- "version": "v0.1.0-alpha1",
442
- "version_normalized": "0.1.0.0-alpha1",
443
- "source": {
444
- "type": "git",
445
- "url": "https://github.com/Dhii/wp-containers.git",
446
- "reference": "e91a6f741622770ed724a2b594145fa917811f0c"
447
- },
448
- "dist": {
449
- "type": "zip",
450
- "url": "https://api.github.com/repos/Dhii/wp-containers/zipball/e91a6f741622770ed724a2b594145fa917811f0c",
451
- "reference": "e91a6f741622770ed724a2b594145fa917811f0c",
452
- "shasum": ""
453
- },
454
- "require": {
455
- "dhii/data-container-interface": "^0.2.1-alpha1",
456
- "php": "^7.0 | ^8.0",
457
- "psr/container": "^1.0"
458
- },
459
- "require-dev": {
460
- "brain/monkey": "^2",
461
- "gmazzap/andrew": "^1.1",
462
- "phpunit/phpunit": "^6",
463
- "slevomat/coding-standard": "~4.0"
464
- },
465
- "time": "2019-05-10T15:04:22+00:00",
466
- "type": "library",
467
- "extra": {
468
- "branch-alias": {
469
- "dev-develop": "0.1.x-dev"
470
- }
471
- },
472
- "installation-source": "dist",
473
- "autoload": {
474
- "psr-4": {
475
- "Dhii\\Wp\\Containers\\": "src/"
476
- }
477
- },
478
- "notification-url": "https://packagist.org/downloads/",
479
- "license": [
480
- "MIT"
481
- ],
482
- "authors": [
483
- {
484
- "name": "Dhii Team",
485
- "email": "development@dhii.co"
486
- }
487
- ],
488
- "description": "PSR-11 container implementations that wrap some WP features, for convenience and interoperability.",
489
- "keywords": [
490
- "container",
491
- "dependency injection",
492
- "di",
493
- "wordpress"
494
- ],
495
- "support": {
496
- "issues": "https://github.com/Dhii/wp-containers/issues",
497
- "source": "https://github.com/Dhii/wp-containers/tree/v0.1.0-alpha1"
498
- },
499
- "abandoned": "wp-oop/containers",
500
- "install-path": "../dhii/wp-containers"
501
- },
502
- {
503
- "name": "psr/container",
504
- "version": "1.0.0",
505
- "version_normalized": "1.0.0.0",
506
- "source": {
507
- "type": "git",
508
- "url": "https://github.com/php-fig/container.git",
509
- "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f"
510
- },
511
- "dist": {
512
- "type": "zip",
513
- "url": "https://api.github.com/repos/php-fig/container/zipball/b7ce3b176482dbbc1245ebf52b181af44c2cf55f",
514
- "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f",
515
- "shasum": ""
516
- },
517
- "require": {
518
- "php": ">=5.3.0"
519
- },
520
- "time": "2017-02-14T16:28:37+00:00",
521
- "type": "library",
522
- "extra": {
523
- "branch-alias": {
524
- "dev-master": "1.0.x-dev"
525
- }
526
- },
527
- "installation-source": "dist",
528
- "autoload": {
529
- "psr-4": {
530
- "Psr\\Container\\": "src/"
531
- }
532
- },
533
- "notification-url": "https://packagist.org/downloads/",
534
- "license": [
535
- "MIT"
536
- ],
537
- "authors": [
538
- {
539
- "name": "PHP-FIG",
540
- "homepage": "http://www.php-fig.org/"
541
- }
542
- ],
543
- "description": "Common Container Interface (PHP FIG PSR-11)",
544
- "homepage": "https://github.com/php-fig/container",
545
- "keywords": [
546
- "PSR-11",
547
- "container",
548
- "container-interface",
549
- "container-interop",
550
- "psr"
551
- ],
552
- "support": {
553
- "issues": "https://github.com/php-fig/container/issues",
554
- "source": "https://github.com/php-fig/container/tree/master"
555
- },
556
- "install-path": "../psr/container"
557
- },
558
- {
559
- "name": "psr/log",
560
- "version": "1.1.4",
561
- "version_normalized": "1.1.4.0",
562
- "source": {
563
- "type": "git",
564
- "url": "https://github.com/php-fig/log.git",
565
- "reference": "d49695b909c3b7628b6289db5479a1c204601f11"
566
- },
567
- "dist": {
568
- "type": "zip",
569
- "url": "https://api.github.com/repos/php-fig/log/zipball/d49695b909c3b7628b6289db5479a1c204601f11",
570
- "reference": "d49695b909c3b7628b6289db5479a1c204601f11",
571
- "shasum": ""
572
- },
573
- "require": {
574
- "php": ">=5.3.0"
575
- },
576
- "time": "2021-05-03T11:20:27+00:00",
577
- "type": "library",
578
- "extra": {
579
- "branch-alias": {
580
- "dev-master": "1.1.x-dev"
581
- }
582
- },
583
- "installation-source": "dist",
584
- "autoload": {
585
- "psr-4": {
586
- "Psr\\Log\\": "Psr/Log/"
587
- }
588
- },
589
- "notification-url": "https://packagist.org/downloads/",
590
- "license": [
591
- "MIT"
592
- ],
593
- "authors": [
594
- {
595
- "name": "PHP-FIG",
596
- "homepage": "https://www.php-fig.org/"
597
- }
598
- ],
599
- "description": "Common interface for logging libraries",
600
- "homepage": "https://github.com/php-fig/log",
601
- "keywords": [
602
- "log",
603
- "psr",
604
- "psr-3"
605
- ],
606
- "support": {
607
- "source": "https://github.com/php-fig/log/tree/1.1.4"
608
- },
609
- "install-path": "../psr/log"
610
- },
611
- {
612
- "name": "ralouphie/getallheaders",
613
- "version": "3.0.3",
614
- "version_normalized": "3.0.3.0",
615
- "source": {
616
- "type": "git",
617
- "url": "https://github.com/ralouphie/getallheaders.git",
618
- "reference": "120b605dfeb996808c31b6477290a714d356e822"
619
- },
620
- "dist": {
621
- "type": "zip",
622
- "url": "https://api.github.com/repos/ralouphie/getallheaders/zipball/120b605dfeb996808c31b6477290a714d356e822",
623
- "reference": "120b605dfeb996808c31b6477290a714d356e822",
624
- "shasum": ""
625
- },
626
- "require": {
627
- "php": ">=5.6"
628
- },
629
- "require-dev": {
630
- "php-coveralls/php-coveralls": "^2.1",
631
- "phpunit/phpunit": "^5 || ^6.5"
632
- },
633
- "time": "2019-03-08T08:55:37+00:00",
634
- "type": "library",
635
- "installation-source": "dist",
636
- "autoload": {
637
- "files": [
638
- "src/getallheaders.php"
639
- ]
640
- },
641
- "notification-url": "https://packagist.org/downloads/",
642
- "license": [
643
- "MIT"
644
- ],
645
- "authors": [
646
- {
647
- "name": "Ralph Khattar",
648
- "email": "ralph.khattar@gmail.com"
649
- }
650
- ],
651
- "description": "A polyfill for getallheaders.",
652
- "support": {
653
- "issues": "https://github.com/ralouphie/getallheaders/issues",
654
- "source": "https://github.com/ralouphie/getallheaders/tree/develop"
655
- },
656
- "install-path": "../ralouphie/getallheaders"
657
  }
658
- ],
659
- "dev": false,
660
- "dev-package-names": []
661
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ [
2
+ {
3
+ "name": "container-interop/service-provider",
4
+ "version": "v0.4.0",
5
+ "version_normalized": "0.4.0.0",
6
+ "source": {
7
+ "type": "git",
8
+ "url": "https://github.com/container-interop/service-provider.git",
9
+ "reference": "4969b9e49460690b7430b3f1a87cab07be61418a"
10
+ },
11
+ "dist": {
12
+ "type": "zip",
13
+ "url": "https://api.github.com/repos/container-interop/service-provider/zipball/4969b9e49460690b7430b3f1a87cab07be61418a",
14
+ "reference": "4969b9e49460690b7430b3f1a87cab07be61418a",
15
+ "shasum": ""
16
+ },
17
+ "require": {
18
+ "psr/container": "^1.0"
19
+ },
20
+ "time": "2017-09-20T14:13:36+00:00",
21
+ "type": "library",
22
+ "installation-source": "dist",
23
+ "autoload": {
24
+ "psr-4": {
25
+ "Interop\\Container\\": "src/"
26
+ }
27
+ },
28
+ "notification-url": "https://packagist.org/downloads/",
29
+ "license": [
30
+ "MIT"
31
+ ],
32
+ "description": "Promoting container interoperability through standard service providers",
33
+ "homepage": "https://github.com/container-interop/service-provider",
34
+ "support": {
35
+ "issues": "https://github.com/container-interop/service-provider/issues",
36
+ "source": "https://github.com/container-interop/service-provider/tree/master"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
37
  }
38
+ },
39
+ {
40
+ "name": "dhii/collections-interface",
41
+ "version": "v0.3.0",
42
+ "version_normalized": "0.3.0.0",
43
+ "source": {
44
+ "type": "git",
45
+ "url": "https://github.com/Dhii/collections-interface.git",
46
+ "reference": "74464a969b340d16889eacd9eadc9817f7e7f47a"
47
+ },
48
+ "dist": {
49
+ "type": "zip",
50
+ "url": "https://api.github.com/repos/Dhii/collections-interface/zipball/74464a969b340d16889eacd9eadc9817f7e7f47a",
51
+ "reference": "74464a969b340d16889eacd9eadc9817f7e7f47a",
52
+ "shasum": ""
53
+ },
54
+ "require": {
55
+ "php": "^7.1 | ^8.0",
56
+ "psr/container": "^1.0"
57
+ },
58
+ "require-dev": {
59
+ "phpunit/phpunit": "^7.0 | ^8.0 | ^9.0",
60
+ "slevomat/coding-standard": "^6.0",
61
+ "vimeo/psalm": "^4.0"
62
+ },
63
+ "time": "2021-10-06T10:56:09+00:00",
64
+ "type": "library",
65
+ "extra": {
66
+ "branch-alias": {
67
+ "dev-develop": "0.3.x-dev"
68
+ }
69
+ },
70
+ "installation-source": "dist",
71
+ "autoload": {
72
+ "psr-4": {
73
+ "Dhii\\Collection\\": "src"
74
+ }
75
+ },
76
+ "notification-url": "https://packagist.org/downloads/",
77
+ "license": [
78
+ "MIT"
79
+ ],
80
+ "authors": [
81
+ {
82
+ "name": "Dhii Team",
83
+ "email": "development@dhii.co"
84
+ },
85
+ {
86
+ "name": "Anton Ukhanev",
87
+ "email": "xedin.unknown@gmail.com"
88
+ }
89
+ ],
90
+ "description": "A highly ISP-compliant collection of interfaces that represent maps and lists."
91
+ },
92
+ {
93
+ "name": "dhii/containers",
94
+ "version": "v0.1.4",
95
+ "version_normalized": "0.1.4.0",
96
+ "source": {
97
+ "type": "git",
98
+ "url": "https://github.com/Dhii/containers.git",
99
+ "reference": "42ab24683183fa0dc155f26c6a470ef697bbdc9a"
100
+ },
101
+ "dist": {
102
+ "type": "zip",
103
+ "url": "https://api.github.com/repos/Dhii/containers/zipball/42ab24683183fa0dc155f26c6a470ef697bbdc9a",
104
+ "reference": "42ab24683183fa0dc155f26c6a470ef697bbdc9a",
105
+ "shasum": ""
106
+ },
107
+ "require": {
108
+ "container-interop/service-provider": "^0.4",
109
+ "dhii/collections-interface": "^0.3.0-alpha4",
110
+ "php": "^7.1 | ^8.0"
111
+ },
112
+ "require-dev": {
113
+ "gmazzap/andrew": "^1.1",
114
+ "phpunit/phpunit": "^7.0 | ^8.0 | ^9.0",
115
+ "psr/container": "^1.0",
116
+ "psr/simple-cache": "^1.0",
117
+ "slevomat/coding-standard": "^6.0",
118
+ "vimeo/psalm": "^4.0",
119
+ "wildwolf/psr-memory-cache": "^1.0"
120
+ },
121
+ "time": "2021-10-06T11:13:51+00:00",
122
+ "type": "library",
123
+ "extra": {
124
+ "branch-alias": {
125
+ "dev-develop": "0.1.x-dev"
126
+ }
127
+ },
128
+ "installation-source": "dist",
129
+ "autoload": {
130
+ "psr-4": {
131
+ "Dhii\\Container\\": "src/"
132
+ }
133
+ },
134
+ "notification-url": "https://packagist.org/downloads/",
135
+ "license": [
136
+ "MIT"
137
+ ],
138
+ "authors": [
139
+ {
140
+ "name": "Dhii Team",
141
+ "email": "development@dhii.co"
142
+ }
143
+ ],
144
+ "description": "A selection of PSR-11 containers for utility, simplicity, and ease.",
145
+ "keywords": [
146
+ "PSR-11",
147
+ "container"
148
+ ]
149
+ },
150
+ {
151
+ "name": "dhii/module-interface",
152
+ "version": "v0.3.0-alpha2",
153
+ "version_normalized": "0.3.0.0-alpha2",
154
+ "source": {
155
+ "type": "git",
156
+ "url": "https://github.com/Dhii/module-interface.git",
157
+ "reference": "0e39f167d7ed8990c82f5d2e6084159d1a502a5b"
158
+ },
159
+ "dist": {
160
+ "type": "zip",
161
+ "url": "https://api.github.com/repos/Dhii/module-interface/zipball/0e39f167d7ed8990c82f5d2e6084159d1a502a5b",
162
+ "reference": "0e39f167d7ed8990c82f5d2e6084159d1a502a5b",
163
+ "shasum": ""
164
+ },
165
+ "require": {
166
+ "container-interop/service-provider": "^0.4",
167
+ "php": "^7.1 | ^8.0",
168
+ "psr/container": "^1.0"
169
+ },
170
+ "require-dev": {
171
+ "phpunit/phpunit": "^7.0 | ^8.0 | ^9.0",
172
+ "slevomat/coding-standard": "^6.0",
173
+ "vimeo/psalm": "^3.11.7 | ^4.0"
174
+ },
175
+ "time": "2021-08-23T08:23:01+00:00",
176
+ "type": "library",
177
+ "extra": {
178
+ "branch-alias": {
179
+ "dev-develop": "0.3.x-dev"
180
+ }
181
+ },
182
+ "installation-source": "dist",
183
+ "autoload": {
184
+ "psr-4": {
185
+ "Dhii\\Modular\\Module\\": "src"
186
+ }
187
+ },
188
+ "notification-url": "https://packagist.org/downloads/",
189
+ "license": [
190
+ "MIT"
191
+ ],
192
+ "authors": [
193
+ {
194
+ "name": "Dhii Team",
195
+ "email": "development@dhii.co"
196
+ }
197
+ ],
198
+ "description": "Interfaces for modules",
199
+ "support": {
200
+ "issues": "https://github.com/Dhii/module-interface/issues",
201
+ "source": "https://github.com/Dhii/module-interface/tree/v0.3.0-alpha2"
202
+ }
203
+ },
204
+ {
205
+ "name": "psr/container",
206
+ "version": "1.0.0",
207
+ "version_normalized": "1.0.0.0",
208
+ "source": {
209
+ "type": "git",
210
+ "url": "https://github.com/php-fig/container.git",
211
+ "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f"
212
+ },
213
+ "dist": {
214
+ "type": "zip",
215
+ "url": "https://api.github.com/repos/php-fig/container/zipball/b7ce3b176482dbbc1245ebf52b181af44c2cf55f",
216
+ "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f",
217
+ "shasum": ""
218
+ },
219
+ "require": {
220
+ "php": ">=5.3.0"
221
+ },
222
+ "time": "2017-02-14T16:28:37+00:00",
223
+ "type": "library",
224
+ "extra": {
225
+ "branch-alias": {
226
+ "dev-master": "1.0.x-dev"
227
+ }
228
+ },
229
+ "installation-source": "dist",
230
+ "autoload": {
231
+ "psr-4": {
232
+ "Psr\\Container\\": "src/"
233
+ }
234
+ },
235
+ "notification-url": "https://packagist.org/downloads/",
236
+ "license": [
237
+ "MIT"
238
+ ],
239
+ "authors": [
240
+ {
241
+ "name": "PHP-FIG",
242
+ "homepage": "http://www.php-fig.org/"
243
+ }
244
+ ],
245
+ "description": "Common Container Interface (PHP FIG PSR-11)",
246
+ "homepage": "https://github.com/php-fig/container",
247
+ "keywords": [
248
+ "PSR-11",
249
+ "container",
250
+ "container-interface",
251
+ "container-interop",
252
+ "psr"
253
+ ],
254
+ "support": {
255
+ "issues": "https://github.com/php-fig/container/issues",
256
+ "source": "https://github.com/php-fig/container/tree/master"
257
+ }
258
+ },
259
+ {
260
+ "name": "psr/log",
261
+ "version": "1.1.4",
262
+ "version_normalized": "1.1.4.0",
263
+ "source": {
264
+ "type": "git",
265
+ "url": "https://github.com/php-fig/log.git",
266
+ "reference": "d49695b909c3b7628b6289db5479a1c204601f11"
267
+ },
268
+ "dist": {
269
+ "type": "zip",
270
+ "url": "https://api.github.com/repos/php-fig/log/zipball/d49695b909c3b7628b6289db5479a1c204601f11",
271
+ "reference": "d49695b909c3b7628b6289db5479a1c204601f11",
272
+ "shasum": ""
273
+ },
274
+ "require": {
275
+ "php": ">=5.3.0"
276
+ },
277
+ "time": "2021-05-03T11:20:27+00:00",
278
+ "type": "library",
279
+ "extra": {
280
+ "branch-alias": {
281
+ "dev-master": "1.1.x-dev"
282
+ }
283
+ },
284
+ "installation-source": "dist",
285
+ "autoload": {
286
+ "psr-4": {
287
+ "Psr\\Log\\": "Psr/Log/"
288
+ }
289
+ },
290
+ "notification-url": "https://packagist.org/downloads/",
291
+ "license": [
292
+ "MIT"
293
+ ],
294
+ "authors": [
295
+ {
296
+ "name": "PHP-FIG",
297
+ "homepage": "https://www.php-fig.org/"
298
+ }
299
+ ],
300
+ "description": "Common interface for logging libraries",
301
+ "homepage": "https://github.com/php-fig/log",
302
+ "keywords": [
303
+ "log",
304
+ "psr",
305
+ "psr-3"
306
+ ],
307
+ "support": {
308
+ "source": "https://github.com/php-fig/log/tree/1.1.4"
309
+ }
310
+ },
311
+ {
312
+ "name": "ralouphie/getallheaders",
313
+ "version": "3.0.3",
314
+ "version_normalized": "3.0.3.0",
315
+ "source": {
316
+ "type": "git",
317
+ "url": "https://github.com/ralouphie/getallheaders.git",
318
+ "reference": "120b605dfeb996808c31b6477290a714d356e822"
319
+ },
320
+ "dist": {
321
+ "type": "zip",
322
+ "url": "https://api.github.com/repos/ralouphie/getallheaders/zipball/120b605dfeb996808c31b6477290a714d356e822",
323
+ "reference": "120b605dfeb996808c31b6477290a714d356e822",
324
+ "shasum": ""
325
+ },
326
+ "require": {
327
+ "php": ">=5.6"
328
+ },
329
+ "require-dev": {
330
+ "php-coveralls/php-coveralls": "^2.1",
331
+ "phpunit/phpunit": "^5 || ^6.5"
332
+ },
333
+ "time": "2019-03-08T08:55:37+00:00",
334
+ "type": "library",
335
+ "installation-source": "dist",
336
+ "autoload": {
337
+ "files": [
338
+ "src/getallheaders.php"
339
+ ]
340
+ },
341
+ "notification-url": "https://packagist.org/downloads/",
342
+ "license": [
343
+ "MIT"
344
+ ],
345
+ "authors": [
346
+ {
347
+ "name": "Ralph Khattar",
348
+ "email": "ralph.khattar@gmail.com"
349
+ }
350
+ ],
351
+ "description": "A polyfill for getallheaders.",
352
+ "support": {
353
+ "issues": "https://github.com/ralouphie/getallheaders/issues",
354
+ "source": "https://github.com/ralouphie/getallheaders/tree/develop"
355
+ }
356
+ },
357
+ {
358
+ "name": "wikimedia/composer-merge-plugin",
359
+ "version": "v1.4.1",
360
+ "version_normalized": "1.4.1.0",
361
+ "source": {
362
+ "type": "git",
363
+ "url": "https://github.com/wikimedia/composer-merge-plugin.git",
364
+ "reference": "81c6ac72a24a67383419c7eb9aa2b3437f2ab100"
365
+ },
366
+ "dist": {
367
+ "type": "zip",
368
+ "url": "https://api.github.com/repos/wikimedia/composer-merge-plugin/zipball/81c6ac72a24a67383419c7eb9aa2b3437f2ab100",
369
+ "reference": "81c6ac72a24a67383419c7eb9aa2b3437f2ab100",
370
+ "shasum": ""
371
+ },
372
+ "require": {
373
+ "composer-plugin-api": "^1.0",
374
+ "php": ">=5.3.2"
375
+ },
376
+ "require-dev": {
377
+ "composer/composer": "~1.0.0",
378
+ "jakub-onderka/php-parallel-lint": "~0.8",
379
+ "phpunit/phpunit": "~4.8|~5.0",
380
+ "squizlabs/php_codesniffer": "~2.1.0"
381
+ },
382
+ "time": "2017-04-25T02:31:25+00:00",
383
+ "type": "composer-plugin",
384
+ "extra": {
385
+ "branch-alias": {
386
+ "dev-master": "1.3.x-dev"
387
+ },
388
+ "class": "Wikimedia\\Composer\\MergePlugin"
389
+ },
390
+ "installation-source": "dist",
391
+ "autoload": {
392
+ "psr-4": {
393
+ "Wikimedia\\Composer\\": "src/"
394
+ }
395
+ },
396
+ "notification-url": "https://packagist.org/downloads/",
397
+ "license": [
398
+ "MIT"
399
+ ],
400
+ "authors": [
401
+ {
402
+ "name": "Bryan Davis",
403
+ "email": "bd808@wikimedia.org"
404
+ }
405
+ ],
406
+ "description": "Composer plugin to merge multiple composer.json files"
407
+ }
408
+ ]
vendor/composer/installed.php DELETED
@@ -1,131 +0,0 @@
1
- <?php return array(
2
- 'root' => array(
3
- 'pretty_version' => 'dev-trunk',
4
- 'version' => 'dev-trunk',
5
- 'type' => 'wordpress-plugin',
6
- 'install_path' => __DIR__ . '/../../',
7
- 'aliases' => array(),
8
- 'reference' => 'c0a727e4a85ecf1e51b60a26f371a7cb94f7e6e0',
9
- 'name' => 'woocommerce/woocommerce-paypal-payments',
10
- 'dev' => false,
11
- ),
12
- 'versions' => array(
13
- 'container-interop/service-provider' => array(
14
- 'pretty_version' => 'v0.4.0',
15
- 'version' => '0.4.0.0',
16
- 'type' => 'library',
17
- 'install_path' => __DIR__ . '/../container-interop/service-provider',
18
- 'aliases' => array(),
19
- 'reference' => '4969b9e49460690b7430b3f1a87cab07be61418a',
20
- 'dev_requirement' => false,
21
- ),
22
- 'dhii/collections-interface' => array(
23
- 'pretty_version' => 'v0.3.0-alpha4',
24
- 'version' => '0.3.0.0-alpha4',
25
- 'type' => 'library',
26
- 'install_path' => __DIR__ . '/../dhii/collections-interface',
27
- 'aliases' => array(),
28
- 'reference' => 'da334f75f6477ef7eecaf28df1d5253fe05684ee',
29
- 'dev_requirement' => false,
30
- ),
31
- 'dhii/containers' => array(
32
- 'pretty_version' => 'v0.1.0-alpha1',
33
- 'version' => '0.1.0.0-alpha1',
34
- 'type' => 'library',
35
- 'install_path' => __DIR__ . '/../dhii/containers',
36
- 'aliases' => array(),
37
- 'reference' => '73eed5422e106006c81ca1fa8b7213c6be33efbc',
38
- 'dev_requirement' => false,
39
- ),
40
- 'dhii/data-container-interface' => array(
41
- 'pretty_version' => 'v0.2.1-alpha1',
42
- 'version' => '0.2.1.0-alpha1',
43
- 'type' => 'library',
44
- 'install_path' => __DIR__ . '/../dhii/data-container-interface',
45
- 'aliases' => array(),
46
- 'reference' => '6be46e427184b95785d9dd563d6acf2e0700cc31',
47
- 'dev_requirement' => false,
48
- ),
49
- 'dhii/exception-interface' => array(
50
- 'pretty_version' => 'v0.2',
51
- 'version' => '0.2.0.0',
52
- 'type' => 'library',
53
- 'install_path' => __DIR__ . '/../dhii/exception-interface',
54
- 'aliases' => array(),
55
- 'reference' => 'b69feebf7cb2879cd43977a03342e2393b73f7fb',
56
- 'dev_requirement' => false,
57
- ),
58
- 'dhii/factory-interface' => array(
59
- 'pretty_version' => 'v0.1',
60
- 'version' => '0.1.0.0',
61
- 'type' => 'library',
62
- 'install_path' => __DIR__ . '/../dhii/factory-interface',
63
- 'aliases' => array(),
64
- 'reference' => 'b8d217aec8838e64ccaa770cb03dc164bf6f0515',
65
- 'dev_requirement' => false,
66
- ),
67
- 'dhii/module-interface' => array(
68
- 'pretty_version' => 'v0.3.0-alpha2',
69
- 'version' => '0.3.0.0-alpha2',
70
- 'type' => 'library',
71
- 'install_path' => __DIR__ . '/../dhii/module-interface',
72
- 'aliases' => array(),
73
- 'reference' => '0e39f167d7ed8990c82f5d2e6084159d1a502a5b',
74
- 'dev_requirement' => false,
75
- ),
76
- 'dhii/stringable-interface' => array(
77
- 'pretty_version' => 'v0.1',
78
- 'version' => '0.1.0.0',
79
- 'type' => 'library',
80
- 'install_path' => __DIR__ . '/../dhii/stringable-interface',
81
- 'aliases' => array(),
82
- 'reference' => 'b6653905eef2ebf377749feb80a6d18abbe913ef',
83
- 'dev_requirement' => false,
84
- ),
85
- 'dhii/wp-containers' => array(
86
- 'pretty_version' => 'v0.1.0-alpha1',
87
- 'version' => '0.1.0.0-alpha1',
88
- 'type' => 'library',
89
- 'install_path' => __DIR__ . '/../dhii/wp-containers',
90
- 'aliases' => array(),
91
- 'reference' => 'e91a6f741622770ed724a2b594145fa917811f0c',
92
- 'dev_requirement' => false,
93
- ),
94
- 'psr/container' => array(
95
- 'pretty_version' => '1.0.0',
96
- 'version' => '1.0.0.0',
97
- 'type' => 'library',
98
- 'install_path' => __DIR__ . '/../psr/container',
99
- 'aliases' => array(),
100
- 'reference' => 'b7ce3b176482dbbc1245ebf52b181af44c2cf55f',
101
- 'dev_requirement' => false,
102
- ),
103
- 'psr/log' => array(
104
- 'pretty_version' => '1.1.4',
105
- 'version' => '1.1.4.0',
106
- 'type' => 'library',
107
- 'install_path' => __DIR__ . '/../psr/log',
108
- 'aliases' => array(),
109
- 'reference' => 'd49695b909c3b7628b6289db5479a1c204601f11',
110
- 'dev_requirement' => false,
111
- ),
112
- 'ralouphie/getallheaders' => array(
113
- 'pretty_version' => '3.0.3',
114
- 'version' => '3.0.3.0',
115
- 'type' => 'library',
116
- 'install_path' => __DIR__ . '/../ralouphie/getallheaders',
117
- 'aliases' => array(),
118
- 'reference' => '120b605dfeb996808c31b6477290a714d356e822',
119
- 'dev_requirement' => false,
120
- ),
121
- 'woocommerce/woocommerce-paypal-payments' => array(
122
- 'pretty_version' => 'dev-trunk',
123
- 'version' => 'dev-trunk',
124
- 'type' => 'wordpress-plugin',
125
- 'install_path' => __DIR__ . '/../../',
126
- 'aliases' => array(),
127
- 'reference' => 'c0a727e4a85ecf1e51b60a26f371a7cb94f7e6e0',
128
- 'dev_requirement' => false,
129
- ),
130
- ),
131
- );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/composer/platform_check.php DELETED
@@ -1,26 +0,0 @@
1
- <?php
2
-
3
- // platform_check.php @generated by Composer
4
-
5
- $issues = array();
6
-
7
- if (!(PHP_VERSION_ID >= 70100)) {
8
- $issues[] = 'Your Composer dependencies require a PHP version ">= 7.1.0". You are running ' . PHP_VERSION . '.';
9
- }
10
-
11
- if ($issues) {
12
- if (!headers_sent()) {
13
- header('HTTP/1.1 500 Internal Server Error');
14
- }
15
- if (!ini_get('display_errors')) {
16
- if (PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg') {
17
- fwrite(STDERR, 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . implode(PHP_EOL, $issues) . PHP_EOL.PHP_EOL);
18
- } elseif (!headers_sent()) {
19
- echo 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . str_replace('You are running '.PHP_VERSION.'.', '', implode(PHP_EOL, $issues)) . PHP_EOL.PHP_EOL;
20
- }
21
- }
22
- trigger_error(
23
- 'Composer detected issues in your platform: ' . implode(' ', $issues),
24
- E_USER_ERROR
25
- );
26
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/dhii/collections-interface/CHANGELOG.md CHANGED
@@ -6,6 +6,9 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
6
 
7
  ## [[*next-version*]] - YYYY-MM-DD
8
 
 
 
 
9
  ## [0.3.0-alpha4] - 2021-03-09
10
  ### Fixed
11
  - Order of `extends` use to cause problems with newer versions
6
 
7
  ## [[*next-version*]] - YYYY-MM-DD
8
 
9
+ ## [0.3.0] - 2021-10-06
10
+ Stable release.
11
+
12
  ## [0.3.0-alpha4] - 2021-03-09
13
  ### Fixed
14
  - Order of `extends` use to cause problems with newer versions
vendor/dhii/collections-interface/composer.json CHANGED
@@ -22,7 +22,7 @@
22
  "require-dev": {
23
  "phpunit/phpunit": "^7.0 | ^8.0 | ^9.0",
24
  "slevomat/coding-standard": "^6.0",
25
- "vimeo/psalm": "^3.11.7 | ^4.0"
26
  },
27
  "autoload": {
28
  "psr-4": {
22
  "require-dev": {
23
  "phpunit/phpunit": "^7.0 | ^8.0 | ^9.0",
24
  "slevomat/coding-standard": "^6.0",
25
+ "vimeo/psalm": "^4.0"
26
  },
27
  "autoload": {
28
  "psr-4": {
vendor/dhii/collections-interface/psalm.xml.dist CHANGED
@@ -10,7 +10,6 @@
10
  strictBinaryOperands="true"
11
  rememberPropertyAssignmentsAfterCall="true"
12
  allowPhpStormGenerics="true"
13
- allowCoercionFromStringToClassConst="false"
14
  allowStringToStandInForClass="false"
15
  memoizeMethodCallResults="false"
16
  hoistConstants="false"
10
  strictBinaryOperands="true"
11
  rememberPropertyAssignmentsAfterCall="true"
12
  allowPhpStormGenerics="true"
 
13
  allowStringToStandInForClass="false"
14
  memoizeMethodCallResults="false"
15
  hoistConstants="false"
vendor/dhii/containers/.editorconfig ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ root = true
2
+
3
+ [*]
4
+ end_of_line = lf
5
+ insert_final_newline = true
6
+ indent_style = space
7
+ indent_size = 4
8
+
9
+ [*.js]
10
+ indent_size = 2
11
+
12
+ [*.json]
13
+ indent_size = 2
14
+
15
+ [*.yml]
16
+ indent_size = 2
vendor/dhii/containers/.env.example CHANGED
@@ -1,2 +1,8 @@
1
  BASE_PATH=./
2
- PROJECT_NAME=dhii_containers
 
 
 
 
 
 
1
  BASE_PATH=./
2
+ BUILD_ROOT_PATH=/app/
3
+ PROJECT_NAME=dhii_containers
4
+
5
+ PHP_BUILD_VERSION=7.1
6
+ PHP_TEST_VERSION=7.1
7
+
8
+ HOST_IP_ADDRESS=127.0.0.1
vendor/dhii/containers/CHANGELOG.md CHANGED
@@ -4,7 +4,40 @@ All notable changes to this project will be documented in this file.
4
  The format is based on [Keep a Changelog](http://keepachangelog.com/)
5
  and this project adheres to [Semantic Versioning](http://semver.org/).
6
 
7
- ## [[*next-version*]] - YYYY-MM-DD
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8
 
9
  ## [0.1.0-alpha1] - 2020-09-14
10
  Initial release.
4
  The format is based on [Keep a Changelog](http://keepachangelog.com/)
5
  and this project adheres to [Semantic Versioning](http://semver.org/).
6
 
7
+ ## [0.1.4] -2021-10-06
8
+ Stable release.
9
+
10
+ ## [0.1.4-alpha2] - 2021-03-10
11
+ ### Fixed
12
+ - Using newer interop interfaces fixes bug with new `psr/container` (#22).
13
+ - Many errors reported by Psalm, making code more resilient (#22).
14
+
15
+ ## [0.1.4-alpha1] - 2021-02-02
16
+ ### Added
17
+ - PHP 8 support!
18
+ - More tests, checks, QoL improvements, etc.
19
+
20
+ ## [0.1.3-alpha2] - 2020-10-23
21
+ ### Added
22
+ - `NoOpContainer` (#16).
23
+
24
+ ## [0.1.3-alpha1] - 2020-10-22
25
+ ### Added
26
+ - `FlashContainer` (#15).
27
+
28
+ ## [0.1.2] - 2020-10-22
29
+ Stable release.
30
+
31
+ ## [0.1.2-alpha1] - 2020-10-13
32
+ ### Added
33
+ - `SimpleCacheContainer`.
34
+
35
+ ## [0.1.1] - 2020-10-13
36
+ Stable release
37
+
38
+ ## [0.1.1-alpha1] - 2020-09-14
39
+ ### Fixed
40
+ - Missing parameter type in `MaskingContainer`'s constructor (#11).
41
 
42
  ## [0.1.0-alpha1] - 2020-09-14
43
  Initial release.
vendor/dhii/containers/README.md CHANGED
@@ -1,14 +1,151 @@
1
  # Dhii - Containers
2
-
3
- [![Build Status](https://travis-ci.org/Dhii/containers.svg?branch=master)](https://travis-ci.org/Dhii/containers)
4
- [![Code Climate](https://codeclimate.com/github/Dhii/containers/badges/gpa.svg)](https://codeclimate.com/github/Dhii/containers)
5
- [![Test Coverage](https://codeclimate.com/github/Dhii/containers/badges/coverage.svg)](https://codeclimate.com/github/Dhii/containers/coverage)
6
- [![Join the chat at https://gitter.im/Dhii/containers](https://badges.gitter.im/Dhii/containers.svg)](https://gitter.im/Dhii/containers?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
7
- [![This package complies with Dhii standards](https://img.shields.io/badge/Dhii-Compliant-green.svg?style=flat-square)][Dhii]
8
 
9
  ## Details
10
  A selection of [PSR-11][] containers for utility, simplicity, and ease.
11
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
12
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
13
  [Dhii]: https://github.com/Dhii/dhii
14
  [PSR-11]: https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-11-container.md
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  # Dhii - Containers
2
+ [![Continuous Integration](https://github.com/Dhii/containers/actions/workflows/ci.yml/badge.svg)](https://github.com/Dhii/containers/actions/workflows/ci.yml)
3
+ [![Latest Stable Version](https://poser.pugx.org/dhii/containers/v)](//packagist.org/packages/dhii/containers)
4
+ [![Latest Unstable Version](https://poser.pugx.org/dhii/containers/v/unstable)](//packagist.org/packages/dhii/containers)
 
 
 
5
 
6
  ## Details
7
  A selection of [PSR-11][] containers for utility, simplicity, and ease.
8
 
9
+ ### Generic
10
+ - [`CachingContainer`][] - A decorator that [separates the concern][SoC] of caching, allowing for caching of any container's values.
11
+ - [`CompositeContainer`][] - A container that is composed of multiple other containers. On key access, iterates over its internal list of containers, and accesses that key of the first container which has that key. Useful for merging configuration from multiple sources, without actually doing any merging.
12
+ - [`ProxyContainer`][] - A container that forwards access to 1 other container, which can be assigned after construction. Useful for solving container-related recursive dependency problems, for example for lookup delegation.
13
+ - [`AliasingContainer`][] - A decorator that provides access to another container via aliased keys. Useful when an immutable map needs to have its keys changed.
14
+ - [`MappingContainer`][] - A decorator that uses a callback to manipulate values retrieved from another container on the fly.
15
+ - [`PrefixingContainer`][] - A decorator that allows access to another container's values via prefixed keys. Can also fall back to non-prefixed keys. Useful when e.g. enforcing a prefixing naming convention on keys. The opposite of `DeprefixingContainer`.
16
+ - [`DeprefixingContainer`][] - A decorator that allows access to another container's values that have prefixed keys - without the prefix. Useful for e.g. simplification of keys that follow a prefixiing naming convention. The opposite of `PrefixingContainer`.
17
+ - [`MaskingContainer`][] - A decorator that selectively hides or exposes keys of another container. Useful when working with maps that have a defined structure.
18
+ - [`PathContainer`][] - A decorator that allows access to a hierarchy of nested container via path-like keys. Useful when accessing configuration merged from multiple sources.
19
+ - [`SegmentingContainer`][] - A decorator that allows access to a container with delimiter-separated path-like keys as if it were a hierarchy of containers. Useful isolating a segment of configuration when using a path-like naming convention for keys (such as namespacing). The opposite of `PathContainer`.
20
+ - [`HierarchyContainer`][] - A container that allows access to a arbitrary hierarchy of arrays as if it was a hierarchy of containers. Creates containers in place, and caches them for future re-use.
21
+ - [`Dictionary`][] - Allows access to an array via a container interface, without sacrificing iterability.
22
+ - [`DataStructureBasedFactory`][] allows this to be recursive for an array hierarchy of an arbitrary depth. Useful for transforming an array into a container, especially with other decorators.
23
+ - [`SimpleCacheContainer`][] - A decorator that presents a PSR-16 cache as a mutable, clearable container with fixed TTL.
24
+ - [`FlashContainer`][] - A decorator that presents a value from an inner storage container as another container, copying that value into memory, then clearing it from storage.
25
+ - [`NoOpContainer`][] - A no-op writable mutable clearable map that does nothing, and cannot have any values.
26
+
27
+ ### DI
28
+ - [`ServiceProvider`][] - A super-simple implementation that allows quick creation of [service providers][Service Provider] from known maps of factories and extensions.
29
+ - [`CompositeCachingServiceProvider`][] - A service provider that aggregates factories and extensions of other service providers. The results of this aggregation will be cached, meaing that it is only performed at most once per instance - when retrieving said factories or extensions.
30
+ - [`DelegatingContainer`][] - A container that will invoke the factories and extensions of its configured service provider before returning values. If a parent container is specified, it will be passed to the service definitions instead of this container. This allows [dependency lookup delegation][DDL], which is especially useful when composing a container out of other containers.
31
+
32
+ ## Examples
33
+
34
+ ### Application Container
35
+ Most modern applications use some kind of DI container setup. The below example demonstrates a use-case where all configuration is composed of different sources, accessible via a single source of truth, services are cached per request.
36
+
37
+ ```php
38
+ // Retrieve factories and extensions from respective files, and create a service provider with them
39
+ $factories = require('factories.php');
40
+ $extensions = require('extensions.php');
41
+ $appProvider = new ServiceProvider($factories, $extensions);
42
+
43
+ // Perhaps retrieve service providers from other modules and aggregate them
44
+ $provider = new CompositeCachingServiceProvider([$appProvider, $moduleProviderA, $moduleProviderB]);
45
+
46
+ $proxyContainer = new ProxyContainer(); // A temporary parent container for lookup delegation
47
+ $container = new DelegatingContainer($provider, $proxyContainer); // Container with application configuration
48
+ $appContainer = new CompositeContainer([ // The application's container
49
+ $dbContainer, // <-- Perhaps another container with configuration from DB
50
+ $container, // <-- The main container with merged configuration from modules
51
+ ]);
52
+ $appContainer = new CachingContainer($appContainer); // Add caching, so that each service definition is only invoked once
53
+ $proxyContainer->setInnerContainer($appContainer); // Switch lookup to the application's main container, making it available in service definitions
54
+
55
+ // Retrieve cached configuration aggregated from various modules and other sources, sucha as the database or a remote API
56
+ $appContainer->get('my-service');
57
+ ```
58
+
59
+ ### Fun Things With Maps
60
+ Maps are very commonly used in applications to represent some key-value relationships. We decided that PSR-11 containers are a great way to represent maps in an interop way. Here are some of the things you can do.
61
+
62
+ ```php
63
+ // App configuration, perhaps from a file
64
+ $config = [
65
+ 'dev' => [
66
+ 'db' => [
67
+ 'host' => 'localhost',
68
+ 'username' => 'root',
69
+ 'password' => '',
70
+ 'database' => 'my_app',
71
+ ],
72
+ 'staging' => [
73
+ 'db' => [
74
+ 'host' => '123.abc.com',
75
+ 'username' => 'application123',
76
+ 'password' => '$*!@$T123SAfa',
77
+ 'database' => 'my_app',
78
+ ],
79
+ ],
80
+ ];
81
+
82
+ // Can create container hierarchies of arbitrary depths from array hierarchies
83
+ $factory = new DataStructureBasedFactory(new DictionaryFactory());
84
+ // The new configuration interface
85
+ $config = $factory->createContainerFromArray($config);
86
+
87
+ // Output the DB host names for each environment
88
+ foreach ($config as $env => $envConfig) {
89
+ echo $env . ': ' . $envConfig->get('db')->get('host') . PHP_EOL; // Print 'dev: localhost' then 'staging: 123.abc.com'
90
+ }
91
 
92
+ // Access configuration using a path
93
+ $config = new PathContainer($config, '/');
94
+ echo $config->get('staging/db/username'); // Print 'application123'
95
+
96
+ // Access dev env DB config with a 'local_' prefix
97
+ $localDbConfig = new PrefixingContainer($config->get('dev/db'), 'local_');
98
+ echo $localDbConfig->get('local_username'); // Print 'root'
99
+
100
+ // Effectively adds production DB configuration
101
+ $productionConfig = new Dictionary([
102
+ 'production' => [
103
+ 'db' => [
104
+ 'host' => 'db.myserver.com',
105
+ 'username' => 'D97rh1d0A&13',
106
+ 'password' => 'DN(Q(u3dgh3q87g3',
107
+ 'database' => 'my_app',
108
+ ],
109
+ ],
110
+ ]);
111
+ $config = new CompositeContainer([$config, $productionConfig]);
112
+ echo $config->get('production/db/password'); // Print 'DN(Q(u3dgh3q87g3'
113
+ echo $config->get('dev/db/password'); // Print '': all of the old configuration is available on this new container
114
+
115
+ // Make production host also available as 'live_db_host' - maybe something requires it to be at that key, and not in a path
116
+ $config = new AliasingContainer($config, ['live_db_host' => 'production/db/host']);
117
+ echo $config->get('live_db_host'); // Print 'db.myserver.com'
118
+ echo $config->get('production/db/host'); // That value is still accessible by the original full path
119
+
120
+ // Isolate production DB configuration, but without the 'password' key - perhaps to be passed to the UI, or another untrusted party
121
+ $productionConfig = new MaskingContainer($config->get('production/db'), true, ['password' => false]);
122
+ echo $productionConfig->get('password'); // NotFoundException: This key does not exist for this container
123
+ ```
124
+
125
+
126
+ [Service Provider]: https://github.com/container-interop/service-provider/
127
  [Dhii]: https://github.com/Dhii/dhii
128
  [PSR-11]: https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-11-container.md
129
+ [SoC]: https://dev.to/xedinunknown/separation-of-concerns-3e7d
130
+
131
+ [`ServiceProvider`]: src/ServiceProvider.php
132
+ [`CompositeCachingServiceProvider`]: src/CompositeCachingServiceProvider.php
133
+ [`DelegatingContainer`]: src/DelegatingContainer.php
134
+ [`CachingContainer`]: src/CachingContainer.php
135
+ [`CompositeContainer`]: src/CompositeContainer.php
136
+ [`ProxyContainer`]: src/ProxyContainer.php
137
+ [`AliasingContainer`]: src/AliasingContainer.php
138
+ [`MappingContainer`]: src/MappingContainer.php
139
+ [`PrefixingContainer`]: src/PrefixingContainer.php
140
+ [`DeprefixingContainer`]: src/DeprefixingContainer.php
141
+ [`MaskingContainer`]: src/MaskingContainer.php
142
+ [`PathContainer`]: src/PathContainer.php
143
+ [`SegmentingContainer`]: src/SegmentingContainer.php
144
+ [`HierarchyContainer`]: src/HierarchyContainer.php
145
+ [`Dictionary`]: src/Dictionary.php
146
+ [`DataStructureBasedFactory`]: src/DataStructureBasedFactory.php
147
+ [`SimpleCacheContainer`]: src/SimpleCacheContainer.php
148
+ [`FlashContainer`]: src/FlashContainer.php
149
+ [`NoOpContainer`]: src/NoOpContainer.php
150
+
151
+ [DDL]: https://thecodingmachine.io/psr-11-an-in-depth-view-at-the-delegate-lookup-feature
vendor/dhii/containers/composer.json CHANGED
@@ -14,17 +14,20 @@
14
  }
15
  ],
16
  "minimum-stability": "dev",
17
- "prefer-stable": true,
18
  "require": {
19
  "php": "^7.1 | ^8.0",
20
- "dhii/collections-interface": "^0.3.0-alpha1",
21
  "container-interop/service-provider": "^0.4"
22
  },
23
  "require-dev": {
24
- "slevomat/coding-standard": "~4.0",
25
- "phpunit/phpunit": "^7.0",
 
26
  "gmazzap/andrew": "^1.1",
27
- "psr/container": "^1.0"
 
 
28
  },
29
  "autoload": {
30
  "psr-4": {
@@ -33,9 +36,10 @@
33
  },
34
  "autoload-dev": {
35
  "psr-4": {
36
- "Dhii\\Container\\UnitTest\\": "test/unit",
37
- "Dhii\\Container\\FuncTest\\": "test/functional",
38
- "Dhii\\Container\\TestHelpers\\": "test/helpers"
 
39
  }
40
  },
41
  "extra": {
14
  }
15
  ],
16
  "minimum-stability": "dev",
17
+ "prefer-stable": false,
18
  "require": {
19
  "php": "^7.1 | ^8.0",
20
+ "dhii/collections-interface": "^0.3.0-alpha4",
21
  "container-interop/service-provider": "^0.4"
22
  },
23
  "require-dev": {
24
+ "slevomat/coding-standard": "^6.0",
25
+ "phpunit/phpunit": "^7.0 | ^8.0 | ^9.0",
26
+ "vimeo/psalm": "^4.0",
27
  "gmazzap/andrew": "^1.1",
28
+ "psr/container": "^1.0",
29
+ "psr/simple-cache": "^1.0",
30
+ "wildwolf/psr-memory-cache": "^1.0"
31
  },
32
  "autoload": {
33
  "psr-4": {
36
  },
37
  "autoload-dev": {
38
  "psr-4": {
39
+ "Dhii\\Container\\UnitTest\\": "tests/unit",
40
+ "Dhii\\Container\\FuncTest\\": "tests/functional",
41
+ "Dhii\\Container\\SysTest\\": "tests/system",
42
+ "Dhii\\Container\\TestHelpers\\": "tests/helpers"
43
  }
44
  },
45
  "extra": {
vendor/dhii/containers/docker-compose.yml CHANGED
@@ -1,9 +1,31 @@
1
- version: '3.2'
2
  services:
3
- php:
4
- container_name: "${PROJECT_NAME}_php"
5
  build:
6
- context: docker
7
- dockerfile: Dockerfile_php
 
 
 
 
 
 
8
  volumes:
9
- - ${BASE_PATH}:/srv/
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ version: '3.4'
2
  services:
3
+
4
+ build:
5
  build:
6
+ context: ./
7
+ dockerfile: docker/Dockerfile
8
+ target: build
9
+ args:
10
+ PHP_BUILD_VERSION: $PHP_BUILD_VERSION
11
+ BUILD_ROOT_PATH: $BUILD_ROOT_PATH
12
+ container_name: "${PROJECT_NAME}_build"
13
+ working_dir: ${BUILD_ROOT_PATH}
14
  volumes:
15
+ - ${BASE_PATH}:${BUILD_ROOT_PATH}
16
+
17
+ test:
18
+ extra_hosts:
19
+ - "host.docker.internal:${HOST_IP_ADDRESS}"
20
+ build:
21
+ context: ./
22
+ dockerfile: docker/Dockerfile
23
+ target: test
24
+ args:
25
+ BUILD_ROOT_PATH: $BUILD_ROOT_PATH
26
+ PHP_BUILD_VERSION: $PHP_BUILD_VERSION
27
+ PHP_TEST_VERSION: $PHP_TEST_VERSION
28
+ container_name: "${PROJECT_NAME}_test"
29
+ working_dir: ${BUILD_ROOT_PATH}
30
+ volumes:
31
+ - ${BASE_PATH}:${BUILD_ROOT_PATH}
vendor/dhii/containers/docker/Dockerfile ADDED
@@ -0,0 +1,39 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ARG PHP_BUILD_VERSION
2
+ ARG PHP_TEST_VERSION
3
+
4
+ # Composer on correct PHP version
5
+ FROM php:${PHP_BUILD_VERSION}-cli as build
6
+
7
+ ARG BUILD_ROOT_PATH
8
+
9
+ RUN mv "$PHP_INI_DIR/php.ini-production" "$PHP_INI_DIR/php.ini"
10
+ RUN apt-get update
11
+ RUN apt-get install -y zip unzip curl git
12
+ RUN php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
13
+ RUN php composer-setup.php --install-dir=/usr/bin --filename=composer
14
+ RUN php -r "unlink('composer-setup.php');"
15
+
16
+ WORKDIR ${BUILD_ROOT_PATH}
17
+ COPY . ./
18
+
19
+
20
+ FROM php:${PHP_TEST_VERSION}-cli as test
21
+
22
+ ARG BUILD_ROOT_PATH
23
+
24
+ RUN mv "$PHP_INI_DIR/php.ini-production" "$PHP_INI_DIR/php.ini"
25
+ RUN pecl install xdebug-2.6.0
26
+ RUN docker-php-ext-install pcntl
27
+ RUN docker-php-ext-install posix
28
+
29
+ WORKDIR ${BUILD_ROOT_PATH}
30
+ COPY --from=build ${BUILD_ROOT_PATH} ${BUILD_ROOT_PATH}
31
+
32
+
33
+ # Install PHP dev dependencies
34
+ FROM build as vendor-dev
35
+
36
+ ARG BUILD_ROOT_PATH
37
+
38
+ WORKDIR ${BUILD_ROOT_PATH}
39
+ RUN composer install
vendor/dhii/containers/docker/Dockerfile_php DELETED
@@ -1,6 +0,0 @@
1
- FROM dockette/php:7.1
2
-
3
- RUN apt-get update \
4
- && apt-get -y install software-properties-common dirmngr apt-transport-https lsb-release ca-certificates \
5
- && add-apt-repository -y ppa:ondrej/php \
6
- && apt-get install -y php7.1-xdebug
 
 
 
 
 
 
vendor/dhii/containers/phpcs.xml.dist CHANGED
@@ -1,43 +1,49 @@
1
  <?xml version="1.0"?>
2
- <ruleset name="wp-jobadder">
3
- <file>./main.php</file>
 
 
4
  <file>./src</file>
5
- <file>./includes</file>
6
 
7
- <rule ref="vendor/consistence/coding-standard/Consistence/ruleset.xml">
8
- <!-- Use 4 spaces per indent -->
9
- <exclude name="Generic.WhiteSpace.DisallowSpaceIndent" />
10
- <rule ref="Generic.WhiteSpace.DisallowTabIndent" />
11
- <rule ref="Generic.WhiteSpace.ScopeIndent">
12
- <properties>
13
- <property name="indent" value="4"/>
14
- <property name="tabIndent" value="false"/>
15
- </properties>
16
- </rule>
17
 
18
- <!-- We can use double quotes as templates -->
19
- <exclude name="Squiz.Strings.DoubleQuoteUsage.ContainsVar" />
20
- </rule>
21
 
22
- <rule ref="vendor/slevomat/coding-standard/SlevomatCodingStandard/ruleset.xml">
23
- <!-- PSR-4 mapping already in Composer -->
24
- <exclude name="SlevomatCodingStandard.Files.TypeNameMatchesFileName" />
 
 
 
 
 
 
 
 
 
 
 
 
 
 
25
 
26
- <!-- There's no reason to have to specify FQNs everywhere if they can be imported -->
27
- <exclude name="SlevomatCodingStandard.Namespaces.FullyQualifiedClassNameAfterKeyword"/>
28
- <exclude name="SlevomatCodingStandard.Namespaces.FullyQualifiedClassNameInAnnotation.NonFullyQualifiedClassName" />
29
- <exclude name="SlevomatCodingStandard.Namespaces.FullyQualifiedExceptions.NonFullyQualifiedException" />
30
- <exclude name="SlevomatCodingStandard.Namespaces.UseOnlyWhitelistedNamespaces" />
31
- <exclude name="SlevomatCodingStandard.Namespaces.ReferenceUsedNamesOnly"/>
32
- <!-- The fallback mechanism is safe enough, and can be good for mocking -->
33
- <exclude name="SlevomatCodingStandard.Namespaces.FullyQualifiedGlobalConstants" />
34
- <exclude name="SlevomatCodingStandard.Namespaces.FullyQualifiedGlobalFunctions" />
35
 
36
- <!-- Sometimes it's fine to work with a list of anything -->
37
- <exclude name="SlevomatCodingStandard.TypeHints.TypeHintDeclaration.MissingTraversableParameterTypeHintSpecification"/>
38
- <exclude name="SlevomatCodingStandard.TypeHints.TypeHintDeclaration.MissingTraversableReturnTypeHintSpecification"/>
39
 
40
- <!-- Doc can be a work in progress -->
41
- <exclude name="SlevomatCodingStandard.TypeHints.TypeHintDeclaration.UselessDocComment" />
 
 
 
 
 
42
  </rule>
 
 
 
 
 
43
  </ruleset>
1
  <?xml version="1.0"?>
2
+ <ruleset name="plugin"
3
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4
+ xsi:noNamespaceSchemaLocation="https://raw.githubusercontent.com/squizlabs/PHP_CodeSniffer/master/phpcs.xsd">
5
+
6
  <file>./src</file>
 
7
 
 
 
 
 
 
 
 
 
 
 
8
 
9
+ <config name="installed_paths" value="../../slevomat/coding-standard"/>
 
 
10
 
11
+ <rule ref="PSR12"/>
12
+ <rule ref="SlevomatCodingStandard.TypeHints.PropertyTypeHint">
13
+ <type>warning</type>
14
+ </rule>
15
+ <rule ref="SlevomatCodingStandard.TypeHints.ReturnTypeHint"/>
16
+ <rule ref="SlevomatCodingStandard.TypeHints.UselessConstantTypeHint"/>
17
+ <rule ref="SlevomatCodingStandard.TypeHints.DeclareStrictTypes">
18
+ <properties>
19
+ <property name="newlinesCountBetweenOpenTagAndDeclare" value="2"/>
20
+ <property name="newlinesCountAfterDeclare" value="2"/>
21
+ <property name="spacesCountAroundEqualsSign" value="0"/>
22
+ </properties>
23
+ </rule>
24
+ <rule ref="SlevomatCodingStandard.Classes.ClassStructure">
25
+ <properties>
26
+ <property name="groups" type="array">
27
+ <element value="uses"/>
28
 
29
+ <!-- Public constants are first but you don't care about the order of protected or private constants -->
30
+ <element value="public constants"/>
31
+ <element value="constants"/>
 
 
 
 
 
 
32
 
33
+ <!-- You don't care about the order among the properties. The same can be done with "properties" shortcut -->
34
+ <element value="public properties, protected properties, private properties, properties"/>
 
35
 
36
+ <!-- Constructor is first, then all public methods, then protected/private methods and magic methods are last -->
37
+ <element value="constructor"/>
38
+ <element value="all public methods"/>
39
+ <element value="methods"/>
40
+ <element value="magic methods"/>
41
+ </property>
42
+ </properties>
43
  </rule>
44
+ <rule ref="SlevomatCodingStandard.ControlStructures.DisallowContinueWithoutIntegerOperandInSwitch"/>
45
+ <rule ref="SlevomatCodingStandard.ControlStructures.RequireNullCoalesceOperator"/>
46
+ <rule ref="SlevomatCodingStandard.PHP.DisallowDirectMagicInvokeCall"/>
47
+ <rule ref="SlevomatCodingStandard.Operators.DisallowEqualOperators"/>
48
+ <rule ref="SlevomatCodingStandard.Operators.RequireCombinedAssignmentOperator"/>
49
  </ruleset>
vendor/dhii/containers/phpmd.xml DELETED
@@ -1,24 +0,0 @@
1
- <?xml version="1.0"?>
2
-
3
- <ruleset name="Dhii Standard"
4
- xmlns="http://pmd.sf.net/ruleset/1.0.0"
5
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
6
- xsi:schemaLocation="http://pmd.sf.net/ruleset/1.0.0
7
- http://pmd.sf.net/ruleset_xml_schema.xsd"
8
- xsi:noNamespaceSchemaLocation="http://pmd.sf.net/ruleset_xml_schema.xsd">
9
- <description>A standard Dhii ruleset</description>
10
-
11
- <!-- Standard Rules of CodeClimate -->
12
- <rule ref="rulesets/cleancode.xml" />
13
- <rule ref="rulesets/codesize.xml" />
14
- <rule ref="rulesets/design.xml" />
15
- <rule ref="rulesets/naming.xml" />
16
- <rule ref="rulesets/unusedcode.xml" />
17
-
18
-
19
- <rule ref="rulesets/controversial.xml/CamelCaseMethodName">
20
- <properties>
21
- <property name="allow-underscore" value="true" />
22
- </properties>
23
- </rule>
24
- </ruleset>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/dhii/containers/phpunit.xml.dist ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <phpunit
3
+ colors="true"
4
+ bootstrap="tests/bootstrap.php"
5
+ >
6
+ <php>
7
+ <ini name="display_errors" value="1" />
8
+ <ini name="display_startup_errors" value="1" />
9
+ </php>
10
+ <testsuites>
11
+ <testsuite name="functional">
12
+ <directory>tests/functional</directory>
13
+ </testsuite>
14
+ <testsuite name="unit">
15
+ <directory>tests/unit</directory>
16
+ </testsuite>
17
+ <testsuite name="system">
18
+ <directory>tests/system</directory>
19
+ </testsuite>
20
+ </testsuites>
21
+ <filter>
22
+ <whitelist processUncoveredFilesFromWhitelist="true">
23
+ <directory suffix=".php">src</directory>
24
+ </whitelist>
25
+ </filter>
26
+ </phpunit>
vendor/dhii/containers/psalm.xml.dist ADDED
@@ -0,0 +1,152 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <psalm
3
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4
+ xmlns="https://getpsalm.org/schema/config"
5
+ xsi:schemaLocation="https://getpsalm.org/schema/config vendor/vimeo/psalm/config.xsd"
6
+ xmlns:xi="http://www.w3.org/2001/XInclude"
7
+ totallyTyped="false"
8
+ useDocblockTypes="true"
9
+ usePhpDocMethodsWithoutMagicCall="false"
10
+ strictBinaryOperands="true"
11
+ rememberPropertyAssignmentsAfterCall="true"
12
+ allowPhpStormGenerics="true"
13
+ allowStringToStandInForClass="false"
14
+ memoizeMethodCallResults="false"
15
+ hoistConstants="false"
16
+ addParamDefaultToDocblockType="false"
17
+ checkForThrowsDocblock="true"
18
+ checkForThrowsInGlobalScope="false"
19
+ ignoreInternalFunctionFalseReturn="false"
20
+ ignoreInternalFunctionNullReturn="false"
21
+ throwExceptionOnError="false"
22
+ hideExternalErrors="true"
23
+ allowFileIncludes="true"
24
+ >
25
+ <projectFiles>
26
+ <directory name="src"/>
27
+ </projectFiles>
28
+
29
+ <extraFiles>
30
+ <ignoreFiles>
31
+ <directory name="vendor/phpspec/prophecy"/>
32
+ </ignoreFiles>
33
+ </extraFiles>
34
+
35
+
36
+ <issueHandlers>
37
+ <ConflictingReferenceConstraint errorLevel="error"/>
38
+ <ContinueOutsideLoop errorLevel="error"/>
39
+ <DuplicateArrayKey errorLevel="error"/>
40
+ <DuplicateClass errorLevel="error"/>
41
+ <DuplicateFunction errorLevel="error"/>
42
+ <DuplicateMethod errorLevel="error"/>
43
+ <DuplicateParam errorLevel="error"/>
44
+ <EmptyArrayAccess errorLevel="error"/>
45
+ <FalsableReturnStatement errorLevel="error"/>
46
+ <FalseOperand errorLevel="error"/>
47
+ <ForbiddenCode errorLevel="error"/>
48
+ <ForbiddenEcho errorLevel="error"/>
49
+ <InaccessibleClassConstant errorLevel="error"/>
50
+ <InaccessibleMethod errorLevel="error"/>
51
+ <InterfaceInstantiation errorLevel="error"/>
52
+ <InaccessibleProperty errorLevel="error"/>
53
+ <InternalClass errorLevel="error"/>
54
+ <InternalMethod errorLevel="error"/>
55
+ <InternalProperty errorLevel="error"/>
56
+ <InvalidArgument errorLevel="error"/>
57
+ <InvalidArrayAccess errorLevel="error"/>
58
+ <InvalidArrayAssignment errorLevel="error"/>
59
+ <InvalidArrayOffset errorLevel="error"/>
60
+ <InvalidCast errorLevel="error"/>
61
+ <InvalidCatch errorLevel="error"/>
62
+ <InvalidClass errorLevel="error"/>
63
+ <InvalidClone errorLevel="error"/>
64
+ <InvalidFalsableReturnType errorLevel="error"/>
65
+ <InvalidThrow errorLevel="error"/>
66
+ <InvalidToString errorLevel="error"/>
67
+ <LoopInvalidation errorLevel="error"/>
68
+ <InvalidNullableReturnType errorLevel="error"/>
69
+ <LessSpecificReturnType errorLevel="error"/>
70
+ <InvalidGlobal errorLevel="error"/>
71
+ <InvalidIterator errorLevel="error"/>
72
+ <InvalidMethodCall errorLevel="error"/>
73
+ <InvalidFunctionCall errorLevel="error"/>
74
+ <ImplicitToStringCast errorLevel="error"/>
75
+ <ImplementedReturnTypeMismatch errorLevel="error"/>
76
+ <InvalidParamDefault errorLevel="error"/>
77
+ <InvalidPassByReference errorLevel="error"/>
78
+ <InvalidPropertyAssignment errorLevel="error"/>
79
+ <InvalidPropertyAssignmentValue errorLevel="error"/>
80
+ <InvalidPropertyFetch errorLevel="error"/>
81
+ <InvalidReturnStatement errorLevel="error"/>
82
+ <InvalidReturnType errorLevel="error"/>
83
+ <InvalidScalarArgument errorLevel="error"/>
84
+ <InvalidScope errorLevel="error"/>
85
+ <InvalidStaticInvocation errorLevel="error"/>
86
+ <MissingConstructor errorLevel="error"/>
87
+ <MissingDependency errorLevel="error"/>
88
+ <MissingFile errorLevel="error"/>
89
+ <MixedArgument errorLevel="error"/>
90
+ <MoreSpecificImplementedParamType errorLevel="error"/>
91
+ <MoreSpecificReturnType errorLevel="error"/>
92
+ <NoValue errorLevel="error"/>
93
+ <NoInterfaceProperties errorLevel="error"/>
94
+ <NonStaticSelfCall errorLevel="error"/>
95
+ <NullableReturnStatement errorLevel="error"/>
96
+ <NullArgument errorLevel="error"/>
97
+ <NullArrayAccess errorLevel="error"/>
98
+ <NullArrayOffset errorLevel="error"/>
99
+ <NullFunctionCall errorLevel="error"/>
100
+ <NullIterator errorLevel="error"/>
101
+ <NullOperand errorLevel="error"/>
102
+ <NullPropertyAssignment errorLevel="error"/>
103
+ <NullPropertyFetch errorLevel="error"/>
104
+ <NullReference errorLevel="error"/>
105
+ <OverriddenMethodAccess errorLevel="error"/>
106
+ <OverriddenPropertyAccess errorLevel="error"/>
107
+ <ParadoxicalCondition errorLevel="error"/>
108
+ <ParentNotFound errorLevel="error"/>
109
+ <LessSpecificImplementedReturnType errorLevel="error"/>
110
+ <MissingParamType errorLevel="error"/>
111
+ <MissingClosureParamType errorLevel="error"/>
112
+ <MissingClosureReturnType errorLevel="error"/>
113
+ <MissingPropertyType errorLevel="error"/>
114
+ <UndefinedConstant errorLevel="error"/>
115
+
116
+ <AssignmentToVoid errorLevel="info"/>
117
+ <DeprecatedClass errorLevel="info"/>
118
+ <DeprecatedConstant errorLevel="info"/>
119
+ <DeprecatedTrait errorLevel="info"/>
120
+ <DocblockTypeContradiction errorLevel="info"/>
121
+ <InvalidDocblock errorLevel="info"/>
122
+ <InvalidDocblockParamName errorLevel="info"/>
123
+ <InvalidTemplateParam errorLevel="info"/>
124
+ <DeprecatedInterface errorLevel="info"/>
125
+ <DeprecatedMethod errorLevel="info"/>
126
+ <DeprecatedProperty errorLevel="info"/>
127
+ <MethodSignatureMustOmitReturnType errorLevel="info"/>
128
+ <MismatchingDocblockParamType errorLevel="info"/>
129
+ <MismatchingDocblockReturnType errorLevel="info"/>
130
+ <MissingDocblockType errorLevel="info"/>
131
+ <MissingParamType errorLevel="info"/>
132
+ <MissingTemplateParam errorLevel="info"/>
133
+ <MissingThrowsDocblock errorLevel="info"/>
134
+ <MixedArgumentTypeCoercion errorLevel="info"/>
135
+ <MixedArrayAccess errorLevel="info"/>
136
+ <MixedArrayAssignment errorLevel="info"/>
137
+ <MixedArrayOffset errorLevel="info"/>
138
+ <MixedArrayTypeCoercion errorLevel="info"/>
139
+ <MixedAssignment errorLevel="info"/>
140
+ <MixedFunctionCall errorLevel="info"/>
141
+ <MixedInferredReturnType errorLevel="info"/>
142
+ <MixedMethodCall errorLevel="info"/>
143
+ <MixedOperand errorLevel="info"/>
144
+ <MixedPropertyAssignment errorLevel="info"/>
145
+ <MixedPropertyFetch errorLevel="info"/>
146
+ <MixedPropertyTypeCoercion errorLevel="info"/>
147
+ <MixedReturnStatement errorLevel="info"/>
148
+ <MixedReturnTypeCoercion errorLevel="info"/>
149
+ <MixedStringOffsetAssignment errorLevel="info"/>
150
+ <ParamNameMismatch errorLevel="info"/>
151
+ </issueHandlers>
152
+ </psalm>
vendor/dhii/containers/src/AliasingContainer.php CHANGED
@@ -1,10 +1,13 @@
1
  <?php
2
 
 
 
3
  namespace Dhii\Container;
4
 
5
  use Dhii\Collection\ContainerInterface;
6
  use Dhii\Container\Util\StringTranslatingTrait;
7
  use Psr\Container\ContainerInterface as PsrContainerInterface;
 
8
  use function array_key_exists;
9
 
10
  /**
@@ -26,7 +29,7 @@ class AliasingContainer implements ContainerInterface
26
  /**
27
  * @since [*next-version*]
28
  *
29
- * @var array
30
  */
31
  protected $aliases;
32
 
@@ -35,8 +38,8 @@ class AliasingContainer implements ContainerInterface
35
  *
36
  * @since [*next-version*]
37
  *
38
- * @param PsrContainerInterface $inner The container whose keys to alias.
39
- * @param array $aliases A mapping of aliases to their original container key counterparts.
40
  */
41
  public function __construct(PsrContainerInterface $inner, array $aliases)
42
  {
@@ -73,7 +76,7 @@ class AliasingContainer implements ContainerInterface
73
  *
74
  * @return string The inner key.
75
  */
76
- protected function getInnerKey($key)
77
  {
78
  if (array_key_exists($key, $this->aliases)) {
79
  return $this->aliases[$key];
1
  <?php
2
 
3
+ declare(strict_types=1);
4
+
5
  namespace Dhii\Container;
6
 
7
  use Dhii\Collection\ContainerInterface;
8
  use Dhii\Container\Util\StringTranslatingTrait;
9
  use Psr\Container\ContainerInterface as PsrContainerInterface;
10
+
11
  use function array_key_exists;
12
 
13
  /**
29
  /**
30
  * @since [*next-version*]
31
  *
32
+ * @var array<array-key, string>
33
  */
34
  protected $aliases;
35
 
38
  *
39
  * @since [*next-version*]
40
  *
41
+ * @param PsrContainerInterface $inner The container whose keys to alias.
42
+ * @param array<array-key, string> $aliases A mapping of aliases to their original container key counterparts.
43
  */
44
  public function __construct(PsrContainerInterface $inner, array $aliases)
45
  {
76
  *
77
  * @return string The inner key.
78
  */
79
+ protected function getInnerKey(string $key): string
80
  {
81
  if (array_key_exists($key, $this->aliases)) {
82
  return $this->aliases[$key];
vendor/dhii/containers/src/CachingContainer.php CHANGED
@@ -1,4 +1,6 @@
1
- <?php declare(strict_types=1);
 
 
2
 
3
  namespace Dhii\Container;
4
 
@@ -19,13 +21,10 @@ class CachingContainer implements ContainerInterface
19
  {
20
  use StringTranslatingTrait;
21
 
22
- /**
23
- * @var array
24
- */
25
  protected $cache;
26
- /**
27
- * @var PsrContainerInterface
28
- */
29
  protected $container;
30
 
31
  /**
@@ -42,18 +41,27 @@ class CachingContainer implements ContainerInterface
42
  */
43
  public function get($key)
44
  {
 
 
 
 
45
  $key = (string) $key;
46
 
 
 
 
 
 
47
  try {
48
- $value = $this->_getCached($key, function () use ($key) {
 
 
 
 
49
  return $this->container->get($key);
50
  });
51
  } catch (NotFoundExceptionInterface $e) {
52
- throw new NotFoundException(
53
- $this->__('Key "%1$s" not found in inner container', [$key]),
54
- 0,
55
- $e
56
- );
57
  } catch (Exception $e) {
58
  throw new ContainerException(
59
  $this->__('Could not retrieve value for key "%1$s from inner container', [$key]),
@@ -70,18 +78,22 @@ class CachingContainer implements ContainerInterface
70
  */
71
  public function has($key)
72
  {
 
 
 
73
  $key = (string) $key;
74
 
 
 
 
 
 
75
  try {
76
- if ($this->_hasCached($key)) {
77
  return true;
78
  }
79
  } catch (Exception $e) {
80
- throw new ContainerException(
81
- $this->__('Could not check cache for key "%1$s"', [$key]),
82
- 0,
83
- $e
84
- );
85
  }
86
 
87
  try {
@@ -108,11 +120,12 @@ class CachingContainer implements ContainerInterface
108
  * @return mixed The cached value.
109
  *
110
  * @throws Exception If problem caching.
 
111
  */
112
- protected function _getCached(string $key, callable $generator)
113
  {
114
  if (!array_key_exists($key, $this->cache)) {
115
- $value = $this->_invokeGenerator($generator);
116
  $this->cache[$key] = $value;
117
  }
118
 
@@ -128,7 +141,7 @@ class CachingContainer implements ContainerInterface
128
  *
129
  * @throws Exception If problem checking.
130
  */
131
- protected function _hasCached(string $key)
132
  {
133
  return array_key_exists($key, $this->cache);
134
  }
@@ -141,11 +154,11 @@ class CachingContainer implements ContainerInterface
141
  * @return mixed The generated result.
142
  *
143
  * @throws Exception If problem generating.
 
144
  */
145
- protected function _invokeGenerator(callable $generator)
146
  {
147
  $result = $generator();
148
-
149
  return $result;
150
  }
151
  }
1
+ <?php
2
+
3
+ declare(strict_types=1);
4
 
5
  namespace Dhii\Container;
6
 
21
  {
22
  use StringTranslatingTrait;
23
 
24
+ /** @var array<array-key, mixed> */
 
 
25
  protected $cache;
26
+
27
+ /** @var PsrContainerInterface */
 
28
  protected $container;
29
 
30
  /**
41
  */
42
  public function get($key)
43
  {
44
+ /** @psalm-suppress RedundantCastGivenDocblockType
45
+ * @psalm-suppress RedundantCast
46
+ * Will remove when switching to PHP 7.2 and new PSR-11 interfaces
47
+ */
48
  $key = (string) $key;
49
 
50
+ /**
51
+ * @psalm-suppress InvalidCatch
52
+ * The base interface does not extend Throwable, but in fact everything that is possible
53
+ * in theory to catch will be Throwable, and PSR-11 exceptions will implement this interface
54
+ */
55
  try {
56
+ /**
57
+ * @psalm-suppress MissingClosureReturnType
58
+ * Unable to specify mixed before PHP 8.
59
+ */
60
+ $value = $this->getCached($key, function () use ($key) {
61
  return $this->container->get($key);
62
  });
63
  } catch (NotFoundExceptionInterface $e) {
64
+ throw new NotFoundException($this->__('Key "%1$s" not found in inner container', [$key]), 0, $e);
 
 
 
 
65
  } catch (Exception $e) {
66
  throw new ContainerException(
67
  $this->__('Could not retrieve value for key "%1$s from inner container', [$key]),
78
  */
79
  public function has($key)
80
  {
81
+ /** @psalm-suppress RedundantCastGivenDocblockType
82
+ * Will remove when switching to PHP 7.2 and new PSR-11 interfaces
83
+ */
84
  $key = (string) $key;
85
 
86
+ /**
87
+ * @psalm-suppress InvalidCatch
88
+ * The base interface does not extend Throwable, but in fact everything that is possible
89
+ * in theory to catch will be Throwable, and PSR-11 exceptions will implement this interface
90
+ */
91
  try {
92
+ if ($this->hasCached($key)) {
93
  return true;
94
  }
95
  } catch (Exception $e) {
96
+ throw new ContainerException($this->__('Could not check cache for key "%1$s"', [$key]), 0, $e);
 
 
 
 
97
  }
98
 
99
  try {
120
  * @return mixed The cached value.
121
  *
122
  * @throws Exception If problem caching.
123
+ * @phpcsSuppress SlevomatCodingStandard.TypeHints.ReturnTypeHint.MissingNativeTypeHint
124
  */
125
+ protected function getCached(string $key, callable $generator)
126
  {
127
  if (!array_key_exists($key, $this->cache)) {
128
+ $value = $this->invokeGenerator($generator);
129
  $this->cache[$key] = $value;
130
  }
131
 
141
  *
142
  * @throws Exception If problem checking.
143
  */
144
+ protected function hasCached(string $key): bool
145
  {
146
  return array_key_exists($key, $this->cache);
147
  }
154
  * @return mixed The generated result.
155
  *
156
  * @throws Exception If problem generating.
157
+ * @phpcsSuppress SlevomatCodingStandard.TypeHints.ReturnTypeHint.MissingNativeTypeHint
158
  */
159
+ protected function invokeGenerator(callable $generator)
160
  {
161
  $result = $generator();
 
162
  return $result;
163
  }
164
  }
vendor/dhii/containers/src/CompositeCachingServiceProvider.php CHANGED
@@ -1,5 +1,7 @@
1
  <?php
2
 
 
 
3
  namespace Dhii\Container;
4
 
5
  use Interop\Container\ServiceProviderInterface;
@@ -11,49 +13,63 @@ use Psr\Container\ContainerInterface as PsrContainerInterface;
11
  class CompositeCachingServiceProvider implements ServiceProviderInterface
12
  {
13
  /**
14
- * @var iterable|callable[]
15
  */
16
  protected $providers;
17
 
18
  /**
19
- * @var iterable|callable[]
20
  */
21
  protected $factories;
22
 
23
  /**
24
- * @var iterable|callable[]
25
  */
26
  protected $extensions;
27
 
28
  /**
29
- * @param iterable|ServiceProviderInterface[] $providers
30
  */
31
- public function __construct($providers)
32
  {
33
  $this->providers = $providers;
 
 
34
  }
35
 
36
  /**
37
  * {@inheritDoc}
 
 
38
  */
39
  public function getFactories()
40
  {
41
  if (!is_array($this->factories)) {
42
- $this->_indexProviderDefinitions($this->providers);
43
  }
44
 
 
 
 
 
45
  return $this->factories;
46
  }
47
 
48
  /**
49
  * {@inheritDoc}
 
 
50
  */
51
  public function getExtensions()
52
  {
53
  if (!is_array($this->extensions)) {
54
- $this->_indexProviderDefinitions($this->providers);
55
  }
56
 
 
 
 
 
57
  return $this->extensions;
58
  }
59
 
@@ -64,14 +80,14 @@ class CompositeCachingServiceProvider implements ServiceProviderInterface
64
  *
65
  * @param iterable|ServiceProviderInterface[] $providers The providers to index.
66
  */
67
- protected function _indexProviderDefinitions($providers)
68
  {
69
  $factories = [];
70
  $extensions = [];
71
 
72
  foreach ($providers as $provider) {
73
- $factories = $this->_mergeFactories($factories, $provider->getFactories());
74
- $extensions = $this->_mergeExtensions($extensions, $provider->getExtensions());
75
  }
76
 
77
  $this->factories = $factories;
@@ -86,7 +102,7 @@ class CompositeCachingServiceProvider implements ServiceProviderInterface
86
  *
87
  * @return callable[] The merged factories.
88
  */
89
- protected function _mergeFactories(array $defaults, array $definitions): array
90
  {
91
  return array_merge($defaults, $definitions);
92
  }
@@ -95,22 +111,23 @@ class CompositeCachingServiceProvider implements ServiceProviderInterface
95
  * Merged service extensions.
96
  *
97
  * @param callable[] $defaults
98
- * @param callable[] $extensions
99
  *
100
  * @return callable[] The merged extensions.
101
  */
102
- protected function _mergeExtensions(array $defaults, array $extensions): array
103
  {
104
  $merged = [];
105
 
106
  foreach ($extensions as $key => $extension) {
107
- assert(is_callable($extension));
108
-
109
  if (isset($defaults[$key])) {
110
  $default = $defaults[$key];
 
 
 
 
 
111
  $merged[$key] = function (PsrContainerInterface $c, $previous = null) use ($default, $extension) {
112
- assert(is_callable($default));
113
-
114
  $result = $default($c, $previous);
115
  $result = $extension($c, $result);
116
 
@@ -123,7 +140,7 @@ class CompositeCachingServiceProvider implements ServiceProviderInterface
123
  }
124
  }
125
 
126
- $merged = $this->_mergeFactories($defaults, $merged);
127
 
128
  return $merged;
129
  }
1
  <?php
2
 
3
+ declare(strict_types=1);
4
+
5
  namespace Dhii\Container;
6
 
7
  use Interop\Container\ServiceProviderInterface;
13
  class CompositeCachingServiceProvider implements ServiceProviderInterface
14
  {
15
  /**
16
+ * @var iterable<ServiceProviderInterface>
17
  */
18
  protected $providers;
19
 
20
  /**
21
+ * @var ?iterable<callable>
22
  */
23
  protected $factories;
24
 
25
  /**
26
+ * @var ?iterable<callable>
27
  */
28
  protected $extensions;
29
 
30
  /**
31
+ * @param iterable<ServiceProviderInterface> $providers
32
  */
33
+ public function __construct(iterable $providers)
34
  {
35
  $this->providers = $providers;
36
+ $this->factories = null;
37
+ $this->extensions = null;
38
  }
39
 
40
  /**
41
  * {@inheritDoc}
42
+ * @psalm-suppress InvalidNullableReturnType
43
+ * It isn't actually going to return null ever, because $factories will be filled during indexing.
44
  */
45
  public function getFactories()
46
  {
47
  if (!is_array($this->factories)) {
48
+ $this->indexProviderDefinitions($this->providers);
49
  }
50
 
51
+ /**
52
+ * @psalm-suppress NullableReturnStatement
53
+ * Not going to be null because will be populated by indexing
54
+ */
55
  return $this->factories;
56
  }
57
 
58
  /**
59
  * {@inheritDoc}
60
+ * @psalm-suppress InvalidNullableReturnType
61
+ * It isn't actually going to return null ever, because $factories will be filled during indexing.
62
  */
63
  public function getExtensions()
64
  {
65
  if (!is_array($this->extensions)) {
66
+ $this->indexProviderDefinitions($this->providers);
67
  }
68
 
69
+ /**
70
+ * @psalm-suppress NullableReturnStatement
71
+ * Not going to be null because will be populated by indexing
72
+ */
73
  return $this->extensions;
74
  }
75
 
80
  *
81
  * @param iterable|ServiceProviderInterface[] $providers The providers to index.
82
  */
83
+ protected function indexProviderDefinitions(iterable $providers): void
84
  {
85
  $factories = [];
86
  $extensions = [];
87
 
88
  foreach ($providers as $provider) {
89
+ $factories = $this->mergeFactories($factories, $provider->getFactories());
90
+ $extensions = $this->mergeExtensions($extensions, $provider->getExtensions());
91
  }
92
 
93
  $this->factories = $factories;
102
  *
103
  * @return callable[] The merged factories.
104
  */
105
+ protected function mergeFactories(array $defaults, array $definitions): array
106
  {
107
  return array_merge($defaults, $definitions);
108
  }
111
  * Merged service extensions.
112
  *
113
  * @param callable[] $defaults
114
+ * @param iterable<callable> $extensions
115
  *
116
  * @return callable[] The merged extensions.
117
  */
118
+ protected function mergeExtensions(array $defaults, iterable $extensions): array
119
  {
120
  $merged = [];
121
 
122
  foreach ($extensions as $key => $extension) {
 
 
123
  if (isset($defaults[$key])) {
124
  $default = $defaults[$key];
125
+ /**
126
+ * @psalm-suppress MissingClosureReturnType
127
+ * @psalm-suppress MissingClosureParamType
128
+ * Unable to specify mixed before PHP 8.
129
+ */
130
  $merged[$key] = function (PsrContainerInterface $c, $previous = null) use ($default, $extension) {
 
 
131
  $result = $default($c, $previous);
132
  $result = $extension($c, $result);
133
 
140
  }
141
  }
142
 
143
+ $merged = $this->mergeFactories($defaults, $merged);
144
 
145
  return $merged;
146
  }
vendor/dhii/containers/src/CompositeContainer.php CHANGED
@@ -1,5 +1,7 @@
1
  <?php
2
 
 
 
3
  namespace Dhii\Container;
4
 
5
  use Dhii\Collection\ContainerInterface;
@@ -17,20 +19,15 @@ class CompositeContainer implements ContainerInterface
17
  use StringTranslatingTrait;
18
 
19
  /**
20
- * @var array|PsrContainerInterface[]|Traversable
21
  */
22
  protected $containers;
23
 
24
  /**
25
- * @param PsrContainerInterface[]|Traversable $containers The list of containers.
26
  */
27
- public function __construct($containers)
28
  {
29
- if (!is_array($containers) && !($containers instanceof Traversable)) {
30
- throw new UnexpectedValueException(
31
- $this->__('The containers argument is not a valid list')
32
- );
33
- }
34
  $this->containers = $containers;
35
  }
36
 
@@ -39,9 +36,18 @@ class CompositeContainer implements ContainerInterface
39
  */
40
  public function get($key)
41
  {
 
 
 
 
42
  $key = (string) $key;
43
 
44
  foreach ($this->containers as $index => $container) {
 
 
 
 
 
45
  try {
46
  if ($container->has($key)) {
47
  return $container->get($key);
@@ -73,6 +79,9 @@ class CompositeContainer implements ContainerInterface
73
  */
74
  public function has($key)
75
  {
 
 
 
76
  $key = (string) $key;
77
 
78
  foreach ($this->containers as $index => $container) {
1
  <?php
2
 
3
+ declare(strict_types=1);
4
+
5
  namespace Dhii\Container;
6
 
7
  use Dhii\Collection\ContainerInterface;
19
  use StringTranslatingTrait;
20
 
21
  /**
22
+ * @var iterable<PsrContainerInterface>
23
  */
24
  protected $containers;
25
 
26
  /**
27
+ * @param iterable<PsrContainerInterface> $containers The list of containers.
28
  */
29
+ public function __construct(iterable $containers)
30
  {
 
 
 
 
 
31
  $this->containers = $containers;
32
  }
33
 
36
  */
37
  public function get($key)
38
  {
39
+ /** @psalm-suppress RedundantCastGivenDocblockType
40
+ * @psalm-suppress RedundantCast
41
+ * Will remove when switching to PHP 7.2 and new PSR-11 interfaces
42
+ */
43
  $key = (string) $key;
44
 
45
  foreach ($this->containers as $index => $container) {
46
+ /**
47
+ * @psalm-suppress InvalidCatch
48
+ * The base interface does not extend Throwable, but in fact everything that is possible
49
+ * in theory to catch will be Throwable, and PSR-11 exceptions will implement this interface
50
+ */
51
  try {
52
  if ($container->has($key)) {
53
  return $container->get($key);
79
  */
80
  public function has($key)
81
  {
82
+ /** @psalm-suppress RedundantCastGivenDocblockType
83
+ * Will remove when switching to PHP 7.2 and new PSR-11 interfaces
84
+ */
85
  $key = (string) $key;
86
 
87
  foreach ($this->containers as $index => $container) {
vendor/dhii/containers/src/DataStructureBasedFactory.php CHANGED
@@ -1,4 +1,5 @@
1
  <?php
 
2
  declare(strict_types=1);
3
 
4
  namespace Dhii\Container;
@@ -15,10 +16,8 @@ class DataStructureBasedFactory implements DataStructureBasedFactoryInterface
15
  * @var WritableMapFactoryInterface
16
  */
17
  protected $containerFactory;
18
-
19
- public function __construct(
20
- WritableMapFactoryInterface $containerFactory
21
- ) {
22
  $this->containerFactory = $containerFactory;
23
  }
24
 
@@ -29,7 +28,11 @@ class DataStructureBasedFactory implements DataStructureBasedFactoryInterface
29
  {
30
  $map = [];
31
  foreach ($structure as $key => $value) {
32
- if (is_array($value) || is_object($value)) {
 
 
 
 
33
  $value = $this->createContainerFromArray($value);
34
  }
35
 
@@ -37,7 +40,6 @@ class DataStructureBasedFactory implements DataStructureBasedFactoryInterface
37
  }
38
 
39
  $container = $this->containerFactory->createContainerFromArray($map);
40
-
41
  return $container;
42
  }
43
- }
1
  <?php
2
+
3
  declare(strict_types=1);
4
 
5
  namespace Dhii\Container;
16
  * @var WritableMapFactoryInterface
17
  */
18
  protected $containerFactory;
19
+ public function __construct(WritableMapFactoryInterface $containerFactory)
20
+ {
 
 
21
  $this->containerFactory = $containerFactory;
22
  }
23
 
28
  {
29
  $map = [];
30
  foreach ($structure as $key => $value) {
31
+ if (is_object($value)) {
32
+ $value = get_object_vars($value);
33
+ }
34
+
35
+ if (is_array($value)) {
36
  $value = $this->createContainerFromArray($value);
37
  }
38
 
40
  }
41
 
42
  $container = $this->containerFactory->createContainerFromArray($map);
 
43
  return $container;
44
  }
45
+ }
vendor/dhii/containers/src/DataStructureBasedFactoryInterface.php CHANGED
@@ -1,4 +1,5 @@
1
  <?php
 
2
  declare(strict_types=1);
3
 
4
  namespace Dhii\Container;
@@ -16,11 +17,11 @@ interface DataStructureBasedFactoryInterface extends WritableMapFactoryInterface
16
  /**
17
  * Based on a traditional data structure, creates a container hierarchy.
18
  *
19
- * @param array $structure The traditional data structure representation.
20
  *
21
  * @return WritableMapInterface A hierarchy of writable maps that reflects the data structure.
22
  *
23
  * @throws Exception If problem creating.
24
  */
25
  public function createContainerFromArray(array $structure): BaseContainerInterface;
26
- }
1
  <?php
2
+
3
  declare(strict_types=1);
4
 
5
  namespace Dhii\Container;
17
  /**
18
  * Based on a traditional data structure, creates a container hierarchy.
19
  *
20
+ * @param mixed[] $structure The traditional data structure representation.
21
  *
22
  * @return WritableMapInterface A hierarchy of writable maps that reflects the data structure.
23
  *
24
  * @throws Exception If problem creating.
25
  */
26
  public function createContainerFromArray(array $structure): BaseContainerInterface;
27
+ }
vendor/dhii/containers/src/DelegatingContainer.php CHANGED
@@ -1,5 +1,7 @@
1
  <?php
2
 
 
 
3
  namespace Dhii\Container;
4
 
5
  use Dhii\Collection\ContainerInterface;
@@ -25,8 +27,6 @@ class DelegatingContainer implements ContainerInterface
25
  protected $parent;
26
 
27
  /**
28
- * @param ServiceProviderInterface $provider
29
- * @param PsrContainerInterface|null $parent
30
  */
31
  public function __construct(ServiceProviderInterface $provider, PsrContainerInterface $parent = null)
32
  {
@@ -53,7 +53,7 @@ class DelegatingContainer implements ContainerInterface
53
  $service = $services[$id];
54
 
55
  try {
56
- $service = $this->_invokeFactory($service);
57
  } catch (UnexpectedValueException $e) {
58
  throw new ContainerException(
59
  $this->__('Could not create service "%1$s"', [$id]),
@@ -71,7 +71,7 @@ class DelegatingContainer implements ContainerInterface
71
  $extension = $extensions[$id];
72
 
73
  try {
74
- $service = $this->_invokeExtension($extension, $service);
75
  } catch (UnexpectedValueException $e) {
76
  throw new ContainerException(
77
  $this->__('Could not extend service "%1$s"', [$id]),
@@ -101,8 +101,9 @@ class DelegatingContainer implements ContainerInterface
101
  * @return mixed The service created by the factory.
102
  *
103
  * @throws UnexpectedValueException If factory could not be invoked.
 
104
  */
105
- protected function _invokeFactory(callable $factory)
106
  {
107
  if (!is_callable($factory)) {
108
  throw new UnexpectedValueException(
@@ -112,7 +113,7 @@ class DelegatingContainer implements ContainerInterface
112
  );
113
  }
114
 
115
- $baseContainer = $this->_getBaseContainer();
116
  $service = $factory($baseContainer);
117
 
118
  return $service;
@@ -127,8 +128,9 @@ class DelegatingContainer implements ContainerInterface
127
  * @return mixed The extended service.
128
  *
129
  * @throws UnexpectedValueException If extension cannot be invoked.
 
130
  */
131
- protected function _invokeExtension(callable $extension, $service)
132
  {
133
  if (!is_callable($extension)) {
134
  throw new UnexpectedValueException(
@@ -138,7 +140,7 @@ class DelegatingContainer implements ContainerInterface
138
  );
139
  }
140
 
141
- $baseContainer = $this->_getBaseContainer();
142
  $service = $extension($baseContainer, $service);
143
 
144
  return $service;
@@ -149,7 +151,7 @@ class DelegatingContainer implements ContainerInterface
149
  *
150
  * @return PsrContainerInterface The parent container, if set. Otherwise, this instance.
151
  */
152
- protected function _getBaseContainer() : PsrContainerInterface
153
  {
154
  return $this->parent instanceof PsrContainerInterface
155
  ? $this->parent
1
  <?php
2
 
3
+ declare(strict_types=1);
4
+
5
  namespace Dhii\Container;
6
 
7
  use Dhii\Collection\ContainerInterface;
27
  protected $parent;
28
 
29
  /**
 
 
30
  */
31
  public function __construct(ServiceProviderInterface $provider, PsrContainerInterface $parent = null)
32
  {
53
  $service = $services[$id];
54
 
55
  try {
56
+ $service = $this->invokeFactory($service);
57
  } catch (UnexpectedValueException $e) {
58
  throw new ContainerException(
59
  $this->__('Could not create service "%1$s"', [$id]),
71
  $extension = $extensions[$id];
72
 
73
  try {
74
+ $service = $this->invokeExtension($extension, $service);
75
  } catch (UnexpectedValueException $e) {
76
  throw new ContainerException(
77
  $this->__('Could not extend service "%1$s"', [$id]),
101
  * @return mixed The service created by the factory.
102
  *
103
  * @throws UnexpectedValueException If factory could not be invoked.
104
+ * @phpcsSuppress SlevomatCodingStandard.TypeHints.ReturnTypeHint.MissingNativeTypeHint
105
  */
106
+ protected function invokeFactory(callable $factory)
107
  {
108
  if (!is_callable($factory)) {
109
  throw new UnexpectedValueException(
113
  );
114
  }
115
 
116
+ $baseContainer = $this->getBaseContainer();
117
  $service = $factory($baseContainer);
118
 
119
  return $service;
128
  * @return mixed The extended service.
129
  *
130
  * @throws UnexpectedValueException If extension cannot be invoked.
131
+ * @phpcsSuppress SlevomatCodingStandard.TypeHints.ReturnTypeHint.MissingNativeTypeHint
132
  */
133
+ protected function invokeExtension(callable $extension, $service)
134
  {
135
  if (!is_callable($extension)) {
136
  throw new UnexpectedValueException(
140
  );
141
  }
142
 
143
+ $baseContainer = $this->getBaseContainer();
144
  $service = $extension($baseContainer, $service);
145
 
146
  return $service;
151
  *
152
  * @return PsrContainerInterface The parent container, if set. Otherwise, this instance.
153
  */
154
+ protected function getBaseContainer(): PsrContainerInterface
155
  {
156
  return $this->parent instanceof PsrContainerInterface
157
  ? $this->parent
vendor/dhii/containers/src/DeprefixingContainer.php CHANGED
@@ -1,5 +1,7 @@
1
  <?php
2
 
 
 
3
  namespace Dhii\Container;
4
 
5
  use Dhii\Collection\ContainerInterface;
@@ -59,6 +61,11 @@ class DeprefixingContainer implements ContainerInterface
59
  */
60
  public function get($key)
61
  {
 
 
 
 
 
62
  try {
63
  return $this->inner->get($this->getInnerKey($key));
64
  } catch (NotFoundExceptionInterface $nfException) {
@@ -89,7 +96,7 @@ class DeprefixingContainer implements ContainerInterface
89
  *
90
  * @return string The inner key.
91
  */
92
- protected function getInnerKey($key)
93
  {
94
  return $this->prefix . $key;
95
  }
1
  <?php
2
 
3
+ declare(strict_types=1);
4
+
5
  namespace Dhii\Container;
6
 
7
  use Dhii\Collection\ContainerInterface;
61
  */
62
  public function get($key)
63
  {
64
+ /**
65
+ * @psalm-suppress InvalidCatch
66
+ * The base interface does not extend Throwable, but in fact everything that is possible
67
+ * in theory to catch will be Throwable, and PSR-11 exceptions will implement this interface
68
+ */
69
  try {
70
  return $this->inner->get($this->getInnerKey($key));
71
  } catch (NotFoundExceptionInterface $nfException) {
96
  *
97
  * @return string The inner key.
98
  */
99
+ protected function getInnerKey(string $key): string
100
  {
101
  return $this->prefix . $key;
102
  }
vendor/dhii/containers/src/Dictionary.php CHANGED
@@ -1,5 +1,7 @@
1
  <?php
2
 
 
 
3
  namespace Dhii\Container;
4
 
5
  use ArrayIterator;
@@ -19,11 +21,11 @@ class Dictionary implements
19
  {
20
  use StringTranslatingTrait;
21
 
22
- /** @var array */
23
  protected $data;
24
 
25
  /**
26
- * @param array $data The key-value map of data.
27
  */
28
  public function __construct(array $data)
29
  {
@@ -66,40 +68,62 @@ class Dictionary implements
66
 
67
  /**
68
  * @inheritDoc
 
 
 
69
  */
70
  public function withMappings(array $mappings): WritableContainerInterface
71
  {
72
  $dictionary = $this->cloneMe();
73
  $dictionary->data = $mappings;
74
 
 
 
 
 
75
  return $dictionary;
76
  }
77
 
78
  /**
79
  * @inheritDoc
 
 
 
80
  */
81
  public function withAddedMappings(array $mappings): WritableContainerInterface
82
  {
83
  $dictionary = $this->cloneMe();
84
  $dictionary->data = $mappings + $this->data;
85
 
 
 
 
 
86
  return $dictionary;
87
  }
88
 
89
  /**
90
  * @inheritDoc
 
 
 
91
  */
92
  public function withoutKeys(array $keys): WritableContainerInterface
93
  {
94
  $dictionary = $this->cloneMe();
95
 
96
  foreach ($keys as $i => $key) {
 
97
  if (!is_string($key)) {
98
  throw new RangeException($this->__('Key at index %1$d is not a string', [$i]));
99
  }
100
  unset($dictionary->data[$key]);
101
  }
102
 
 
 
 
 
103
  return $dictionary;
104
  }
105
 
@@ -112,4 +136,4 @@ class Dictionary implements
112
  {
113
  return clone $this;
114
  }
115
- }
1
  <?php
2
 
3
+ declare(strict_types=1);
4
+
5
  namespace Dhii\Container;
6
 
7
  use ArrayIterator;
21
  {
22
  use StringTranslatingTrait;
23
 
24
+ /** @var array<array-key, mixed> */
25
  protected $data;
26
 
27
  /**
28
+ * @param array<array-key, mixed> $data The key-value map of data.
29
  */
30
  public function __construct(array $data)
31
  {
68
 
69
  /**
70
  * @inheritDoc
71
+ * @psalm-suppress MoreSpecificReturnType
72
+ * Psalm complains that the declared return type is more specific than inferred.
73
+ * This is not true, as it promises to return the interface.
74
  */
75
  public function withMappings(array $mappings): WritableContainerInterface
76
  {
77
  $dictionary = $this->cloneMe();
78
  $dictionary->data = $mappings;
79
 
80
+ /**
81
+ * @psalm-suppress LessSpecificReturnStatement
82
+ * Looks like this needs to be suppressed until able to hint return type `self`.
83
+ */
84
  return $dictionary;
85
  }
86
 
87
  /**
88
  * @inheritDoc
89
+ * @psalm-suppress MoreSpecificReturnType
90
+ * Psalm complains that the declared return type is more specific than inferred.
91
+ * This is not true, as it promises to return the interface.
92
  */
93
  public function withAddedMappings(array $mappings): WritableContainerInterface
94
  {
95
  $dictionary = $this->cloneMe();
96
  $dictionary->data = $mappings + $this->data;
97
 
98
+ /**
99
+ * @psalm-suppress LessSpecificReturnStatement
100
+ * Looks like this needs to be suppressed until able to hint return type `self`.
101
+ */
102
  return $dictionary;
103
  }
104
 
105
  /**
106
  * @inheritDoc
107
+ * @psalm-suppress MoreSpecificReturnType
108
+ * Psalm complains that the declared return type is more specific than inferred.
109
+ * This is not true, as it promises to return the interface.
110
  */
111
  public function withoutKeys(array $keys): WritableContainerInterface
112
  {
113
  $dictionary = $this->cloneMe();
114
 
115
  foreach ($keys as $i => $key) {
116
+ /** @psalm-suppress DocblockTypeContradiction Still want to enforce string */
117
  if (!is_string($key)) {
118
  throw new RangeException($this->__('Key at index %1$d is not a string', [$i]));
119
  }
120
  unset($dictionary->data[$key]);
121
  }
122
 
123
+ /**
124
+ * @psalm-suppress LessSpecificReturnStatement
125
+ * Looks like this needs to be suppressed until able to hint return type `self`.
126
+ */
127
  return $dictionary;
128
  }
129
 
136
  {
137
  return clone $this;
138
  }
139
+ }
vendor/dhii/containers/src/DictionaryFactory.php CHANGED
@@ -1,4 +1,5 @@
1
  <?php
 
2
  declare(strict_types=1);
3
 
4
  namespace Dhii\Container;
@@ -18,4 +19,4 @@ class DictionaryFactory implements WritableMapFactoryInterface
18
  {
19
  return new Dictionary($data);
20
  }
21
- }
1
  <?php
2
+
3
  declare(strict_types=1);
4
 
5
  namespace Dhii\Container;
19
  {
20
  return new Dictionary($data);
21
  }
22
+ }
vendor/dhii/containers/src/Exception/ContainerException.php CHANGED
@@ -1,4 +1,6 @@
1
- <?php declare(strict_types = 1);
 
 
2
 
3
  namespace Dhii\Container\Exception;
4
 
@@ -20,15 +22,12 @@ class ContainerException extends Exception implements ContainerExceptionInterfac
20
  protected $container;
21
 
22
  /**
23
- * @param string $message The exception message.
24
- * @param int $code The exception code.
25
  * @param Throwable|null $previous The inner exception, if any.
26
  */
27
- public function __construct(
28
- string $message = "",
29
- int $code = 0,
30
- Throwable $previous = null
31
- ) {
32
  parent::__construct($message, $code, $previous);
33
  }
34
  }
1
+ <?php
2
+
3
+ declare(strict_types=1);
4
 
5
  namespace Dhii\Container\Exception;
6
 
22
  protected $container;
23
 
24
  /**
25
+ * @param string $message The exception message.
26
+ * @param int $code The exception code.
27
  * @param Throwable|null $previous The inner exception, if any.
28
  */
29
+ public function __construct(string $message = "", int $code = 0, Throwable $previous = null)
30
+ {
 
 
 
31
  parent::__construct($message, $code, $previous);
32
  }
33
  }
vendor/dhii/containers/src/Exception/NotFoundException.php CHANGED
@@ -1,5 +1,7 @@
1
  <?php
2
 
 
 
3
  namespace Dhii\Container\Exception;
4
 
5
  use Psr\Container\NotFoundExceptionInterface;
@@ -8,13 +10,13 @@ use Throwable;
8
  class NotFoundException extends ContainerException implements NotFoundExceptionInterface
9
  {
10
  /**
11
- * @var string
 
 
12
  */
13
- protected $dataKey;
14
-
15
  public function __construct(
16
- $message = '',
17
- $code = 0,
18
  Throwable $previous = null
19
  ) {
20
  parent::__construct($message, $code, $previous);
1
  <?php
2
 
3
+ declare(strict_types=1);
4
+
5
  namespace Dhii\Container\Exception;
6
 
7
  use Psr\Container\NotFoundExceptionInterface;
10
  class NotFoundException extends ContainerException implements NotFoundExceptionInterface
11
  {
12
  /**
13
+ * @param string $message The error message.
14
+ * @param int $code The error code.
15
+ * @param Throwable|null $previous The inner error, if any.
16
  */
 
 
17
  public function __construct(
18
+ string $message = '',
19
+ int $code = 0,
20
  Throwable $previous = null
21
  ) {
22
  parent::__construct($message, $code, $previous);
vendor/dhii/containers/src/FlashContainer.php ADDED
@@ -0,0 +1,135 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ declare(strict_types=1);
4
+
5
+ namespace Dhii\Container;
6
+
7
+ use Dhii\Collection\ClearableContainerInterface;
8
+ use Dhii\Collection\MutableContainerInterface;
9
+ use Dhii\Container\Exception\NotFoundException;
10
+ use Psr\Container\ContainerExceptionInterface;
11
+
12
+ /**
13
+ * A container for data that is accessible once per init.
14
+ *
15
+ * The {@see init()} method copies data from the internal container into memory,
16
+ * then clears it. The data is still accessible from memory,
17
+ * but no longer from internal container.
18
+ *
19
+ * This is useful for flash data, i.e. data that should only be accessible
20
+ * once per request. If a session-specific persistent container is used
21
+ * as storage, this will become session-based flash data.
22
+ */
23
+ class FlashContainer implements
24
+ MutableContainerInterface,
25
+ ClearableContainerInterface
26
+ {
27
+ /** @var MutableContainerInterface */
28
+ protected $data;
29
+ /** @var string */
30
+ protected $dataKey;
31
+ /** @var array<array-key, scalar> */
32
+ protected $flashData = [];
33
+
34
+ /**
35
+ * @param MutableContainerInterface $data The storage.
36
+ * @param string $dataKey The key to be used to store data in the storage.
37
+ */
38
+ public function __construct(MutableContainerInterface $data, string $dataKey)
39
+ {
40
+ $this->data = $data;
41
+ $this->dataKey = $dataKey;
42
+ }
43
+
44
+ /**
45
+ * Prepare storage before use.
46
+ *
47
+ * Should be called once before accessing data through this class.
48
+ * Will clear the data for the configured key from the storage.
49
+ */
50
+ public function init(): void
51
+ {
52
+ $this->flashData = $this->data->has($this->dataKey)
53
+ ? $this->data->get($this->dataKey)
54
+ : [];
55
+
56
+ $this->purgePersistentData();
57
+ }
58
+
59
+ /**
60
+ * @inheritDoc
61
+ */
62
+ public function has($key)
63
+ {
64
+ return array_key_exists($key, $this->flashData);
65
+ }
66
+
67
+ /**
68
+ * @inheritDoc
69
+ *
70
+ * Retrieves the value for the specified key from memory.
71
+ */
72
+ public function get($key)
73
+ {
74
+ if (!array_key_exists($key, $this->flashData)) {
75
+ throw new NotFoundException(sprintf('Flash data not found for key "%1$s"', $key));
76
+ }
77
+
78
+ return $this->flashData[$key];
79
+ }
80
+
81
+ /**
82
+ * @inheritDoc
83
+ *
84
+ * Assigns the given value to the specified key in memory, and persists this change in storage.
85
+ */
86
+ public function set(string $key, $value): void
87
+ {
88
+ $this->flashData[$key] = $value;
89
+ $this->persist($this->flashData);
90
+ }
91
+
92
+ /**
93
+ * @inheritDoc
94
+ *
95
+ * Removes the specified key from memory, and persists this change in storage.
96
+ */
97
+ public function unset(string $key): void
98
+ {
99
+ if (!array_key_exists($key, $this->flashData)) {
100
+ throw new NotFoundException(sprintf('Flash data not found for key "%1$s"', $key));
101
+ }
102
+
103
+ unset($this->flashData[$key]);
104
+ $this->persist($this->flashData);
105
+ }
106
+
107
+ /**
108
+ * @inheritDoc
109
+ *
110
+ * Clears all of this instance's data from memory.
111
+ */
112
+ public function clear(): void
113
+ {
114
+ $this->flashData = [];
115
+ $this->persist($this->flashData);
116
+ }
117
+
118
+ /**
119
+ * Clear data from internal storage.
120
+ */
121
+ protected function purgePersistentData(): void
122
+ {
123
+ $this->data->set($this->dataKey, []);
124
+ }
125
+
126
+ /**
127
+ * Persist this instance's data from memory into storage.
128
+ *
129
+ * @param array<array-key, scalar> $data The data to persist.
130
+ */
131
+ protected function persist(array $data): void
132
+ {
133
+ $this->data->set($this->dataKey, $data);
134
+ }
135
+ }
vendor/dhii/containers/src/HierarchyContainer.php CHANGED
@@ -1,5 +1,7 @@
1
  <?php
2
 
 
 
3
  namespace Dhii\Container;
4
 
5
  use Dhii\Collection\ContainerInterface;
@@ -39,7 +41,7 @@ class HierarchyContainer implements ContainerInterface
39
  /**
40
  * @since [*next-version*]
41
  *
42
- * @var array
43
  */
44
  protected $data;
45
 
@@ -48,7 +50,7 @@ class HierarchyContainer implements ContainerInterface
48
  *
49
  * @since [*next-version*]
50
  *
51
- * @param array $data The hierarchical data for which to create the container tree.
52
  */
53
  public function __construct(array $data)
54
  {
@@ -63,13 +65,17 @@ class HierarchyContainer implements ContainerInterface
63
  public function get($key)
64
  {
65
  if (!array_key_exists($key, $this->data)) {
66
- throw new NotFoundException("Key '{$key}' does not exist", 0, null, $this, $key);
67
  }
68
 
69
  $value = $this->data[$key];
70
 
71
- if (is_array($value) || $value instanceof stdClass) {
72
- $value = $this->data[$key] = new HierarchyContainer($value);
 
 
 
 
73
  }
74
 
75
  return $value;
1
  <?php
2
 
3
+ declare(strict_types=1);
4
+
5
  namespace Dhii\Container;
6
 
7
  use Dhii\Collection\ContainerInterface;
41
  /**
42
  * @since [*next-version*]
43
  *
44
+ * @var mixed[]
45
  */
46
  protected $data;
47
 
50
  *
51
  * @since [*next-version*]
52
  *
53
+ * @param mixed[] $data The hierarchical data for which to create the container tree.
54
  */
55
  public function __construct(array $data)
56
  {
65
  public function get($key)
66
  {
67
  if (!array_key_exists($key, $this->data)) {
68
+ throw new NotFoundException("Key '{$key}' does not exist", 0, null);
69
  }
70
 
71
  $value = $this->data[$key];
72
 
73
+ if ($value instanceof stdClass) {
74
+ $value = get_object_vars($value);
75
+ }
76
+
77
+ if (is_array($value)) {
78
+ $value = $this->data[$key] = new self($value);
79
  }
80
 
81
  return $value;
vendor/dhii/containers/src/MappingContainer.php CHANGED
@@ -1,5 +1,7 @@
1
  <?php
2
 
 
 
3
  namespace Dhii\Container;
4
 
5
  use Dhii\Collection\ContainerInterface;
@@ -54,11 +56,11 @@ class MappingContainer implements ContainerInterface
54
  *
55
  * @since [*next-version*]
56
  *
57
- * @param PsrContainerInterface|null $inner The container instance to decorate.
58
- * @param callable $callback The callback to invoke on get. It will be passed 3 parameters:
59
- * * The inner container's value for the key being fetched.
60
- * * The key being fetched.
61
- * * A reference to this container instance.
62
  */
63
  public function __construct(PsrContainerInterface $inner, callable $callback)
64
  {
1
  <?php
2
 
3
+ declare(strict_types=1);
4
+
5
  namespace Dhii\Container;
6
 
7
  use Dhii\Collection\ContainerInterface;
56
  *
57
  * @since [*next-version*]
58
  *
59
+ * @param PsrContainerInterface $inner The container instance to decorate.
60
+ * @param callable $callback The callback to invoke on get. It will be passed 3 parameters:
61
+ * * The inner container's value for the key being fetched.
62
+ * * The key being fetched.
63
+ * * A reference to this container instance.
64
  */
65
  public function __construct(PsrContainerInterface $inner, callable $callback)
66
  {
vendor/dhii/containers/src/MaskingContainer.php CHANGED
@@ -1,11 +1,14 @@
1
  <?php
2
 
 
 
3
  namespace Dhii\Container;
4
 
5
  use Dhii\Collection\ContainerInterface;
6
  use Dhii\Container\Exception\NotFoundException;
7
  use Dhii\Container\Util\StringTranslatingTrait;
8
  use Psr\Container\ContainerInterface as PsrContainerInterface;
 
9
  use function array_key_exists;
10
 
11
  /**
@@ -45,7 +48,7 @@ class MaskingContainer implements ContainerInterface
45
  * @param bool[] $mask A mapping of keys to booleans, such that `true` exposes the mapped key
46
  * and `false` hides the mapped key.
47
  */
48
- public function __construct(PsrContainerInterface $inner, $defaultMask, array $mask)
49
  {
50
  $this->inner = $inner;
51
  $this->defMask = $defaultMask;
@@ -63,9 +66,7 @@ class MaskingContainer implements ContainerInterface
63
  throw new NotFoundException(
64
  $this->__('Inner key "%1$s" is not exposed', [$key]),
65
  0,
66
- null,
67
- $this,
68
- $key
69
  );
70
  }
71
 
@@ -91,7 +92,7 @@ class MaskingContainer implements ContainerInterface
91
  *
92
  * @return bool True if the key is exposed, false if the key is hidden.
93
  */
94
- protected function isExposed($key)
95
  {
96
  return array_key_exists($key, $this->mask)
97
  ? $this->mask[$key] !== false
1
  <?php
2
 
3
+ declare(strict_types=1);
4
+
5
  namespace Dhii\Container;
6
 
7
  use Dhii\Collection\ContainerInterface;
8
  use Dhii\Container\Exception\NotFoundException;
9
  use Dhii\Container\Util\StringTranslatingTrait;
10
  use Psr\Container\ContainerInterface as PsrContainerInterface;
11
+
12
  use function array_key_exists;
13
 
14
  /**
48
  * @param bool[] $mask A mapping of keys to booleans, such that `true` exposes the mapped key
49
  * and `false` hides the mapped key.
50
  */
51
+ public function __construct(PsrContainerInterface $inner, bool $defaultMask, array $mask)
52
  {
53
  $this->inner = $inner;
54
  $this->defMask = $defaultMask;
66
  throw new NotFoundException(
67
  $this->__('Inner key "%1$s" is not exposed', [$key]),
68
  0,
69
+ null
 
 
70
  );
71
  }
72
 
92
  *
93
  * @return bool True if the key is exposed, false if the key is hidden.
94
  */
95
+ protected function isExposed(string $key): bool
96
  {
97
  return array_key_exists($key, $this->mask)
98
  ? $this->mask[$key] !== false
vendor/dhii/containers/src/NoOpContainer.php ADDED
@@ -0,0 +1,99 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ declare(strict_types=1);
4
+
5
+ namespace Dhii\Container;
6
+
7
+ use ArrayIterator;
8
+ use Dhii\Collection\ClearableContainerInterface;
9
+ use Dhii\Collection\MutableContainerInterface;
10
+ use Dhii\Collection\WritableContainerInterface;
11
+ use Dhii\Collection\WritableMapInterface;
12
+ use Dhii\Container\Exception\ContainerException;
13
+ use Dhii\Container\Exception\NotFoundException;
14
+ use IteratorAggregate;
15
+
16
+ /**
17
+ * A container that does nothing.
18
+ *
19
+ * This can be used if an actual implementation is not available,
20
+ * without extra checks or nullables - just as if it was a real one.
21
+ */
22
+ class NoOpContainer implements
23
+ MutableContainerInterface,
24
+ IteratorAggregate,
25
+ WritableMapInterface,
26
+ ClearableContainerInterface
27
+ {
28
+ /**
29
+ * @inheritDoc
30
+ */
31
+ public function get($id)
32
+ {
33
+ throw new NotFoundException('NoOp container cannot have values');
34
+ }
35
+
36
+ /**
37
+ * @inheritDoc
38
+ */
39
+ public function has($id)
40
+ {
41
+ return false;
42
+ }
43
+
44
+ /**
45
+ * @inheritDoc
46
+ */
47
+ public function set(string $key, $value): void
48
+ {
49
+ // Do nothing
50
+ }
51
+
52
+ /**
53
+ * @inheritDoc
54
+ */
55
+ public function unset(string $key): void
56
+ {
57
+ throw new ContainerException('NoOp container cannot have values');
58
+ }
59
+
60
+ /**
61
+ * @inheritDoc
62
+ */
63
+ public function clear(): void
64
+ {
65
+ // Do nothing
66
+ }
67
+
68
+ /**
69
+ * @inheritDoc
70
+ */
71
+ public function withMappings(array $mappings): WritableContainerInterface
72
+ {
73
+ return clone $this;
74
+ }
75
+
76
+ /**
77
+ * @inheritDoc
78
+ */
79
+ public function withAddedMappings(array $mappings): WritableContainerInterface
80
+ {
81
+ return clone $this;
82
+ }
83
+
84
+ /**
85
+ * @inheritDoc
86
+ */
87
+ public function withoutKeys(array $keys): WritableContainerInterface
88
+ {
89
+ return clone $this;
90
+ }
91
+
92
+ /**
93
+ * @inheritDoc
94
+ */
95
+ public function getIterator()
96
+ {
97
+ return new ArrayIterator([]);
98
+ }
99
+ }
vendor/dhii/containers/src/PathContainer.php CHANGED
@@ -1,8 +1,11 @@
1
  <?php
2
 
 
 
3
  namespace Dhii\Container;
4
 
5
  use Dhii\Collection\ContainerInterface;
 
6
  use Dhii\Container\Exception\NotFoundException;
7
  use Psr\Container\ContainerInterface as PsrContainerInterface;
8
  use Psr\Container\NotFoundExceptionInterface;
@@ -57,7 +60,7 @@ class PathContainer implements ContainerInterface
57
  /**
58
  * @since [*next-version*]
59
  *
60
- * @var string
61
  */
62
  protected $delimiter;
63
 
@@ -67,7 +70,7 @@ class PathContainer implements ContainerInterface
67
  * @since [*next-version*]
68
  *
69
  * @param PsrContainerInterface $inner The container instance to decorate.
70
- * @param string $delimiter The path delimiter to use.
71
  */
72
  public function __construct(PsrContainerInterface $inner, string $delimiter = '/')
73
  {
@@ -85,10 +88,20 @@ class PathContainer implements ContainerInterface
85
  $tKey = (strpos($key, $this->delimiter) === 0)
86
  ? substr($key, strlen($this->delimiter))
87
  : $key;
 
 
 
 
 
 
 
 
 
 
88
  $path = array_filter(explode($this->delimiter, $tKey));
89
 
90
  if (empty($path)) {
91
- throw new NotFoundException("The path is empty");
92
  }
93
 
94
  $current = $this->inner;
@@ -97,7 +110,7 @@ class PathContainer implements ContainerInterface
97
  while (!empty($path)) {
98
  if (!($current instanceof PsrContainerInterface)) {
99
  $tail = implode($this->delimiter, $path);
100
- throw new NotFoundException("Key '{$head}' does not exist at path '{$tail}'", 0, null, $this, $head);
101
  }
102
 
103
  $head = array_shift($path);
@@ -114,6 +127,11 @@ class PathContainer implements ContainerInterface
114
  */
115
  public function has($key)
116
  {
 
 
 
 
 
117
  try {
118
  $this->get($key);
119
 
1
  <?php
2
 
3
+ declare(strict_types=1);
4
+
5
  namespace Dhii\Container;
6
 
7
  use Dhii\Collection\ContainerInterface;
8
+ use Dhii\Container\Exception\ContainerException;
9
  use Dhii\Container\Exception\NotFoundException;
10
  use Psr\Container\ContainerInterface as PsrContainerInterface;
11
  use Psr\Container\NotFoundExceptionInterface;
60
  /**
61
  * @since [*next-version*]
62
  *
63
+ * @var non-empty-string
64
  */
65
  protected $delimiter;
66
 
70
  * @since [*next-version*]
71
  *
72
  * @param PsrContainerInterface $inner The container instance to decorate.
73
+ * @param non-empty-string $delimiter The path delimiter to use.
74
  */
75
  public function __construct(PsrContainerInterface $inner, string $delimiter = '/')
76
  {
88
  $tKey = (strpos($key, $this->delimiter) === 0)
89
  ? substr($key, strlen($this->delimiter))
90
  : $key;
91
+
92
+ $delimiter = $this->delimiter;
93
+ if (!strlen($delimiter)) {
94
+ throw new ContainerException('Cannot use empty delimiter');
95
+ }
96
+
97
+ /**
98
+ * @psalm-suppress PossiblyFalseArgument
99
+ * Result of explode() will never be false, because delimiter is never empty - see above.
100
+ */
101
  $path = array_filter(explode($this->delimiter, $tKey));
102
 
103
  if (empty($path)) {
104
+ throw new NotFoundException('The path is empty');
105
  }
106
 
107
  $current = $this->inner;
110
  while (!empty($path)) {
111
  if (!($current instanceof PsrContainerInterface)) {
112
  $tail = implode($this->delimiter, $path);
113
+ throw new NotFoundException(sprintf('Key "%1$s" does not exist at path "%2$s"', $head, $tail));
114
  }
115
 
116
  $head = array_shift($path);
127
  */
128
  public function has($key)
129
  {
130
+ /**
131
+ * @psalm-suppress InvalidCatch
132
+ * The base interface does not extend Throwable, but in fact everything that is possible
133
+ * in theory to catch will be Throwable, and PSR-11 exceptions will implement this interface
134
+ */
135
  try {
136
  $this->get($key);
137
 
vendor/dhii/containers/src/PrefixingContainer.php CHANGED
@@ -1,5 +1,7 @@
1
  <?php
2
 
 
 
3
  namespace Dhii\Container;
4
 
5
  use Dhii\Collection\ContainerInterface;
@@ -61,9 +63,14 @@ class PrefixingContainer implements ContainerInterface
61
  public function get($key)
62
  {
63
  if (!$this->isPrefixed($key) && $this->strict) {
64
- throw new NotFoundException(sprintf('Key "%s" does not exist', $key), 0, null, $this, $key);
65
  }
66
 
 
 
 
 
 
67
  try {
68
  return $this->inner->get($this->unprefix($key));
69
  } catch (NotFoundExceptionInterface $nfException) {
@@ -98,7 +105,7 @@ class PrefixingContainer implements ContainerInterface
98
  *
99
  * @return string The inner key.
100
  */
101
- protected function unprefix($key)
102
  {
103
  return $this->isPrefixed($key)
104
  ? substr($key, strlen($this->prefix))
@@ -114,7 +121,7 @@ class PrefixingContainer implements ContainerInterface
114
  *
115
  * @return bool True if the key is prefixed, false if not.
116
  */
117
- protected function isPrefixed($key)
118
  {
119
  return strlen($this->prefix) > 0 && strpos($key, $this->prefix) === 0;
120
  }
1
  <?php
2
 
3
+ declare(strict_types=1);
4
+
5
  namespace Dhii\Container;
6
 
7
  use Dhii\Collection\ContainerInterface;
63
  public function get($key)
64
  {
65
  if (!$this->isPrefixed($key) && $this->strict) {
66
+ throw new NotFoundException(sprintf('Key "%s" does not exist', $key));
67
  }
68
 
69
+ /**
70
+ * @psalm-suppress InvalidCatch
71
+ * The base interface does not extend Throwable, but in fact everything that is possible
72
+ * in theory to catch will be Throwable, and PSR-11 exceptions will implement this interface
73
+ */
74
  try {
75
  return $this->inner->get($this->unprefix($key));
76
  } catch (NotFoundExceptionInterface $nfException) {
105
  *
106
  * @return string The inner key.
107
  */
108
+ protected function unprefix(string $key): string
109
  {
110
  return $this->isPrefixed($key)
111
  ? substr($key, strlen($this->prefix))
121
  *
122
  * @return bool True if the key is prefixed, false if not.
123
  */
124
+ protected function isPrefixed(string $key): bool
125
  {
126
  return strlen($this->prefix) > 0 && strpos($key, $this->prefix) === 0;
127
  }
vendor/dhii/containers/src/ProxyContainer.php CHANGED
@@ -1,4 +1,5 @@
1
  <?php
 
2
  declare(strict_types=1);
3
 
4
  namespace Dhii\Container;
@@ -18,7 +19,7 @@ class ProxyContainer implements BaseContainerInterface
18
  use StringTranslatingTrait;
19
 
20
  /**
21
- * @var BaseContainerInterface
22
  */
23
  protected $innerContainer;
24
 
@@ -49,6 +50,7 @@ class ProxyContainer implements BaseContainerInterface
49
  public function has($key)
50
  {
51
  if (!($this->innerContainer instanceof BaseContainerInterface)) {
 
52
  throw new ContainerException($this->__('Inner container not set'));
53
  }
54
 
@@ -62,7 +64,7 @@ class ProxyContainer implements BaseContainerInterface
62
  *
63
  * @param BaseContainerInterface $innerContainer The inner container to proxy.
64
  */
65
- public function setInnerContainer(BaseContainerInterface $innerContainer)
66
  {
67
  $this->innerContainer = $innerContainer;
68
  }
1
  <?php
2
+
3
  declare(strict_types=1);
4
 
5
  namespace Dhii\Container;
19
  use StringTranslatingTrait;
20
 
21
  /**
22
+ * @var ?BaseContainerInterface
23
  */
24
  protected $innerContainer;
25
 
50
  public function has($key)
51
  {
52
  if (!($this->innerContainer instanceof BaseContainerInterface)) {
53
+ /** @psalm-suppress MissingThrowsDocblock The exception class implements declared thrown interface */
54
  throw new ContainerException($this->__('Inner container not set'));
55
  }
56
 
64
  *
65
  * @param BaseContainerInterface $innerContainer The inner container to proxy.
66
  */
67
+ public function setInnerContainer(BaseContainerInterface $innerContainer): void
68
  {
69
  $this->innerContainer = $innerContainer;
70
  }
vendor/dhii/containers/src/SegmentingContainer.php CHANGED
@@ -1,9 +1,12 @@
1
  <?php
2
 
 
 
3
  namespace Dhii\Container;
4
 
5
  use Dhii\Collection\ContainerInterface;
6
  use Psr\Container\ContainerInterface as PsrContainerInterface;
 
7
  use function array_filter;
8
  use function ltrim;
9
 
@@ -75,7 +78,7 @@ class SegmentingContainer implements ContainerInterface
75
  * @param PsrContainerInterface $inner The container to decorate.
76
  * @param string $delimiter The path delimiter.
77
  */
78
- public function __construct($inner, $delimiter = '/')
79
  {
80
  $this->inner = $inner;
81
  $this->root = '';
1
  <?php
2
 
3
+ declare(strict_types=1);
4
+
5
  namespace Dhii\Container;
6
 
7
  use Dhii\Collection\ContainerInterface;
8
  use Psr\Container\ContainerInterface as PsrContainerInterface;
9
+
10
  use function array_filter;
11
  use function ltrim;
12
 
78
  * @param PsrContainerInterface $inner The container to decorate.
79
  * @param string $delimiter The path delimiter.
80
  */
81
+ public function __construct(PsrContainerInterface $inner, string $delimiter = '/')
82
  {
83
  $this->inner = $inner;
84
  $this->root = '';
vendor/dhii/containers/src/ServiceProvider.php CHANGED
@@ -1,5 +1,7 @@
1
  <?php
2
 
 
 
3
  namespace Dhii\Container;
4
 
5
  use Interop\Container\ServiceProviderInterface;
@@ -45,4 +47,4 @@ class ServiceProvider implements ServiceProviderInterface
45
  {
46
  return $this->extensions;
47
  }
48
- }
1
  <?php
2
 
3
+ declare(strict_types=1);
4
+
5
  namespace Dhii\Container;
6
 
7
  use Interop\Container\ServiceProviderInterface;
47
  {
48
  return $this->extensions;
49
  }
50
+ }
vendor/dhii/containers/src/SimpleCacheContainer.php ADDED
@@ -0,0 +1,111 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ declare(strict_types=1);
4
+
5
+ namespace Dhii\Container;
6
+
7
+ use Dhii\Collection\ClearableContainerInterface;
8
+ use Dhii\Collection\MutableContainerInterface;
9
+ use Dhii\Container\Exception\ContainerException;
10
+ use Dhii\Container\Exception\NotFoundException;
11
+ use Exception;
12
+ use Psr\SimpleCache\CacheInterface;
13
+
14
+ class SimpleCacheContainer implements
15
+ MutableContainerInterface,
16
+ ClearableContainerInterface
17
+ {
18
+ /**
19
+ * @var CacheInterface
20
+ */
21
+ protected $storage;
22
+ /**
23
+ * @var int
24
+ */
25
+ protected $ttl;
26
+
27
+ public function __construct(CacheInterface $storage, int $ttl)
28
+ {
29
+ $this->storage = $storage;
30
+ $this->ttl = $ttl;
31
+ }
32
+
33
+ /**
34
+ * @inheritDoc
35
+ */
36
+ public function get($id)
37
+ {
38
+ $storage = $this->storage;
39
+
40
+ try {
41
+ if (!$storage->has($id)) {
42
+ return new NotFoundException(sprintf('Key "%1$s" not found', $id));
43
+ }
44
+
45
+ $value = $storage->get($id);
46
+ } catch (Exception $e) {
47
+ throw new ContainerException(sprintf('Could not retrieve value for key "%1$s"', $id), 0, $e);
48
+ }
49
+
50
+ return $value;
51
+ }
52
+
53
+ /**
54
+ * @inheritDoc
55
+ */
56
+ public function has($id)
57
+ {
58
+ $storage = $this->storage;
59
+
60
+ try {
61
+ $has = $storage->has($id);
62
+ } catch (Exception $e) {
63
+ throw new ContainerException(sprintf('Could not check for key "%1$s"', $id), 0, $e);
64
+ }
65
+
66
+ return $has;
67
+ }
68
+
69
+ /**
70
+ * @inheritDoc
71
+ */
72
+ public function set(string $key, $value): void
73
+ {
74
+ $storage = $this->storage;
75
+ $ttl = $this->ttl;
76
+
77
+ try {
78
+ $storage->set($key, $value, $ttl);
79
+ } catch (Exception $e) {
80
+ throw new ContainerException(sprintf('Could not set key "%1$s" with value "%2$s"', $key, $value), 0, $e);
81
+ }
82
+ }
83
+
84
+ /**
85
+ * @inheritDoc
86
+ */
87
+ public function unset(string $key): void
88
+ {
89
+ $storage = $this->storage;
90
+
91
+ try {
92
+ $storage->delete($key);
93
+ } catch (Exception $e) {
94
+ throw new ContainerException(sprintf('Could not unset key "%1$s"', $key), 0, $e);
95
+ }
96
+ }
97
+
98
+ /**
99
+ * @inheritDoc
100
+ */
101
+ public function clear(): void
102
+ {
103
+ $storage = $this->storage;
104
+
105
+ try {
106
+ $storage->clear();
107
+ } catch (Exception $e) {
108
+ throw new ContainerException(sprintf('Could not clear container'), 0, $e);
109
+ }
110
+ }
111
+ }
vendor/dhii/containers/src/Util/StringTranslatingTrait.php CHANGED
@@ -1,4 +1,6 @@
1
- <?php declare(strict_types = 1);
 
 
2
 
3
  namespace Dhii\Container\Util;
4
 
@@ -9,7 +11,6 @@ namespace Dhii\Container\Util;
9
  */
10
  trait StringTranslatingTrait
11
  {
12
-
13
  /**
14
  * Translates a string, and replaces placeholders.
15
  *
@@ -17,16 +18,17 @@ trait StringTranslatingTrait
17
  *
18
  * @see sprintf()
19
  * @see _translate()
20
- * @param string $string The format string to translate.
21
- * @param array $args Placeholder values to replace in the string.
22
- * @param mixed $context The context for translation.
 
 
23
  * @return string The translated string.
24
  */
25
  protected function __(string $string, array $args = array(), $context = null): string
26
  {
27
  $string = $this->_translate($string, $context);
28
  array_unshift($args, $string);
29
-
30
  return call_user_func_array('sprintf', $args);
31
  }
32
 
@@ -36,12 +38,15 @@ trait StringTranslatingTrait
36
  * A no-op implementation.
37
  *
38
  * @since [*next-version*]
 
39
  * @param string $string The string to translate.
 
 
40
  * @return string The translated string.
 
41
  */
42
- protected function _translate(string $string, $context = null): string
43
  {
44
  return $string;
45
  }
46
-
47
- }
1
+ <?php
2
+
3
+ declare(strict_types=1);
4
 
5
  namespace Dhii\Container\Util;
6
 
11
  */
12
  trait StringTranslatingTrait
13
  {
 
14
  /**
15
  * Translates a string, and replaces placeholders.
16
  *
18
  *
19
  * @see sprintf()
20
  * @see _translate()
21
+ *
22
+ * @param string $string The format string to translate.
23
+ * @param list<scalar> $args Placeholder values to replace in the string.
24
+ * @param mixed $context The context for translation.
25
+ *
26
  * @return string The translated string.
27
  */
28
  protected function __(string $string, array $args = array(), $context = null): string
29
  {
30
  $string = $this->_translate($string, $context);
31
  array_unshift($args, $string);
 
32
  return call_user_func_array('sprintf', $args);
33
  }
34
 
38
  * A no-op implementation.
39
  *
40
  * @since [*next-version*]
41
+ *
42
  * @param string $string The string to translate.
43
+ * @param string $context The context to translate the string in.
44
+ *
45
  * @return string The translated string.
46
+ * phpcs:disable PSR2.Methods.MethodDeclaration.Underscore
47
  */
48
+ protected function _translate(string $string, string $context = null): string
49
  {
50
  return $string;
51
  }
52
+ }
 
vendor/dhii/containers/tests/bootstrap.php ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
1
+ <?php
2
+
3
+ error_reporting(E_ALL | E_STRICT);
4
+
5
+ require_once dirname(__FILE__).'/../vendor/autoload.php';
vendor/dhii/containers/tests/functional/AliasingContainerTest.php ADDED
@@ -0,0 +1,148 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Dhii\Container\FuncTest;
4
+
5
+ use Dhii\Container\AliasingContainer;
6
+ use Dhii\Container\Exception\NotFoundException;
7
+ use Dhii\Container\TestHelpers\ContainerMock;
8
+ use Psr\Container\NotFoundExceptionInterface;
9
+ use Exception;
10
+ use PHPUnit\Framework\TestCase;
11
+ use function uniqid;
12
+
13
+ class AliasingContainerTest extends TestCase
14
+ {
15
+ /**
16
+ * Tests that the subject is able to fetch aliased data from the inner container, using the original key.
17
+ *
18
+ * @since [*next-version*]
19
+ *
20
+ * @throws Exception
21
+ */
22
+ public function testGet()
23
+ {
24
+ $serviceKey = uniqid('key');
25
+ $aliasKey = uniqid('alias');
26
+ $service = uniqid('service');
27
+
28
+ $inner = ContainerMock::create($this)->expectHasService($serviceKey, $service);
29
+
30
+ $aliases = [
31
+ $aliasKey => $serviceKey,
32
+ ];
33
+ $subject = new AliasingContainer($inner, $aliases);
34
+
35
+ $this->assertSame($service, $subject->get($aliasKey), 'Wrong result retrieved');
36
+ }
37
+
38
+ /**
39
+ * Tests that the subject is able to fetch non-aliased data from the inner container, using the original key.
40
+ *
41
+ * @since [*next-version*]
42
+ *
43
+ * @throws Exception
44
+ */
45
+ public function testGetNoAlias()
46
+ {
47
+ $serviceKey = uniqid('key');
48
+ $service = uniqid('service');
49
+
50
+ $inner = ContainerMock::create($this)->expectHasService($serviceKey, $service);
51
+
52
+ $aliases = [];
53
+ $subject = new AliasingContainer($inner, $aliases);
54
+
55
+ $result = $subject->get($serviceKey);
56
+
57
+ $this->assertSame($service, $result, 'Wrong result retrieved');
58
+ }
59
+
60
+ /**
61
+ * Tests that the subject is unable to fetch non-existing data from the inner container.
62
+ *
63
+ * @since [*next-version*]
64
+ *
65
+ * @throws Exception
66
+ */
67
+ public function testGetNotFound()
68
+ {
69
+ $key = uniqid('not-exists');
70
+ $inner = ContainerMock::create($this)->expectNotHasService($key);
71
+
72
+ $aliases = [];
73
+ $subject = new AliasingContainer($inner, $aliases);
74
+
75
+ try {
76
+ $subject->get($key);
77
+
78
+ $this->fail('Subject did not throw an exception');
79
+ } catch (Exception $exception) {
80
+ $this->assertInstanceOf(
81
+ NotFoundExceptionInterface::class,
82
+ $exception,
83
+ 'Exception does not implement correct interface'
84
+ );
85
+ }
86
+ }
87
+
88
+ /**
89
+ * Tests that the subject is able to look up aliased data in the inner container.
90
+ *
91
+ * @since [*next-version*]
92
+ *
93
+ * @throws Exception
94
+ */
95
+ public function testHas()
96
+ {
97
+ $serviceKey = uniqid('key');
98
+ $aliasKey = uniqid('alias');
99
+ $service = uniqid('service');
100
+
101
+ $inner = ContainerMock::create($this)->expectHasService($serviceKey, $service);
102
+
103
+ $aliases = [
104
+ $aliasKey => $serviceKey,
105
+ ];
106
+ $subject = new AliasingContainer($inner, $aliases);
107
+
108
+ $this->assertTrue($subject->has($aliasKey));
109
+ }
110
+
111
+ /**
112
+ * Tests that the subject can look up data in the inner container that was not aliased.
113
+ *
114
+ * @since [*next-version*]
115
+ *
116
+ * @throws Exception
117
+ */
118
+ public function testHasNoAlias()
119
+ {
120
+ $serviceKey = uniqid('key');
121
+ $service = uniqid('service');
122
+
123
+ $inner = ContainerMock::create($this)->expectHasService($serviceKey, $service);
124
+
125
+ $aliases = [];
126
+ $subject = new AliasingContainer($inner, $aliases);
127
+
128
+ $this->assertTrue($subject->has($serviceKey));
129
+ }
130
+
131
+ /**
132
+ * Tests that the subject correctly reports that non-existing data in the inner container does not exist.
133
+ *
134
+ * @since [*next-version*]
135
+ *
136
+ * @throws Exception
137
+ */
138
+ public function testHasNotFound()
139
+ {
140
+ $key = uniqid('service-key');
141
+ $inner = ContainerMock::create($this)->expectNotHasService($key);
142
+
143
+ $aliases = [];
144
+ $subject = new AliasingContainer($inner, $aliases);
145
+
146
+ $this->assertFalse($subject->has($key));
147
+ }
148
+ }
vendor/dhii/containers/tests/functional/CachingContainerTest.php ADDED
@@ -0,0 +1,93 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Dhii\Container\FuncTest;
4
+
5
+ use Dhii\Container\CachingContainer as TestSubject;
6
+ use Dhii\Container\TestHelpers\ComponentMockeryTrait;
7
+ use Exception;
8
+ use PHPUnit\Framework\MockObject\MockObject;
9
+ use PHPUnit\Framework\TestCase;
10
+
11
+ class CachingContainerTest extends TestCase
12
+ {
13
+ use ComponentMockeryTrait;
14
+
15
+ /**
16
+ * Creates a new instance of the test subject.
17
+ *
18
+ * @param array $dependencies A list of constructor args.
19
+ * @param array|null $methods The names of methods to mock in the subject.
20
+ * @return MockObject|TestSubject The new instance.
21
+ * @throws Exception If problem creating.
22
+ */
23
+ protected function createSubject(array $dependencies, array $methods = null)
24
+ {
25
+ return $this->createMockBuilder(TestSubject::class, $methods, $dependencies)
26
+ ->setConstructorArgs($dependencies)
27
+ ->getMock();
28
+ }
29
+
30
+ /**
31
+ * Tests that the subject can correctly retrieve a value from the inner container.
32
+ *
33
+ * The value must be the _same thing_ no matter how many times it is retrieved.
34
+ * The subject must only ask the inner container once for the value.
35
+ *
36
+ * @throws Exception If problem testing.
37
+ */
38
+ public function testGet()
39
+ {
40
+ {
41
+ $key = uniqid('key');
42
+ $value = (object) [];
43
+ $container = $this->createContainer([
44
+ $key => $value,
45
+ ]);
46
+ $subject = $this->createSubject([$container]);
47
+
48
+ $container->expects($this->exactly(1))
49
+ ->method('get')
50
+ ->with($key);
51
+ }
52
+
53
+ {
54
+ $operations = rand(2, 9);
55
+ $result = null;
56
+
57
+ for ($i = 0; $i < $operations; $i++) {
58
+ $result = $subject->get($key);
59
+ }
60
+ }
61
+
62
+ {
63
+ $this->assertSame($value, $result, 'Wrong value retrieved');
64
+ }
65
+ }
66
+
67
+ /**
68
+ * Tests that the subject correctly determines having keys.
69
+ *
70
+ * Subject must report having a key only if the inner container has that key.
71
+ *
72
+ * @depends testGet
73
+ */
74
+ public function testHas()
75
+ {
76
+ {
77
+ $key1 = uniqid('key');
78
+ $key2 = uniqid('not-exists');
79
+
80
+ $container = $this->createContainer([
81
+ $key1 => uniqid('value'),
82
+ ]);
83
+ $container->method('has')->withConsecutive([$key1], [$key2])->willReturnOnConsecutiveCalls(true, false);
84
+
85
+ $subject = $this->createSubject([$container]);
86
+ }
87
+
88
+ {
89
+ $this->assertTrue($subject->has($key1), 'Wrong determined having');
90
+ $this->assertFalse($subject->has($key2), 'Wrong determined not having');
91
+ }
92
+ }
93
+ }
vendor/dhii/containers/tests/functional/CompositeCachingServiceProviderTest.php ADDED
@@ -0,0 +1,108 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Dhii\Container\FuncTest;
4
+
5
+ use Dhii\Container\CompositeCachingServiceProvider;
6
+ use Dhii\Container\TestHelpers\ContainerMock;
7
+ use Dhii\Container\TestHelpers\ServiceProviderMock;
8
+ use Exception;
9
+ use PHPUnit\Framework\TestCase;
10
+
11
+ class CompositeCachingServiceProviderTest extends TestCase
12
+ {
13
+ /**
14
+ * Tests that `getFactories()` returns factories correctly overridden.
15
+ *
16
+ * @throws Exception If problem testing.
17
+ */
18
+ public function testGetFactories()
19
+ {
20
+ {
21
+ $srv1 = uniqid('srv1');
22
+ $f1 = function () use ($srv1) { return $srv1; };
23
+ $srv2 = uniqid('srv2');
24
+ $f2 = function () use ($srv2) { return $srv2; };
25
+ $srv3 = uniqid('srv3');
26
+ $f3 = function () use ($srv3) { return $srv3; };
27
+ $srv4 = uniqid('srv4');
28
+ $f4 = function () use ($srv4) { return $srv4; };
29
+
30
+ $provider1 = ServiceProviderMock::create($this, [
31
+ 'one' => $f1,
32
+ 'two' => $f2,
33
+ ]);
34
+
35
+ $provider2 = ServiceProviderMock::create($this, [
36
+ 'two' => $f3,
37
+ 'three' => $f4,
38
+ ],[]);
39
+
40
+ $subject = new CompositeCachingServiceProvider([$provider1, $provider2]);
41
+ }
42
+
43
+ {
44
+ $result = $subject->getFactories();
45
+ }
46
+
47
+ {
48
+ $this->assertCount(3, $result, 'Wrong number of factories');
49
+ $this->assertArrayHasKey('one', $result, 'Factory missing');
50
+ $this->assertArrayHasKey('two', $result, 'Factory missing');
51
+ $this->assertArrayHasKey('three', $result, 'Factory missing');
52
+
53
+ $this->assertEquals($srv1, $result['one'](), 'Wrong factory');
54
+ $this->assertEquals($srv3, $result['two'](), 'Wrong factory');
55
+ $this->assertEquals($srv4, $result['three'](), 'Wrong factory');
56
+ }
57
+ }
58
+
59
+ /**
60
+ * Tests that `getExtensions()` returns extensions correctly nested.
61
+ *
62
+ * @throws Exception If problem testing.
63
+ */
64
+ public function testGetExtensions()
65
+ {
66
+ {
67
+ $combination = function (string $a, string $b) {
68
+ return sprintf('%1$s-%2$s', $a, $b);
69
+ };
70
+ $srv1 = uniqid('srv1');
71
+ $f1 = function () use ($srv1) { return $srv1; };
72
+ $srv2 = uniqid('srv2');
73
+ $f2 = function () use ($srv2) { return $srv2; };
74
+ $srv3 = uniqid('srv3');
75
+ $f3 = function ($container, $previous) use ($srv3, $combination) { return $combination($previous, $srv3); };
76
+ $srv4 = uniqid('srv4');
77
+ $f4 = function () use ($srv4) { return $srv4; };
78
+
79
+ $provider1 = ServiceProviderMock::create($this, [], [
80
+ 'one' => $f1,
81
+ 'two' => $f2,
82
+ ]);
83
+ $provider2 = ServiceProviderMock::create($this, [], [
84
+ 'two' => $f3,
85
+ 'three' => $f4,
86
+ ]);
87
+
88
+ $container = ContainerMock::create($this);
89
+
90
+ $subject = new CompositeCachingServiceProvider([$provider1, $provider2]);
91
+ }
92
+
93
+ {
94
+ $result = $subject->getExtensions();
95
+ }
96
+
97
+ {
98
+ $this->assertCount(3, $result, 'Wrong number of factories');
99
+ $this->assertArrayHasKey('one', $result, 'Factory missing');
100
+ $this->assertArrayHasKey('two', $result, 'Factory missing');
101
+ $this->assertArrayHasKey('three', $result, 'Factory missing');
102
+
103
+ $this->assertEquals($srv1, $result['one']($container, $srv1), 'Wrong factory');
104
+ $this->assertEquals($combination($srv2, $srv3), $result['two']($container, $srv2), 'Wrong factory');
105
+ $this->assertEquals($srv4, $result['three']($container, $srv4), 'Wrong factory');
106
+ }
107
+ }
108
+ }
vendor/dhii/containers/tests/functional/CompositeContainerTest.php ADDED
@@ -0,0 +1,112 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Dhii\Container\FuncTest;
4
+
5
+ use Dhii\Container\CompositeContainer;
6
+ use Dhii\Container\TestHelpers\ContainerMock;
7
+ use Exception;
8
+ use PHPUnit\Framework\TestCase;
9
+
10
+ class CompositeContainerTest extends TestCase
11
+ {
12
+ /**
13
+ * Tests if subject can correctly retrieve a value by key from a list of containers.
14
+ *
15
+ * @throws Exception If problem testing.
16
+ */
17
+ public function testGet()
18
+ {
19
+ {
20
+ $key = uniqid('key');
21
+ $value1 = uniqid('value1');
22
+ $value2 = uniqid('value2');
23
+ }
24
+
25
+ {
26
+ $c1 = ContainerMock::create($this);
27
+ $c1->expectNotHasService($key);
28
+
29
+ $c2 = ContainerMock::create($this);
30
+ $c2->expectHasService($key, $value1);
31
+
32
+ $c3 = ContainerMock::create($this);
33
+ $c3->expectHasService($key, $value2);
34
+
35
+ $subject = new CompositeContainer([$c1, $c2, $c3]);
36
+ }
37
+
38
+ {
39
+ $result = $subject->get($key);
40
+ }
41
+
42
+ {
43
+ $this->assertEquals($value1, $result, 'Wrong value retrieved');
44
+ }
45
+ }
46
+
47
+ /**
48
+ * Tests that the subject can correctly determine having an existing key.
49
+ *
50
+ * @throws Exception If problem testing.
51
+ */
52
+ public function testHasTrue()
53
+ {
54
+ {
55
+ $key = uniqid('key');
56
+ $value1 = uniqid('value1');
57
+ $value2 = uniqid('value2');
58
+ }
59
+
60
+ {
61
+ $c1 = ContainerMock::create($this);
62
+ $c1->expectNotHasService($key);
63
+
64
+ $c2 = ContainerMock::create($this);
65
+ $c2->expectHasService($key, $value1);
66
+
67
+ $c3 = ContainerMock::create($this);
68
+ $c3->expectHasService($key, $value2);
69
+
70
+ $subject = new CompositeContainer([$c1, $c2, $c3]);
71
+ }
72
+
73
+ {
74
+ $result = $subject->has($key);
75
+ }
76
+
77
+ {
78
+ $this->assertTrue($result, 'Wrong value retrieved');
79
+ }
80
+ }
81
+
82
+ /**
83
+ * Tests that the subject can correctly determine not having a non-existing key.
84
+ *
85
+ * @throws Exception If problem testing.
86
+ */
87
+ public function testHasFalse()
88
+ {
89
+ $key = uniqid('key');
90
+
91
+ {
92
+ $c1 = ContainerMock::create($this);
93
+ $c1->expectNotHasService($key);
94
+
95
+ $c2 = ContainerMock::create($this);
96
+ $c2->expectNotHasService($key);
97
+
98
+ $c3 = ContainerMock::create($this);
99
+ $c3->expectNotHasService($key);
100
+
101
+ $subject = new CompositeContainer([$c1, $c2, $c3]);
102
+ }
103
+
104
+ {
105
+ $result = $subject->has($key);
106
+ }
107
+
108
+ {
109
+ $this->assertFalse($result, 'Incorrectly determined not having');
110
+ }
111
+ }
112
+ }
vendor/dhii/containers/tests/functional/DataStructureBasedFactoryTest.php ADDED
@@ -0,0 +1,80 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Dhii\Container\FuncTest;
4
+
5
+ use Dhii\Collection\WritableMapFactoryInterface;
6
+ use Dhii\Container\DataStructureBasedFactory as TestSubject;
7
+ use Dhii\Container\DictionaryFactory;
8
+ use PHPUnit\Framework\MockObject\MockObject;
9
+ use PHPUnit\Framework\TestCase;
10
+
11
+ class DataStructureBasedFactoryTest extends TestCase
12
+ {
13
+ /**
14
+ * @return TestSubject&MockObject
15
+ */
16
+ public function createInstance(WritableMapFactoryInterface $mapFactory): TestSubject
17
+ {
18
+ $mock = $this->getMockBuilder(TestSubject::class)
19
+ ->setMethods(null)
20
+ ->setConstructorArgs([$mapFactory])
21
+ ->getMock();
22
+
23
+ return $mock;
24
+ }
25
+
26
+ /**
27
+ * @return TestSubject
28
+ */
29
+ public function createConfiguredInstance(): TestSubject
30
+ {
31
+ $mapFactory = $this->createWritableMapFactory();
32
+ $subject = $this->createInstance($mapFactory);
33
+
34
+ return $subject;
35
+ }
36
+
37
+ /**
38
+ * @return DictionaryFactory&MockObject
39
+ */
40
+ public function createWritableMapFactory(): DictionaryFactory
41
+ {
42
+ $mock = $this->getMockBuilder(DictionaryFactory::class)
43
+ ->setMethods(null)
44
+ ->getMock();
45
+
46
+ return $mock;
47
+ }
48
+
49
+ public function testCreateContainerFromArray()
50
+ {
51
+ {
52
+ $grandchildName = uniqid('grandchild');
53
+ $path = ['children', 0, 'children', 'name'];
54
+ $structure = [
55
+ 'name' => 'Bob',
56
+ $path[0] => [
57
+ $path[1] => [
58
+ 'name' => 'Alex',
59
+ $path[2] => [
60
+ $path[3] => $grandchildName,
61
+ 'children' => []
62
+ ],
63
+ ]
64
+ ],
65
+ ];
66
+ $subject = $this->createConfiguredInstance();
67
+ }
68
+
69
+ {
70
+ $hierarchy = $subject->createContainerFromArray($structure);
71
+
72
+ $result = $hierarchy;
73
+ foreach ($path as $key) {
74
+ $result = $result->get($key);
75
+ }
76
+
77
+ $this->assertEquals($grandchildName, $result);
78
+ }
79
+ }
80
+ }
vendor/dhii/containers/tests/functional/DelegatingContainerTest.php ADDED
@@ -0,0 +1,90 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Dhii\Container\FuncTest;
4
+
5
+ use Dhii\Container\DelegatingContainer;
6
+ use Dhii\Container\TestHelpers\ContainerMock;
7
+ use Dhii\Container\TestHelpers\InvocableMock;
8
+ use Dhii\Container\TestHelpers\ServiceProviderMock;
9
+ use Exception;
10
+ use PHPUnit\Framework\TestCase;
11
+ use Psr\Container\ContainerInterface;
12
+
13
+ class DelegatingContainerTest extends TestCase
14
+ {
15
+ /**
16
+ * Tests that the subject is able to retrieve an extended service.
17
+ *
18
+ * The service definition and extension must both receive the parent container.
19
+ *
20
+ * @throws Exception If problem testing.
21
+ */
22
+ public function testGet()
23
+ {
24
+ {
25
+ $serviceName = uniqid('service');
26
+ $parent = ContainerMock::create($this);
27
+ $service = 1;
28
+ $definition = InvocableMock::create($this, function (ContainerInterface $container) use ($service) {
29
+ return $service;
30
+ });
31
+ $extension = InvocableMock::create($this, function (ContainerInterface $container, $previous) {
32
+ return $previous + 1;
33
+ });
34
+ $provider = ServiceProviderMock::create($this, [
35
+ $serviceName => $definition,
36
+ ], [
37
+ $serviceName => $extension,
38
+ ]);
39
+ $subject = new DelegatingContainer($provider, $parent);
40
+
41
+ $definition->expectCalled(static::once())->with($parent);
42
+ $extension->expectCalled(static::once())->with($parent, $service);
43
+ }
44
+
45
+ {
46
+ $result = $subject->get($serviceName);
47
+ }
48
+
49
+ {
50
+ $this->assertEquals(2, $result, 'Wrong result retrieved');
51
+ }
52
+ }
53
+
54
+ public function testHasTrue()
55
+ {
56
+ {
57
+ $serviceName = uniqid('service');
58
+ $provider = ServiceProviderMock::create($this, [
59
+ $serviceName => function (ContainerInterface $container) {
60
+ return 1;
61
+ }
62
+ ], []);
63
+ $subject = new DelegatingContainer($provider);
64
+ }
65
+
66
+ {
67
+ $result = $subject->has($serviceName);
68
+ }
69
+
70
+ {
71
+ $this->assertTrue($result, 'Wrongly determined having');
72
+ }
73
+ }
74
+
75
+ public function testHasFalse()
76
+ {
77
+ {
78
+ $provider = ServiceProviderMock::create($this, [], []);
79
+ $subject = new DelegatingContainer($provider);
80
+ }
81
+
82
+ {
83
+ $result = $subject->has(uniqid('service'));
84
+ }
85
+
86
+ {
87
+ $this->assertFalse($result, 'Wrongly determined not having');
88
+ }
89
+ }
90
+ }
vendor/dhii/containers/tests/functional/DeprefixingContainerTest.php ADDED
@@ -0,0 +1,167 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Dhii\Container\FuncTest;
4
+
5
+ use Dhii\Container\DeprefixingContainer;
6
+ use Dhii\Container\Exception\NotFoundException;
7
+ use Dhii\Container\TestHelpers\ContainerMock;
8
+ use Exception;
9
+ use PHPUnit\Framework\TestCase;
10
+ use function uniqid;
11
+
12
+ class DeprefixingContainerTest extends TestCase
13
+ {
14
+ /**
15
+ * Tests that the subject is able to delegate retrieval to the inner container with a prefixed key.
16
+ *
17
+ * This test uses strict mode for the subject, preventing fallback to the original key.
18
+ *
19
+ * @throws Exception If problem testing.
20
+ */
21
+ public function testGetStrict()
22
+ {
23
+ $prefix = uniqid('prefix');
24
+ $serviceKey = uniqid('service-key');
25
+ $serviceVal = uniqid('service-val');
26
+
27
+ $inner = ContainerMock::create($this)->expectHasService($prefix . $serviceKey, $serviceVal);
28
+
29
+ $strict = true;
30
+ $subject = new DeprefixingContainer($inner, $prefix, $strict);
31
+
32
+ $result = $subject->get($serviceKey);
33
+
34
+ $this->assertSame($serviceVal, $result, 'Wrong result retrieved');
35
+ }
36
+
37
+ /**
38
+ * Tests that the subject is able to delegate retrieval to the inner container with a prefixed key when strict
39
+ * mode is disabled.
40
+ *
41
+ * @throws Exception If problem testing.
42
+ */
43
+ public function testGetNonStrict()
44
+ {
45
+ $serviceKey = uniqid('service-key');
46
+ $serviceVal = uniqid('service-val');
47
+ $prefix = uniqid('prefix');
48
+
49
+ $inner = ContainerMock::create($this);
50
+ $inner->method('get')
51
+ ->withConsecutive([$prefix . $serviceKey], [$serviceKey])
52
+ ->willReturnCallback(function () use ($serviceVal) {
53
+ static $count = 1;
54
+
55
+ // Throw the first time
56
+ if ($count === 1) {
57
+ $count++;
58
+ throw new NotFoundException();
59
+ }
60
+
61
+ // Return service the second time
62
+ return $serviceVal;
63
+ });
64
+ $inner->method('has')
65
+ ->with($serviceKey)
66
+ ->willReturn(true);
67
+
68
+ $strict = false;
69
+ $subject = new DeprefixingContainer($inner, $prefix, $strict);
70
+
71
+ $result = $subject->get($serviceKey);
72
+
73
+ $this->assertSame($serviceVal, $result, 'Wrong result retrieved');
74
+ }
75
+
76
+ /**
77
+ * Tests that the subject is able to delegate checking for the prefixed service key to the inner container when
78
+ * strict mode is enabled.
79
+ *
80
+ * @throws Exception If problem testing.
81
+ */
82
+ public function testHasStrict()
83
+ {
84
+ $prefix = uniqid('prefix');
85
+ $serviceKey = uniqid('service-key');
86
+ $serviceVal = uniqid('service-val');
87
+
88
+ $inner = ContainerMock::create($this)->expectHasService($prefix . $serviceKey, $serviceVal);
89
+
90
+ $strict = true;
91
+ $subject = new DeprefixingContainer($inner, $prefix, $strict);
92
+
93
+ $result = $subject->has($serviceKey);
94
+
95
+ $this->assertEquals(true, $result, 'Wrong result retrieved');
96
+ }
97
+
98
+ /**
99
+ * Tests that the subject is unable to find an un-prefixed entry when strict mode is enabled.
100
+ *
101
+ * @throws Exception If problem testing.
102
+ */
103
+ public function testHasStrictFalse()
104
+ {
105
+ $prefix = uniqid('prefix');
106
+ $serviceKey = uniqid('service-key');
107
+
108
+ $inner = ContainerMock::create($this)->expectNotHasService($prefix . $serviceKey);
109
+
110
+ $strict = true;
111
+ $subject = new DeprefixingContainer($inner, $prefix, $strict);
112
+
113
+ $result = $subject->has($serviceKey);
114
+
115
+ $this->assertEquals(false, $result, 'Wrong result retrieved');
116
+ }
117
+
118
+ /**
119
+ * Tests that the subject is able to delegate checking for an un-prefixed service key to the inner container when
120
+ * strict mode is disabled.
121
+ *
122
+ * @throws Exception If problem testing.
123
+ */
124
+ public function testHasNonStrict()
125
+ {
126
+ $serviceKey = uniqid('service-key');
127
+ $prefix = uniqid('prefix');
128
+
129
+ $inner = ContainerMock::create($this);
130
+ $inner->method('has')
131
+ ->withConsecutive([$prefix . $serviceKey], [$serviceKey])
132
+ ->willReturnCallback(function () {
133
+ static $count = 1;
134
+
135
+ // Return true on second run
136
+ return ($count++) === 2;
137
+ });
138
+
139
+ $strict = false;
140
+ $subject = new DeprefixingContainer($inner, $prefix, $strict);
141
+
142
+ $result = $subject->has($serviceKey);
143
+
144
+ $this->assertEquals(true, $result, 'Wrong result retrieved');
145
+ }
146
+
147
+ /**
148
+ * Tests that the subject is unable to find a non-existing service, regardless of prefix and strict mode.
149
+ *
150
+ * @throws Exception If problem testing.
151
+ */
152
+ public function testHasFalse()
153
+ {
154
+ $serviceKey = uniqid('service-key');
155
+
156
+ $inner = ContainerMock::create($this);
157
+ $inner->method('has')->willReturn(false);
158
+
159
+ $prefix = uniqid('prefix');
160
+ $strict = false;
161
+ $subject = new DeprefixingContainer($inner, $prefix, $strict);
162
+
163
+ $result = $subject->has($serviceKey);
164
+
165
+ $this->assertEquals(false, $result, 'Wrong result retrieved');
166
+ }
167
+ }
vendor/dhii/containers/tests/functional/DictionaryTest.php ADDED
@@ -0,0 +1,125 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Dhii\Container\FuncTest;
4
+
5
+ use Dhii\Collection\MapInterface;
6
+ use Dhii\Container\Dictionary as TestSubject;
7
+ use Dhii\Container\TestHelpers\ComponentMockeryTrait;
8
+ use Exception;
9
+ use PHPUnit\Framework\MockObject\MockObject;
10
+ use PHPUnit\Framework\TestCase;
11
+
12
+ class DictionaryTest extends TestCase
13
+ {
14
+
15
+ use ComponentMockeryTrait;
16
+
17
+ /**
18
+ * Creates a new instance of the test subject.
19
+ *
20
+ * @param array $dependencies A list of constructor args.
21
+ * @param array|null $methods The names of methods to mock in the subject.
22
+ * @return MockObject|TestSubject The new instance.
23
+ * @throws Exception If problem creating.
24
+ */
25
+ protected function createSubject(array $dependencies = [], array $methods = null)
26
+ {
27
+ return $this->createMockBuilder(TestSubject::class, $methods, $dependencies)
28
+ ->getMock();
29
+ }
30
+
31
+ protected function getDictionaryData()
32
+ {
33
+ static $data = null;
34
+
35
+ if ($data === null) {
36
+ $data = $this->createArray(
37
+ rand(2, 9),
38
+ function ($index) {
39
+ return uniqid("value-$index-");
40
+ },
41
+ function ($index) {
42
+ return uniqid("key-$index-");
43
+ }
44
+ );
45
+ }
46
+
47
+ return $data;
48
+ }
49
+
50
+ /**
51
+ * Tests that the SUT is what is should be.
52
+ *
53
+ * @return TestSubject|MockObject
54
+ * @throws Exception
55
+ */
56
+ public function testSubject()
57
+ {
58
+ {
59
+ $data = $this->getDictionaryData();
60
+ $subject = $this->createSubject([$data]);
61
+ }
62
+
63
+ {
64
+ $this->assertInstanceOf(MapInterface::class, $subject);
65
+ }
66
+
67
+ return $subject;
68
+ }
69
+
70
+ /**
71
+ * @param TestSubject $subject
72
+ * @depends testSubject
73
+ */
74
+ public function testIteration(TestSubject $subject)
75
+ {
76
+ {
77
+ $data = $this->getDictionaryData();
78
+ }
79
+
80
+ {
81
+ $this->assertEquals($data, iterator_to_array($subject));
82
+ }
83
+ }
84
+
85
+ /**
86
+ * @param TestSubject $subject
87
+ * @depends testSubject
88
+ */
89
+ public function testAccessors(TestSubject $subject)
90
+ {
91
+ {
92
+ $data = $this->getDictionaryData();
93
+ $key = array_keys($data)[0];
94
+ $value = $data[$key];
95
+ }
96
+
97
+ {
98
+ $this->assertTrue($subject->has($key));
99
+ $this->assertEquals($value, $subject->get($key));
100
+ }
101
+
102
+ return $subject;
103
+ }
104
+
105
+ /**
106
+ * @depends testAccessors
107
+ */
108
+ public function testMutators(TestSubject $subject)
109
+ {
110
+ $subject1 = $subject->withAddedMappings(['one' => 'hello', 'two' => 'world']);
111
+ $this->assertTrue($subject1->has('one'));
112
+ $this->assertEquals('hello', $subject1->get('one'));
113
+ $this->assertTrue($subject1->has('two'));
114
+ $this->assertEquals('world', $subject1->get('two'));
115
+
116
+ $subject2 = $subject1->withoutKeys(['one']);
117
+ $this->assertFalse($subject2->has('one'));
118
+
119
+ $subject3 = $subject2->withMappings(['three' => 'great']);
120
+ $this->assertTrue($subject3->has('three'));
121
+ $this->assertEquals('great', $subject3->get('three'));
122
+ $this->assertFalse($subject3->has('one'));
123
+ $this->assertFalse($subject3->has('two'));
124
+ }
125
+ }
vendor/dhii/containers/tests/functional/Exception/ContainerExceptionTest.php ADDED
@@ -0,0 +1,60 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php declare(strict_types = 1);
2
+
3
+ namespace Dhii\Container\FuncTest\Exception;
4
+
5
+ use Dhii\Container\Exception\ContainerException as TestSubject;
6
+ use Dhii\Container\TestHelpers\ComponentMockeryTrait;
7
+ use Exception;
8
+ use PHPUnit\Framework\MockObject\MockObject;
9
+ use PHPUnit\Framework\TestCase;
10
+
11
+ /**
12
+ * Tests {@see TestSubject}.
13
+ *
14
+ * @package Dhii\Containers
15
+ */
16
+ class ContainerExceptionTest extends TestCase
17
+ {
18
+ use ComponentMockeryTrait;
19
+
20
+ /**
21
+ * Creates a new instance of the test subject.
22
+ *
23
+ * @param array $dependencies A list of constructor args.
24
+ * @param array|null $methods The names of methods to mock in the subject.
25
+ * @return MockObject|TestSubject The new instance.
26
+ * @throws Exception If problem creating.
27
+ */
28
+ protected function createSubject(array $dependencies, $methods = null)
29
+ {
30
+ return $this->createMockBuilder(TestSubject::class, $methods, $dependencies)
31
+ ->getMock();
32
+ }
33
+
34
+ /**
35
+ * Tests that the instance is created correctly, and getters work as expected.`
36
+ *
37
+ * @throws Exception If problem testing.
38
+ */
39
+ public function testConstructorAndGetContainer()
40
+ {
41
+ {
42
+ $message = uniqid('message');
43
+ $code = rand(1, 99);
44
+ $prev = new Exception(uniqid('inner-message'));
45
+
46
+ $subject = $this->createSubject([$message, $code, $prev], null);
47
+ }
48
+
49
+ {
50
+ try {
51
+ throw $subject;
52
+ } catch (TestSubject $e) {
53
+ $this->assertSame($message, $e->getMessage(), 'Wrong message');
54
+ $this->assertSame($code, $e->getCode(), 'Wrong code');
55
+ $this->assertSame($prev, $e->getPrevious(), 'Wrong previous exception');
56
+ }
57
+ }
58
+ }
59
+
60
+ }
vendor/dhii/containers/tests/functional/Exception/NotFoundExceptionTest.php ADDED
@@ -0,0 +1,59 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php declare(strict_types = 1);
2
+
3
+ namespace Dhii\Container\FuncTest\Exception;
4
+
5
+ use Dhii\Container\Exception\NotFoundException as TestSubject;
6
+ use Dhii\Container\TestHelpers\ComponentMockeryTrait;
7
+ use Exception;
8
+ use PHPUnit\Framework\TestCase;
9
+ use PHPUnit\Framework\MockObject\MockObject;
10
+
11
+ /**
12
+ * Tests {@see TestSubject}.
13
+ *
14
+ * @package Dhii\Wp\Containers
15
+ */
16
+ class NotFoundExceptionTest extends TestCase
17
+ {
18
+ use ComponentMockeryTrait;
19
+
20
+ /**
21
+ * Creates a new instance of the test subject.
22
+ *
23
+ * @param array $dependencies A list of constructor args.
24
+ * @return MockObject|TestSubject The new instance.
25
+ * @throws Exception If problem creating.
26
+ */
27
+ protected function createSubject(array $dependencies, array $methods = null)
28
+ {
29
+ return $this->createMockBuilder(TestSubject::class, $methods, $dependencies)
30
+ ->getMock();
31
+ }
32
+
33
+ /**
34
+ * Tests that the instance is created correctly, and getters work as expected.`
35
+ *
36
+ * @throws Exception If problem testing.
37
+ */
38
+ public function testConstructorAndGetContainerAndDataKey()
39
+ {
40
+ {
41
+ $message = uniqid('message');
42
+ $code = rand(1, 99);
43
+ $prev = new Exception(uniqid('inner-message'));
44
+
45
+ $subject = $this->createSubject([$message, $code, $prev], null);
46
+ }
47
+
48
+ {
49
+ try {
50
+ throw $subject;
51
+ } catch (TestSubject $e) {
52
+ $this->assertSame($message, $e->getMessage(), 'Wrong message');
53
+ $this->assertSame($code, $e->getCode(), 'Wrong code');
54
+ $this->assertSame($prev, $e->getPrevious(), 'Wrong previous exception');
55
+ }
56
+ }
57
+ }
58
+
59
+ }
vendor/dhii/containers/tests/functional/FlashContainerTest.php ADDED
@@ -0,0 +1,124 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Dhii\Container\FuncTest;
4
+
5
+ use Dhii\Collection\MutableContainerInterface;
6
+ use Dhii\Container\FlashContainer as Subject;
7
+ use PHPUnit\Framework\MockObject\MockObject;
8
+ use PHPUnit\Framework\TestCase;
9
+
10
+ class FlashContainerTest extends TestCase
11
+ {
12
+ /**
13
+ * Creates a new instance of the test subject.
14
+ *
15
+ * @param MutableContainerInterface $storage
16
+ * @param string $key
17
+ *
18
+ * @return MockObject&Subject The new instance.
19
+ */
20
+ protected function createSubject(MutableContainerInterface $storage, string $key)
21
+ {
22
+ $mock = $this->getMockBuilder(Subject::class)
23
+ ->enableProxyingToOriginalMethods()
24
+ ->enableOriginalConstructor()
25
+ ->setConstructorArgs([$storage, $key])
26
+ ->getMock();
27
+
28
+ return $mock;
29
+ }
30
+
31
+ /**
32
+ * @return MockObject&MutableContainerInterface
33
+ */
34
+ protected function createStorage(array $data): MutableContainerInterface
35
+ {
36
+ $mock = $this->getMockBuilder(MutableContainerInterface::class)
37
+ ->setMethods(['has', 'get', 'set', 'unset'])
38
+ ->getMockForAbstractClass();
39
+
40
+ $mock->data = $data;
41
+
42
+ $mock->method('has')
43
+ ->with($this->isType('string'))
44
+ ->will($this->returnCallback(function (string $key) use ($mock) {
45
+ return array_key_exists($key, $mock->data);
46
+ }));
47
+ $mock->method('get')
48
+ ->with($this->isType('string'))
49
+ ->will($this->returnCallback(function (string $key) use ($mock) {
50
+ return array_key_exists($key, $mock->data)
51
+ ? $mock->data[$key]
52
+ : null;
53
+ }));
54
+ $mock->method('set')
55
+ ->with($this->isType('string'), $this->anything())
56
+ ->will($this->returnCallback(function (string $key, $value) use ($mock) {
57
+ $mock->data[$key] = $value;
58
+ }));
59
+ $mock->method('unset')
60
+ ->with($this->isType('string'))
61
+ ->will($this->returnCallback(function (string $key) use ($mock) {
62
+ if (array_key_exists($key, $mock->data)) {
63
+ unset($mock->data[$key]);
64
+ }
65
+ }));
66
+
67
+ return $mock;
68
+ }
69
+
70
+ /**
71
+ * Tests that flash data operations work correctly, and only affect the designated key of the storage.
72
+ *
73
+ * @return Subject
74
+ */
75
+ public function testCrud(): Subject
76
+ {
77
+ {
78
+ $key1 = uniqid('key1');
79
+ $val1 = uniqid('val1');
80
+ $key2 = uniqid('key2');
81
+ $val2 = uniqid('val2');
82
+ $initialFlashData = [$key1 => $val1];
83
+ $otherStorageKey = uniqid('other-storage-key');
84
+ $otherStorageValue = uniqid('other-storage-value');
85
+ $storageKey = uniqid('storage-key');
86
+ $storage = $this->createStorage([
87
+ $storageKey => $initialFlashData,
88
+ $otherStorageKey => $otherStorageValue,
89
+ ]);
90
+ $subject = $this->createSubject($storage, $storageKey);
91
+ }
92
+
93
+ {
94
+ // Initialization
95
+ $this->assertEquals($initialFlashData, $storage->get($storageKey), 'Initial flash data not set in storage');
96
+ $this->assertFalse($subject->has($key1), 'Flash data available before initialization');
97
+ $subject->init();
98
+ $this->assertEquals([], $storage->get($storageKey), 'Flash data not cleared from storage');
99
+
100
+ // Retrieval
101
+ $this->assertEquals($val1, $subject->get($key1));
102
+
103
+ // Writing
104
+ $subject->set($key2, $val2);
105
+ $this->assertEquals($val2, $subject->get($key2), 'Flash value not set correctly');
106
+ $this->assertEquals(array_merge($initialFlashData, [$key2 => $val2]), $storage->get($storageKey), 'Flash value not persisted correctly');
107
+
108
+ // Deleting
109
+ $subject->unset($key1);
110
+ $this->assertFalse($subject->has($key1), 'Flash value not unset correctly');
111
+ $this->assertEquals([$key2 => $val2], $storage->get($storageKey), 'Flash value removal not persisted correctly');
112
+
113
+ // Clearing
114
+ $subject->clear();
115
+ $this->assertFalse($subject->has($key2), 'Flash data was not cleared correctly');
116
+ $this->assertEquals([], $storage->get($storageKey), 'Flash data clearing not persisted correctly');
117
+
118
+ // Isolation
119
+ $this->assertEquals($otherStorageValue, $storage->get($otherStorageKey), 'Other storage values affected by flash data');
120
+ }
121
+
122
+ return $subject;
123
+ }
124
+ }
vendor/dhii/containers/tests/functional/HierarchyContainerTest.php ADDED
@@ -0,0 +1,158 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Dhii\Container\FuncTest;
4
+
5
+ use Dhii\Container\HierarchyContainer;
6
+ use Psr\Container\NotFoundExceptionInterface;
7
+ use PHPUnit\Framework\TestCase;
8
+
9
+ /**
10
+ * @since [*next-version*]
11
+ */
12
+ class HierarchyContainerTest extends TestCase
13
+ {
14
+ /**
15
+ * @since [*next-version*]
16
+ */
17
+ public function testCreateSubContainer()
18
+ {
19
+ $container = new HierarchyContainer([
20
+ 'config' => []
21
+ ]);
22
+
23
+ $result = $container->get('config');
24
+
25
+ static::assertInstanceOf(HierarchyContainer::class, $result);
26
+ }
27
+
28
+ /**
29
+ * @since [*next-version*]
30
+ */
31
+ public function testGetValue()
32
+ {
33
+ $container = new HierarchyContainer([
34
+ 'config' => ($expected = uniqid()),
35
+ ]);
36
+
37
+ $actual = $container->get('config');
38
+
39
+ static::assertEquals($expected, $actual);
40
+ }
41
+
42
+ /**
43
+ * @since [*next-version*]
44
+ */
45
+ public function testDeepGet()
46
+ {
47
+ $container = new HierarchyContainer([
48
+ 'config' => [
49
+ 'db' => [
50
+ 'host' => ($expected = uniqid()),
51
+ ],
52
+ ],
53
+ ]);
54
+
55
+ $result = $container->get('config')->get('db')->get('host');
56
+
57
+ static::assertEquals($expected, $result);
58
+ }
59
+
60
+ /**
61
+ * @since [*next-version*]
62
+ */
63
+ public function testNotFound()
64
+ {
65
+ $this->expectException(NotFoundExceptionInterface::class);
66
+
67
+ $container = new HierarchyContainer([
68
+ 'key' => 'value',
69
+ ]);
70
+
71
+ $container->get('not_exists');
72
+ }
73
+
74
+ /**
75
+ * @since [*next-version*]
76
+ */
77
+ public function testDeepNotFound()
78
+ {
79
+ $this->expectException(NotFoundExceptionInterface::class);
80
+
81
+ $container = new HierarchyContainer([
82
+ 'config' => [
83
+ 'db' => [
84
+ 'host' => 'localhost',
85
+ 'port' => 3306,
86
+ ],
87
+ ],
88
+ ]);
89
+
90
+ $container->get('config')->get('db')->get('not_exists');
91
+ }
92
+
93
+ /**
94
+ * @since [*next-version*]
95
+ */
96
+ public function testHasTrue()
97
+ {
98
+ $container = new HierarchyContainer([
99
+ 'key' => 'value',
100
+ ]);
101
+
102
+ $result = $container->has('key');
103
+
104
+ static::assertTrue($result);
105
+ }
106
+
107
+ /**
108
+ * @since [*next-version*]
109
+ */
110
+ public function testHasFalse()
111
+ {
112
+ $container = new HierarchyContainer([
113
+ 'key' => 'value',
114
+ ]);
115
+
116
+ $result = $container->has('not_exists');
117
+
118
+ static::assertFalse($result);
119
+ }
120
+
121
+ /**
122
+ * @since [*next-version*]
123
+ */
124
+ public function testDeepHasTrue()
125
+ {
126
+ $container = new HierarchyContainer([
127
+ 'config' => [
128
+ 'db' => [
129
+ 'host' => 'localhost',
130
+ 'port' => 3306
131
+ ]
132
+ ],
133
+ ]);
134
+
135
+ $result = $container->get('config')->get('db')->has('port');
136
+
137
+ static::assertTrue($result);
138
+ }
139
+
140
+ /**
141
+ * @since [*next-version*]
142
+ */
143
+ public function testDeepHasFalse()
144
+ {
145
+ $container = new HierarchyContainer([
146
+ 'config' => [
147
+ 'db' => [
148
+ 'host' => 'localhost',
149
+ 'port' => 3306
150
+ ]
151
+ ],
152
+ ]);
153
+
154
+ $result = $container->get('config')->get('db')->has('not_exists');
155
+
156
+ static::assertFalse($result);
157
+ }
158
+ }
vendor/dhii/containers/tests/functional/MappingContainerTest.php ADDED
@@ -0,0 +1,125 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Dhii\Container\FuncTest;
4
+
5
+ use Dhii\Container\MappingContainer;
6
+ use Dhii\Container\TestHelpers\ContainerMock;
7
+ use Psr\Container\NotFoundExceptionInterface;
8
+ use Exception;
9
+ use PHPUnit\Framework\TestCase;
10
+ use function uniqid;
11
+
12
+ class MappingContainerTest extends TestCase
13
+ {
14
+ /**
15
+ * Tests that the subject correctly invokes the callback with the inner container's result, and returns the
16
+ * callback's result.
17
+ *
18
+ * @since [*next-version*]
19
+ *
20
+ * @throws Exception
21
+ */
22
+ public function testGet()
23
+ {
24
+ $key = uniqid('key');
25
+ $value = uniqid('value');
26
+ $inner = ContainerMock::create($this)->expectHasService($key, $value);
27
+
28
+ $newValue = uniqid('new-value');
29
+ $cc = null; // This will record the container that was given as the $c arg in the callback
30
+ $callback = function ($v, $k, $c) use ($value, $key, &$cc, $newValue) {
31
+ $this->assertEquals($v, $value, 'Wrong value');
32
+ $this->assertEquals($k, $key, 'Wrong key');
33
+
34
+ $cc = $c;
35
+
36
+ return $newValue;
37
+ };
38
+
39
+ $subject = new MappingContainer($inner, $callback);
40
+
41
+ $result = $subject->get($key);
42
+
43
+ $this->assertEquals($newValue, $result, 'Wrong result retrieved');
44
+ $this->assertSame($subject, $cc, 'Wrong container passed as 3rd arg to callback');
45
+ }
46
+
47
+ /**
48
+ * Tests that the subject correctly throws when the inner container does not have an entry, skipping the
49
+ * callback's invocation.
50
+ *
51
+ * @since [*next-version*]
52
+ *
53
+ * @throws Exception
54
+ */
55
+ public function testGetNotFound()
56
+ {
57
+ $key = uniqid('key');
58
+ $inner = ContainerMock::create($this)->expectNotHasService($key);
59
+
60
+ $callback = function () {
61
+ $this->fail('Callback should not have been invoked');
62
+ };
63
+
64
+ $subject = new MappingContainer($inner, $callback);
65
+
66
+ try {
67
+ $subject->get($key);
68
+
69
+ $this->fail('Container did not throw a NotFoundExceptionInterface');
70
+ } catch (Exception $exception) {
71
+ $this->assertInstanceOf(
72
+ NotFoundExceptionInterface::class,
73
+ $exception,
74
+ 'Exception does not implement correct interface'
75
+ );
76
+ }
77
+ }
78
+
79
+ /**
80
+ * Tests that the subject correctly reports whether it has a key or not in the same way the inner container does.
81
+ *
82
+ * @since [*next-version*]
83
+ *
84
+ * @throws Exception
85
+ */
86
+ public function testHasTrue()
87
+ {
88
+ $key = uniqid('key');
89
+ $value = uniqid('value');
90
+ $inner = ContainerMock::create($this)->expectHasService($key, $value);
91
+
92
+ $callback = function () {
93
+ $this->fail('Callback should not have been invoked');
94
+ };
95
+ $subject = new MappingContainer($inner, $callback);
96
+
97
+ $expected = $inner->has($key);
98
+ $result = $subject->has($key);
99
+
100
+ $this->assertEquals($expected, $result, 'Wrong result retrieved');
101
+ }
102
+
103
+ /**
104
+ * Tests that the subject correctly reports whether it has a key or not in the same way the inner container does.
105
+ *
106
+ * @since [*next-version*]
107
+ *
108
+ * @throws Exception
109
+ */
110
+ public function testHasFalse()
111
+ {
112
+ $key = uniqid('key');
113
+ $inner = ContainerMock::create($this)->expectNotHasService($key);
114
+
115
+ $callback = function ($v) {
116
+ $this->fail('Callback should not have been invoked');
117
+ };
118
+ $subject = new MappingContainer($inner, $callback);
119
+
120
+ $expected = $inner->has($key);
121
+ $result = $subject->has($key);
122
+
123
+ $this->assertEquals($expected, $result, 'Wrong result retrieved');
124
+ }
125
+ }
vendor/dhii/containers/tests/functional/MaskingContainerTest.php ADDED
@@ -0,0 +1,187 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Dhii\Container\FuncTest;
4
+
5
+ use Dhii\Container\Exception\NotFoundException;
6
+ use Dhii\Container\MaskingContainer;
7
+ use Dhii\Container\TestHelpers\ContainerMock;
8
+ use Exception;
9
+ use PHPUnit\Framework\TestCase;
10
+ use function uniqid;
11
+
12
+ class MaskingContainerTest extends TestCase
13
+ {
14
+ /**
15
+ * Tests that the subject is able to retrieve an exposed entry from the inner container.
16
+ *
17
+ * @throws Exception If problem testing.
18
+ */
19
+ public function testGetExposed()
20
+ {
21
+ $serviceKey = uniqid('service-key');
22
+ $serviceVal = uniqid('service-val');
23
+ $inner = ContainerMock::create($this)->expectHasService($serviceKey, $serviceVal);
24
+
25
+ $mask = [
26
+ $serviceKey => true
27
+ ];
28
+ $subject = new MaskingContainer($inner, false, $mask);
29
+
30
+ $result = $subject->get($serviceKey);
31
+
32
+ $this->assertSame($serviceVal, $result, 'Wrong result retrieved');
33
+ }
34
+
35
+ /**
36
+ * Tests that the subject is unable to retrieve a masked entry from the inner container.
37
+ *
38
+ * @throws Exception If problem testing.
39
+ */
40
+ public function testGetMasked()
41
+ {
42
+ $serviceKey = uniqid('service-key');
43
+ $serviceVal = uniqid('service-val');
44
+ $inner = ContainerMock::create($this)->expectHasService($serviceKey, $serviceVal);
45
+
46
+ $mask = [
47
+ $serviceKey => false
48
+ ];
49
+ $subject = new MaskingContainer($inner, true, $mask);
50
+
51
+ try {
52
+ $subject->get($serviceKey);
53
+
54
+ $this->fail('Subject did not throw an exception');
55
+ } catch (NotFoundException $exception) {
56
+ $this->assertTrue(true);
57
+ }
58
+ }
59
+
60
+ /**
61
+ * Tests that the subject is able to retrieve an entry, that is implicitly exposed via the default mask, from the
62
+ * inner container.
63
+ *
64
+ * @throws Exception If problem testing.
65
+ */
66
+ public function testGetExposedDefault()
67
+ {
68
+ $serviceKey = uniqid('service-key');
69
+ $serviceVal = uniqid('service-val');
70
+ $inner = ContainerMock::create($this)->expectHasService($serviceKey, $serviceVal);
71
+
72
+ $mask = [];
73
+ $subject = new MaskingContainer($inner, true, $mask);
74
+
75
+ $result = $subject->get($serviceKey);
76
+
77
+ $this->assertSame($serviceVal, $result, 'Wrong result retrieved');
78
+ }
79
+
80
+ /**
81
+ * Tests that the subject is unable to retrieve an entry, that is implicitly masked via the default mask, from the
82
+ * inner container.
83
+ *
84
+ * @throws Exception If problem testing.
85
+ */
86
+ public function testGetMaskedDefault()
87
+ {
88
+ $serviceKey = uniqid('service-key');
89
+ $serviceVal = uniqid('service-val');
90
+ $inner = ContainerMock::create($this)->expectHasService($serviceKey, $serviceVal);
91
+
92
+ $mask = [
93
+ $serviceKey => false
94
+ ];
95
+ $subject = new MaskingContainer($inner, true, $mask);
96
+
97
+ try {
98
+ $subject->get($serviceKey);
99
+
100
+ $this->fail('Subject did not throw an exception');
101
+ } catch (NotFoundException $exception) {
102
+ $this->assertTrue(true);
103
+ }
104
+ }
105
+
106
+ /**
107
+ * Tests that the subject is able to look up an exposed entry in the inner container.
108
+ *
109
+ * @throws Exception If problem testing.
110
+ */
111
+ public function testHasExposed()
112
+ {
113
+ $serviceKey = uniqid('service-key');
114
+ $serviceVal = uniqid('service-val');
115
+ $inner = ContainerMock::create($this)->expectHasService($serviceKey, $serviceVal);
116
+
117
+ $mask = [
118
+ $serviceKey => true
119
+ ];
120
+ $subject = new MaskingContainer($inner, false, $mask);
121
+
122
+ $result = $subject->has($serviceKey);
123
+
124
+ $this->assertTrue($result);
125
+ }
126
+
127
+ /**
128
+ * Tests that the subject is unable to look up a masked entry in the inner container.
129
+ *
130
+ * @throws Exception If problem testing.
131
+ */
132
+ public function testHasMasked()
133
+ {
134
+ $serviceKey = uniqid('service-key');
135
+ $serviceVal = uniqid('service-val');
136
+ $inner = ContainerMock::create($this)->expectHasService($serviceKey, $serviceVal);
137
+
138
+ $mask = [
139
+ $serviceKey => false
140
+ ];
141
+ $subject = new MaskingContainer($inner, true, $mask);
142
+
143
+ $result = $subject->has($serviceKey);
144
+
145
+ $this->assertFalse($result);
146
+ }
147
+
148
+ /**
149
+ * Tests that the subject is unable to look up a non-existing exposed entry in the inner container.
150
+ *
151
+ * @throws Exception If problem testing.
152
+ */
153
+ public function testHasExposedFalse()
154
+ {
155
+ $serviceKey = uniqid('service-key');
156
+ $inner = ContainerMock::create($this)->expectNotHasService($serviceKey);
157
+
158
+ $mask = [
159
+ $serviceKey => true
160
+ ];
161
+ $subject = new MaskingContainer($inner, false, $mask);
162
+
163
+ $result = $subject->has($serviceKey);
164
+
165
+ $this->assertFalse($result);
166
+ }
167
+
168
+ /**
169
+ * Tests that the subject is unable to look up a non-existing masked entry in the inner container.
170
+ *
171
+ * @throws Exception If problem testing.
172
+ */
173
+ public function testHasMaskedFalse()
174
+ {
175
+ $serviceKey = uniqid('service-key');
176
+ $inner = ContainerMock::create($this)->expectNotHasService($serviceKey);
177
+
178
+ $mask = [
179
+ $serviceKey => false
180
+ ];
181
+ $subject = new MaskingContainer($inner, true, $mask);
182
+
183
+ $result = $subject->has($serviceKey);
184
+
185
+ $this->assertFalse($result);
186
+ }
187
+ }
vendor/dhii/containers/tests/functional/NoOpContainerTest.php ADDED
@@ -0,0 +1,60 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Dhii\Container\FuncTest;
4
+
5
+ use Dhii\Container\NoOpContainer as Subject;
6
+ use PHPUnit\Framework\MockObject\MockObject;
7
+ use PHPUnit\Framework\TestCase;
8
+ use Psr\Container\ContainerExceptionInterface;
9
+ use Psr\Container\NotFoundExceptionInterface;
10
+
11
+ class NoOpContainerTest extends TestCase
12
+ {
13
+ /**
14
+ * @return MockObject&Subject
15
+ */
16
+ protected function createSubject()
17
+ {
18
+ $mock = $this->getMockBuilder(Subject::class)
19
+ ->enableProxyingToOriginalMethods()
20
+ ->getMock();
21
+
22
+ return $mock;
23
+ }
24
+
25
+ public function testMembers()
26
+ {
27
+ {
28
+ $key = uniqid('key');
29
+ $subject = $this->createSubject();
30
+ }
31
+
32
+ {
33
+ $subject->set($key, uniqid('value'));
34
+ $this->assertFalse($subject->has($key));
35
+
36
+ $this->expectException(NotFoundExceptionInterface::class);
37
+ $subject->get($key);
38
+ $this->expectException(null);
39
+
40
+ $this->expectException(ContainerExceptionInterface::class);
41
+ $subject->unset($key);
42
+ $this->expectException(null);
43
+
44
+ $subject->clear();
45
+
46
+ $clone1 = $subject->withoutKeys([$key]);
47
+ $this->assertNotSame($subject, $clone1);
48
+
49
+ $clone2 = $subject->withAddedMappings([$key => uniqid('value2')]);
50
+ $this->assertNotSame($subject, $clone2);
51
+ $this->assertFalse($clone2->has($key));
52
+
53
+ $clone3 = $subject->withMappings([$key => uniqid('value3')]);
54
+ $this->assertNotSame($subject, $clone3);
55
+ $this->assertFalse($clone3->has($key));
56
+
57
+ $this->assertEquals([], iterator_to_array($subject));
58
+ }
59
+ }
60
+ }
vendor/dhii/containers/tests/functional/PathContainerTest.php ADDED
@@ -0,0 +1,159 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Dhii\Container\FuncTest;
4
+
5
+ use Dhii\Container\PathContainer;
6
+ use Dhii\Container\TestHelpers\ContainerMock;
7
+ use PHPUnit\Framework\TestCase;
8
+ use Psr\Container\NotFoundExceptionInterface;
9
+
10
+ /**
11
+ * @since [*next-version*]
12
+ */
13
+ class PathContainerTest extends TestCase
14
+ {
15
+ /**
16
+ * @since [*next-version*]
17
+ */
18
+ public function testGet()
19
+ {
20
+ {
21
+ $key1 = 'lorem';
22
+ $key2 = 'ipsum';
23
+ $expected = 'dolor';
24
+ }
25
+ {
26
+ $inner2 = ContainerMock::create($this)->expectHasService($key2, $expected);
27
+ $inner1 = ContainerMock::create($this)->expectHasService($key1, $inner2);
28
+ }
29
+ {
30
+ $delimiter = '/';
31
+ $path = implode($delimiter, [$key1, $key2]);
32
+ }
33
+
34
+ $container = new PathContainer($inner1, $delimiter);
35
+ $actual = $container->get($path);
36
+
37
+ static::assertEquals($expected, $actual);
38
+ }
39
+
40
+ /**
41
+ * @since [*next-version*]
42
+ */
43
+ public function testNotFound()
44
+ {
45
+ $this->expectException(NotFoundExceptionInterface::class);
46
+
47
+ $key = 'lorem';
48
+ $inner = ContainerMock::create($this)->expectNotHasService($key);
49
+
50
+ $container = new PathContainer($inner);
51
+ $container->get($key);
52
+ }
53
+
54
+ /**
55
+ * @since [*next-version*]
56
+ */
57
+ public function testDeepNotFound()
58
+ {
59
+ $this->expectException(NotFoundExceptionInterface::class);
60
+
61
+ {
62
+ $key1 = 'lorem';
63
+ $key2 = 'ipsum';
64
+ }
65
+ {
66
+ $inner2 = ContainerMock::create($this)->expectNotHasService($key2);
67
+ $inner1 = ContainerMock::create($this)->expectHasService($key1, $inner2);
68
+ }
69
+ {
70
+ $delimiter = '/';
71
+ $path = implode($delimiter, [$key1, $key2]);
72
+ }
73
+
74
+ $container = new PathContainer($inner1, $delimiter);
75
+ $container->get($path);
76
+ }
77
+
78
+ /**
79
+ * @since [*next-version*]
80
+ */
81
+ public function testHasTrue()
82
+ {
83
+ {
84
+ $key = 'lorem';
85
+ $value = 'ipsum';
86
+ }
87
+ {
88
+ $inner = ContainerMock::create($this)->expectHasService($key, $value);
89
+ }
90
+
91
+ $container = new PathContainer($inner);
92
+ $result = $container->has($key);
93
+
94
+ static::assertTrue($result);
95
+ }
96
+
97
+ /**
98
+ * @since [*next-version*]
99
+ */
100
+ public function testHasFalse()
101
+ {
102
+ $key = 'lorem';
103
+ $inner = ContainerMock::create($this)->expectNotHasService($key);
104
+
105
+ $container = new PathContainer($inner);
106
+ $result = $container->has($key);
107
+
108
+ static::assertFalse($result);
109
+ }
110
+
111
+ /**
112
+ * @since [*next-version*]
113
+ */
114
+ public function testDeepHasTrue()
115
+ {
116
+ {
117
+ $key1 = 'lorem';
118
+ $key2 = 'ipsum';
119
+ $value = 'dolor';
120
+ }
121
+ {
122
+ $inner2 = ContainerMock::create($this)->expectHasService($key2, $value);
123
+ $inner1 = ContainerMock::create($this)->expectHasService($key1, $inner2);
124
+ }
125
+ {
126
+ $delimiter = '/';
127
+ $path = implode($delimiter, [$key1, $key2]);
128
+ }
129
+
130
+ $container = new PathContainer($inner1, $delimiter);
131
+ $result = $container->has($path);
132
+
133
+ static::assertTrue($result);
134
+ }
135
+
136
+ /**
137
+ * @since [*next-version*]
138
+ */
139
+ public function testDeepHasFalse()
140
+ {
141
+ {
142
+ $key1 = 'lorem';
143
+ $key2 = 'ipsum';
144
+ }
145
+ {
146
+ $inner2 = ContainerMock::create($this)->expectNotHasService($key2);
147
+ $inner1 = ContainerMock::create($this)->expectHasService($key1, $inner2);
148
+ }
149
+ {
150
+ $delimiter = '/';
151
+ $path = implode($delimiter, [$key1, $key2]);
152
+ }
153
+
154
+ $container = new PathContainer($inner1, $delimiter);
155
+ $result = $container->has($path);
156
+
157
+ static::assertFalse($result);
158
+ }
159
+ }
vendor/dhii/containers/tests/functional/PrefixingContainerTest.php ADDED
@@ -0,0 +1,335 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Dhii\Container\FuncTest;
4
+
5
+ use Dhii\Container\Exception\NotFoundException;
6
+ use Dhii\Container\PrefixingContainer;
7
+ use Dhii\Container\TestHelpers\ContainerMock;
8
+ use PHPUnit\Framework\TestCase;
9
+ use function uniqid;
10
+
11
+ /**
12
+ * Tests the prefixing container implementation.
13
+ *
14
+ * Tests with "Strict" in the method name test strict prefixing containers, while tests "Permissive" in the name test
15
+ * prefixing containers in non-strict mode.
16
+ *
17
+ * Tests with "NotExists" in the method name test scenarios where the key does not exist in the inner container.
18
+ *
19
+ * Tests with "NoPrefix" in the method name test scenarios where the inner container has the key but the callee does
20
+ * not prefix the key that is passed to the outer container.
21
+ *
22
+ * @since [*next-version*]
23
+ */
24
+ class PrefixingContainerTest extends TestCase
25
+ {
26
+ /**
27
+ * @since [*next-version*]
28
+ */
29
+ public function testGetStrict()
30
+ {
31
+ {
32
+ $prefix = uniqid('prefix');
33
+ $innerKey = uniqid('key');
34
+ $outerKey = $prefix . $innerKey;
35
+ }
36
+ {
37
+ $value = uniqid('value');
38
+ $inner = ContainerMock::create($this)->expectGet([
39
+ $innerKey => $value
40
+ ]);
41
+ }
42
+ {
43
+ $strict = true;
44
+ $subject = new PrefixingContainer($inner, $prefix, $strict);
45
+ }
46
+
47
+ // Fetching the prefixed key should return the value of the un-prefixed key from the inner container
48
+ $result = $subject->get($outerKey);
49
+
50
+ $this->assertSame($value, $result);
51
+ }
52
+
53
+ /**
54
+ * @since [*next-version*]
55
+ */
56
+ public function testGetPermissive()
57
+ {
58
+ {
59
+ $prefix = uniqid('prefix');
60
+ $innerKey = uniqid('key');
61
+ $outerKey = $prefix . $innerKey;
62
+ }
63
+ {
64
+ $value = uniqid('value');
65
+ $inner = ContainerMock::create($this)->expectGet([
66
+ $innerKey => $value
67
+ ]);
68
+ }
69
+ {
70
+ $strict = false;
71
+ $subject = new PrefixingContainer($inner, $prefix, $strict);
72
+ }
73
+
74
+ // Fetching the prefixed key should return the value of the un-prefixed key from the inner container
75
+ $result = $subject->get($outerKey);
76
+
77
+ $this->assertSame($value, $result);
78
+ }
79
+
80
+ /**
81
+ * @since [*next-version*]
82
+ */
83
+ public function testGetNotExistsStrict()
84
+ {
85
+ {
86
+ $prefix = uniqid('prefix');
87
+ $innerKey = uniqid('key');
88
+ $outerKey = $prefix . $innerKey;
89
+ }
90
+ {
91
+ $inner = ContainerMock::create($this)->expectGet([
92
+ $innerKey => new NotFoundException()
93
+ ]);
94
+ }
95
+ {
96
+ $strict = true;
97
+ $subject = new PrefixingContainer($inner, $prefix, $strict);
98
+ }
99
+
100
+ // Fetching the prefixed key should throw an exception
101
+ $this->expectException(NotFoundException::class);
102
+
103
+ $subject->get($outerKey);
104
+ }
105
+
106
+ /**
107
+ * @since [*next-version*]
108
+ */
109
+ public function testGetNotExistsPermissive()
110
+ {
111
+ {
112
+ $prefix = uniqid('prefix');
113
+ $innerKey = uniqid('key');
114
+ $outerKey = $prefix . $innerKey;
115
+ }
116
+ {
117
+ $inner = ContainerMock::create($this)->expectGet([
118
+ $innerKey => new NotFoundException(),
119
+ $outerKey => new NotFoundException(),
120
+ ]);
121
+ }
122
+ {
123
+ $strict = false;
124
+ $subject = new PrefixingContainer($inner, $prefix, $strict);
125
+ }
126
+
127
+ // Fetching the prefixed key should throw an exception
128
+ $this->expectException(NotFoundException::class);
129
+
130
+ $subject->get($outerKey);
131
+ }
132
+
133
+ /**
134
+ * @since [*next-version*]
135
+ */
136
+ public function testGetNoPrefixStrict()
137
+ {
138
+ {
139
+ $prefix = uniqid('prefix');
140
+ $innerKey = uniqid('key');
141
+ }
142
+ {
143
+ $inner = ContainerMock::create($this);
144
+ }
145
+ {
146
+ $strict = true;
147
+ $subject = new PrefixingContainer($inner, $prefix, $strict);
148
+ }
149
+
150
+ // Fetching the un-prefixed key should throw an exception without querying the inner container
151
+ $this->expectException(NotFoundException::class);
152
+
153
+ $subject->get($innerKey);
154
+ }
155
+
156
+ /**
157
+ * @since [*next-version*]
158
+ */
159
+ public function testGetNoPrefixPermissive()
160
+ {
161
+ {
162
+ $prefix = uniqid('prefix');
163
+ $innerKey = uniqid('key');
164
+ }
165
+ {
166
+ $value = uniqid('value');
167
+ $inner = ContainerMock::create($this)->expectGet([
168
+ $innerKey => $value,
169
+ ]);
170
+ }
171
+ {
172
+ // The outer container is a non-strict prefixing container
173
+ $strict = false;
174
+ $subject = new PrefixingContainer($inner, $prefix, $strict);
175
+ }
176
+
177
+ // Fetching the un-prefixed key should return the inner container's value for that key
178
+ $result = $subject->get($innerKey);
179
+
180
+ $this->assertSame($value, $result);
181
+ }
182
+
183
+ /**
184
+ * @since [*next-version*]
185
+ */
186
+ public function testHasTrueStrict()
187
+ {
188
+ {
189
+ $prefix = uniqid('prefix');
190
+ $innerKey = uniqid('key');
191
+ $outerKey = $prefix . $innerKey;
192
+ }
193
+ {
194
+ $value = uniqid('value');
195
+ $inner = ContainerMock::create($this)->expectGet([
196
+ $innerKey => $value,
197
+ ]);
198
+ }
199
+ {
200
+ $strict = true;
201
+ $subject = new PrefixingContainer($inner, $prefix, $strict);
202
+ }
203
+
204
+ $result = $subject->has($outerKey);
205
+
206
+ $this->assertTrue($result);
207
+ }
208
+
209
+ /**
210
+ * @since [*next-version*]
211
+ */
212
+ public function testHasTruePermissive()
213
+ {
214
+ {
215
+ $prefix = uniqid('prefix');
216
+ $innerKey = uniqid('key');
217
+ $outerKey = $prefix . $innerKey;
218
+ }
219
+ {
220
+ $value = uniqid('value');
221
+ $inner = ContainerMock::create($this)->expectGet([
222
+ $innerKey => $value,
223
+ ]);
224
+ }
225
+ {
226
+ $strict = false;
227
+ $subject = new PrefixingContainer($inner, $prefix, $strict);
228
+ }
229
+
230
+ $result = $subject->has($outerKey);
231
+
232
+ $this->assertTrue($result);
233
+ }
234
+
235
+ /**
236
+ * @since [*next-version*]
237
+ */
238
+ public function testHasFalseStrict()
239
+ {
240
+ {
241
+ $prefix = uniqid('prefix');
242
+ $innerKey = uniqid('key');
243
+ $outerKey = $prefix . $innerKey;
244
+ }
245
+ {
246
+ $inner = ContainerMock::create($this)->expectGet([
247
+ $innerKey => new NotFoundException(),
248
+ ]);
249
+ }
250
+ {
251
+ $strict = true;
252
+ $subject = new PrefixingContainer($inner, $prefix, $strict);
253
+ }
254
+
255
+ $result = $subject->has($outerKey);
256
+
257
+ $this->assertFalse($result);
258
+ }
259
+
260
+ /**
261
+ * @since [*next-version*]
262
+ */
263
+ public function testHasFalsePermissive()
264
+ {
265
+ {
266
+ $prefix = uniqid('prefix');
267
+ $innerKey = uniqid('key');
268
+ $outerKey = $prefix . $innerKey;
269
+ }
270
+ {
271
+ $inner = ContainerMock::create($this)->expectGet([
272
+ $innerKey => new NotFoundException(),
273
+ $outerKey => new NotFoundException(),
274
+ ]);
275
+ }
276
+ {
277
+ $strict = false;
278
+ $subject = new PrefixingContainer($inner, $prefix, $strict);
279
+ }
280
+
281
+ $result = $subject->has($outerKey);
282
+
283
+ $this->assertFalse($result);
284
+ }
285
+
286
+ /**
287
+ * @since [*next-version*]
288
+ */
289
+ public function testHasNoPrefixStrict()
290
+ {
291
+ {
292
+ $prefix = uniqid('prefix');
293
+ $innerKey = uniqid('key');
294
+ }
295
+ {
296
+ $value = uniqid('value');
297
+ $inner = ContainerMock::create($this)->expectGet([
298
+ $innerKey => $value,
299
+ ]);
300
+ }
301
+ {
302
+ $strict = true;
303
+ $subject = new PrefixingContainer($inner, $prefix, $strict);
304
+ }
305
+
306
+ $result = $subject->has($innerKey);
307
+
308
+ $this->assertFalse($result);
309
+ }
310
+
311
+ /**
312
+ * @since [*next-version*]
313
+ */
314
+ public function testHasNoPrefixPermissive()
315
+ {
316
+ {
317
+ $prefix = uniqid('prefix');
318
+ $innerKey = uniqid('key');
319
+ }
320
+ {
321
+ $value = uniqid('value');
322
+ $inner = ContainerMock::create($this)->expectGet([
323
+ $innerKey => $value,
324
+ ]);
325
+ }
326
+ {
327
+ $strict = false;
328
+ $subject = new PrefixingContainer($inner, $prefix, $strict);
329
+ }
330
+
331
+ $result = $subject->has($innerKey);
332
+
333
+ $this->assertTrue($result);
334
+ }
335
+ }
vendor/dhii/containers/tests/functional/SegmentingContainerTest.php ADDED
@@ -0,0 +1,162 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Dhii\Container\FuncTest;
4
+
5
+ use Dhii\Container\SegmentingContainer;
6
+ use Dhii\Container\TestHelpers\ContainerMock;
7
+ use Exception;
8
+ use PHPUnit\Framework\TestCase;
9
+ use Psr\Container\ContainerInterface;
10
+ use function uniqid;
11
+
12
+ class SegmentingContainerTest extends TestCase
13
+ {
14
+ /**
15
+ * Tests that the subject correctly returns intermediate containers when fetching non-existent keys.
16
+ *
17
+ * @since [*next-version*]
18
+ *
19
+ * @throws Exception
20
+ */
21
+ public function testGet()
22
+ {
23
+ $key = 'foo';
24
+ $value = uniqid('value');
25
+ $inner = ContainerMock::create($this)->expectHasService($key, $value);
26
+
27
+ $delimiter = '/';
28
+ $subject = new SegmentingContainer($inner, $delimiter);
29
+
30
+ $result = $subject->get('foo');
31
+ $this->assertEquals($value, $result);
32
+ }
33
+
34
+ /**
35
+ * Tests that the subject's results are containers that can themselves also return more containers.
36
+ *
37
+ * @since [*next-version*]
38
+ *
39
+ * @throws Exception
40
+ */
41
+ public function testGetDeep()
42
+ {
43
+ {
44
+ $delimiter = '/';
45
+ $path = [
46
+ 'lorem',
47
+ 'ipsum',
48
+ 'dolor',
49
+ ];
50
+ }
51
+ {
52
+ $key1 = $path[0];
53
+ $key2 = $key1 . $delimiter . $path[1];
54
+ $key3 = $key2 . $delimiter . $path[2];
55
+ $value = uniqid('value');
56
+ }
57
+
58
+ {
59
+ $inner = ContainerMock::create($this);
60
+ // Container only returns true for full path
61
+ $inner->method('has')
62
+ ->withConsecutive([$key1], [$key2], [$key3])
63
+ ->willReturnOnConsecutiveCalls(false, false, true);
64
+ // Container returns value for full path
65
+ $inner->method('get')->with($key3)->willReturn($value);
66
+ }
67
+
68
+ $subject = new SegmentingContainer($inner, $delimiter);
69
+
70
+ $c1 = $subject->get('lorem');
71
+ $this->assertInstanceOf(ContainerInterface::class, $c1);
72
+
73
+ $c2 = $c1->get('ipsum');
74
+ $this->assertInstanceOf(ContainerInterface::class, $c2);
75
+
76
+ $result3 = $c2->get('dolor');
77
+ $this->assertEquals($value, $result3, 'Wrong result value retrieved');
78
+ }
79
+
80
+ /**
81
+ * Tests that the subject can accept path-like keys to return deeper container.
82
+ *
83
+ * @since [*next-version*]
84
+ *
85
+ * @throws Exception
86
+ */
87
+ public function testGetPath()
88
+ {
89
+ {
90
+ $delimiter = '/';
91
+ $path = [
92
+ 'lorem',
93
+ 'ipsum',
94
+ 'dolor',
95
+ ];
96
+ }
97
+ {
98
+ $key1 = $path[0] . $delimiter . $path[1];
99
+ $key2 = $key1 . $delimiter . $path[2];
100
+ $value = uniqid('value');
101
+ }
102
+ {
103
+ $inner = ContainerMock::create($this);
104
+ // Container only returns true for full path
105
+ $inner->method('has')
106
+ ->withConsecutive([$key1], [$key2])
107
+ ->willReturnOnConsecutiveCalls(false, true);
108
+ // Container returns value for full path
109
+ $inner->method('get')->with($key2)->willReturn($value);
110
+ }
111
+
112
+ $delimiter = '/';
113
+ $subject = new SegmentingContainer($inner, $delimiter);
114
+
115
+ $c1 = $subject->get('lorem/ipsum');
116
+ $this->assertInstanceOf(ContainerInterface::class, $c1);
117
+
118
+ $result = $c1->get('dolor');
119
+ $this->assertEquals($value, $result, 'Wrong result value retrieved');
120
+ }
121
+
122
+ /**
123
+ * Tests that the subject correctly reports whether it has a key or not in the same way the inner container does.
124
+ *
125
+ * @since [*next-version*]
126
+ *
127
+ * @throws Exception
128
+ */
129
+ public function testHasTrue()
130
+ {
131
+ $key = uniqid('key');
132
+ $value = uniqid('value');
133
+ $inner = ContainerMock::create($this)->expectHasService($key, $value);
134
+
135
+ $subject = new SegmentingContainer($inner);
136
+
137
+ $expected = $inner->has($key);
138
+ $result = $subject->has($key);
139
+
140
+ $this->assertEquals($expected, $result, 'Wrong result retrieved');
141
+ }
142
+
143
+ /**
144
+ * Tests that the subject correctly reports whether it has a key or not in the same way the inner container does.
145
+ *
146
+ * @since [*next-version*]
147
+ *
148
+ * @throws Exception
149
+ */
150
+ public function testHasFalse()
151
+ {
152
+ $key = uniqid('key');
153
+ $inner = ContainerMock::create($this)->expectNotHasService($key);
154
+
155
+ $subject = new SegmentingContainer($inner);
156
+
157
+ $expected = $inner->has($key);
158
+ $result = $subject->has($key);
159
+
160
+ $this->assertEquals($expected, $result, 'Wrong result retrieved');
161
+ }
162
+ }
vendor/dhii/containers/tests/functional/ServiceProviderTest.php ADDED
@@ -0,0 +1,56 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Dhii\Container\FuncTest;
4
+
5
+ use Dhii\Container\ServiceProvider;
6
+ use Exception;
7
+ use PHPUnit\Framework\TestCase;
8
+
9
+ class ServiceProviderTest extends TestCase
10
+ {
11
+ /**
12
+ * Tests that the extensions passed are correctly retrieved.
13
+ *
14
+ * @throws Exception If problem testing.
15
+ */
16
+ public function testGetExtensions()
17
+ {
18
+ $extensions = [
19
+ 'one' => function () {},
20
+ 'two' => function () {},
21
+ ];
22
+ $subject = new ServiceProvider([], $extensions);
23
+
24
+ $this->assertEquals(
25
+ $extensions,
26
+ $subject->getExtensions(),
27
+ 'Wrong extensions retrieved',
28
+ 0.0,
29
+ 10,
30
+ true
31
+ );
32
+ }
33
+
34
+ /**
35
+ * Tests that the factories passed are correctly retrieved.
36
+ *
37
+ * @throws Exception If problem testing.
38
+ */
39
+ public function testGetFactories()
40
+ {
41
+ $factories = [
42
+ 'three' => function () {},
43
+ 'four' => function () {},
44
+ ];
45
+ $subject = new ServiceProvider($factories, []);
46
+
47
+ $this->assertEquals(
48
+ $factories,
49
+ $subject->getFactories(),
50
+ 'Wrong factories retrieved',
51
+ 0.0,
52
+ 10,
53
+ true
54
+ );
55
+ }
56
+ }
vendor/dhii/containers/tests/functional/SimpleCacheContainerTest.php ADDED
@@ -0,0 +1,101 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Dhii\Container\FuncTest;
4
+
5
+ use Dhii\Container\SimpleCacheContainer as Subject;
6
+ use PHPUnit\Framework\MockObject\MockObject;
7
+ use PHPUnit\Framework\TestCase;
8
+ use Psr\SimpleCache\CacheInterface;
9
+ use WildWolf\Psr16MemoryCache;
10
+
11
+ class SimpleCacheContainerTest extends TestCase
12
+ {
13
+ /**
14
+ * Creates a new instance of the test subject.
15
+ *
16
+ * @param CacheInterface $storage
17
+ * @param int $ttl
18
+ *
19
+ * @return MockObject&Subject The new instance.
20
+ */
21
+ protected function createSubject(CacheInterface $storage, int $ttl)
22
+ {
23
+ $mock = $this->getMockBuilder(Subject::class)
24
+ ->enableProxyingToOriginalMethods()
25
+ ->enableOriginalConstructor()
26
+ ->setConstructorArgs([$storage, $ttl])
27
+ ->getMock();
28
+
29
+ return $mock;
30
+ }
31
+
32
+ /**
33
+ * @return MockObject&CacheInterface
34
+ */
35
+ protected function createCache(): CacheInterface
36
+ {
37
+ $mock = $this->getMockBuilder(Psr16MemoryCache::class)
38
+ ->enableProxyingToOriginalMethods()
39
+ ->enableOriginalConstructor()
40
+ ->getMock();
41
+
42
+ return $mock;
43
+ }
44
+
45
+ public function testCrud(): Subject
46
+ {
47
+ {
48
+ $storage = $this->createCache();
49
+ $ttl = rand(1, 999);
50
+ $subject = $this->createSubject($storage, $ttl);
51
+ $key = uniqid('key');
52
+ $val = uniqid('val');
53
+ }
54
+
55
+ {
56
+ $this->assertFalse($subject->has($key));
57
+ $subject->set($key, $val);
58
+ $this->assertTrue($subject->has($key));
59
+
60
+ $this->assertEquals($val, $subject->get($key));
61
+
62
+ $subject->unset($key);
63
+ $this->assertFalse($subject->has($key));
64
+ }
65
+
66
+ return $subject;
67
+ }
68
+
69
+ public function testClear(): Subject
70
+ {
71
+ {
72
+ $storage = $this->createCache();
73
+ $ttl = rand(1, 999);
74
+ $subject = $this->createSubject($storage, $ttl);
75
+ $data = [
76
+ uniqid('key1') => uniqid('val1'),
77
+ uniqid('key2') => uniqid('val2'),
78
+ uniqid('key3') => uniqid('val3'),
79
+ ];
80
+ }
81
+
82
+ {
83
+ foreach ($data as $key => $value) {
84
+ $subject->set($key, $value);
85
+ }
86
+
87
+ foreach ($data as $key => $value) {
88
+ $this->assertTrue($subject->has($key));
89
+ $this->assertEquals($data[$key], $subject->get($key));
90
+ }
91
+
92
+ $subject->clear();
93
+
94
+ foreach ($data as $key => $value) {
95
+ $this->assertFalse($subject->has($key));
96
+ }
97
+
98
+ return $subject;
99
+ }
100
+ }
101
+ }
vendor/dhii/containers/tests/helpers/AbstractMockHelper.php ADDED
@@ -0,0 +1,70 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Dhii\Container\TestHelpers;
4
+
5
+ use PHPUnit\Framework\MockObject\Builder\InvocationMocker;
6
+ use PHPUnit\Framework\MockObject\Matcher\Invocation;
7
+ use PHPUnit\Framework\MockObject\MockObject;
8
+ use PHPUnit\Framework\TestCase;
9
+
10
+ /**
11
+ * Abstract mock helper class.
12
+ *
13
+ * Extend this class and implement {@link AbstractMockHelper::nameOfClassToMock()} to create a mock class.
14
+ *
15
+ * @since [*next-version*]
16
+ */
17
+ abstract class AbstractMockHelper
18
+ {
19
+ /**
20
+ * @var MockObject
21
+ */
22
+ protected $mock;
23
+
24
+ /**
25
+ * @since [*next-version*]
26
+ *
27
+ * @param TestCase $testCase
28
+ *
29
+ * @return static
30
+ */
31
+ public static function create(TestCase $testCase) {
32
+ $instance = new static();
33
+ $instance->mock = $testCase->getMockBuilder(static::nameOfClassToMock())->getMockForAbstractClass();
34
+
35
+ return $instance;
36
+ }
37
+
38
+ /**
39
+ * @since [*next-version*]
40
+ *
41
+ * @param Invocation $matcher
42
+ *
43
+ * @return InvocationMocker
44
+ */
45
+ public function expects(Invocation $matcher)
46
+ {
47
+ return $this->mock->expects($matcher);
48
+ }
49
+
50
+ /**
51
+ * @since [*next-version*]
52
+ *
53
+ * @param $constraint
54
+ *
55
+ * @return InvocationMocker
56
+ */
57
+ public function method($constraint)
58
+ {
59
+ return $this->mock->method($constraint);
60
+ }
61
+
62
+ /**
63
+ * Retrieves the name of the class to mock.
64
+ *
65
+ * @since [*next-version*]
66
+ *
67
+ * @return string
68
+ */
69
+ abstract static function nameOfClassToMock() : string;
70
+ }
vendor/dhii/containers/tests/helpers/ComponentMockeryTrait.php ADDED
@@ -0,0 +1,258 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+
4
+ namespace Dhii\Container\TestHelpers;
5
+
6
+ use Andrew\Proxy;
7
+ use Psr\Container\NotFoundExceptionInterface;
8
+ use Exception;
9
+ use Interop\Container\ServiceProviderInterface;
10
+ use PHPUnit\Framework\MockObject\MockBuilder;
11
+ use PHPUnit\Framework\MockObject\MockObject;
12
+ use Psr\Container\ContainerInterface;
13
+ use Throwable;
14
+
15
+ trait ComponentMockeryTrait
16
+ {
17
+ /**
18
+ * Creates a new instance of the test subject mock.
19
+ *
20
+ * @param string $className The name of the class to mock.
21
+ * @param array|null $methods The methods to mock.
22
+ * Use `null` to not mock anything. Use empty array to mock everything.
23
+ * @param array|null $dependencies The parameters for the subject constructor.
24
+ * Use `null` to disable the original constructor.
25
+ *
26
+ * @return MockBuilder The new builder.
27
+ *
28
+ * @throws Exception If problem creating.
29
+ */
30
+ protected function createMockBuilder(string $className, $methods = [], $dependencies = null)
31
+ {
32
+ $builder = $this->getMockBuilder($className);
33
+
34
+ $builder->setMethods($methods);
35
+
36
+ if ($dependencies !== null) {
37
+ $builder->enableOriginalConstructor();
38
+ $builder->setConstructorArgs($dependencies);
39
+ } else {
40
+ $builder->disableOriginalConstructor();
41
+ }
42
+
43
+ return $builder;
44
+ }
45
+
46
+ /**
47
+ * Creates a new abstract class that extends the specified class while implementing the specified interfaces.
48
+ *
49
+ * @param string $className Name of the class to extend.
50
+ * @param array $interfaceNames List of interface names to implement.
51
+ *
52
+ * @return string The name of the new class.
53
+ *
54
+ * @throws Exception If problem creating.
55
+ * @throws Throwable If problem running.
56
+ */
57
+ protected function createImplementingClass(
58
+ string $className,
59
+ array $interfaceNames = []
60
+ ) {
61
+ $newClassName = uniqid(sprintf('%1$s_', $className));
62
+ $implements = count($interfaceNames)
63
+ ? 'implements ' . implode(', ', $interfaceNames)
64
+ : '';
65
+ $class = <<<PHP
66
+ abstract class $newClassName extends $className $implements {}
67
+ PHP;
68
+ eval($class);
69
+
70
+ return $newClassName;
71
+ }
72
+
73
+ /**
74
+ * Creates a new Dhii Container - Not Found exception.
75
+ *
76
+ * @param string $message Error message.
77
+ * @param Throwable|null $previous Inner exception.
78
+ * @param ContainerInterface|null $container The container, if any.
79
+ * @param string|null $dataKey The data key, if any.
80
+ *
81
+ * @return MockObject|NotFoundExceptionInterface The new exception.
82
+ *
83
+ * @throws Exception If problem creating.
84
+ * @throws Throwable If problem running.
85
+ */
86
+ protected function createNotFoundException(
87
+ string $message,
88
+ Throwable $previous = null,
89
+ ContainerInterface $container = null,
90
+ string $dataKey = null
91
+ ) {
92
+ $eClass = $this->createImplementingClass('Exception', [NotFoundExceptionInterface::class]);
93
+ $e = $this->createMockBuilder(
94
+ $eClass,
95
+ ['getContainer', 'getDataKey'],
96
+ [
97
+ $message,
98
+ 0,
99
+ $previous,
100
+ ]
101
+ )->getMock();
102
+ $e->method('getContainer')
103
+ ->willReturn($container);
104
+ $e->method('getDataKey')
105
+ ->willReturn($dataKey);
106
+
107
+ return $e;
108
+ }
109
+
110
+ /**
111
+ * @return callable|MockObject
112
+ *
113
+ * @throws Exception If problem creating.
114
+ */
115
+ protected function createCallable(callable $callable): callable
116
+ {
117
+ static $className = null;
118
+
119
+ if (!$className) {
120
+ $className = uniqid('MockInvocable');
121
+ }
122
+
123
+ if (!interface_exists($className)) {
124
+ $class = <<<EOL
125
+ interface $className
126
+ {
127
+ public function __invoke();
128
+ }
129
+ EOL;
130
+ eval($class);
131
+ }
132
+
133
+ $mock = $this->getMockBuilder($className)
134
+ ->setMethods(['__invoke'])
135
+ ->getMock();
136
+
137
+ $mock->method('__invoke')
138
+ ->willReturnCallback($callable);
139
+
140
+ assert(is_callable($mock));
141
+
142
+ return $mock;
143
+ }
144
+
145
+ /**
146
+ * Creates a new mock container.
147
+ *
148
+ * @param array $services The map of service name to service value.
149
+ *
150
+ * @return ContainerInterface|MockObject
151
+ *
152
+ * @throws Exception If problem creating.
153
+ */
154
+ protected function createContainer(array $services = [])
155
+ {
156
+ $mock = $this->getMockBuilder(ContainerInterface::class)
157
+ ->setMethods(['has', 'get'])
158
+ ->getMock();
159
+ assert($mock instanceof ContainerInterface);
160
+
161
+ $mock->method('get')
162
+ ->willReturnCallback(function ($key) use ($services, $mock) {
163
+ if (!isset($services[$key])) {
164
+ throw $this->createNotFoundException(
165
+ sprintf('No entry found for key "%1$s"', $key),
166
+ null,
167
+ $mock,
168
+ $key
169
+ );
170
+
171
+ throw $e;
172
+ }
173
+
174
+ return $services[$key];
175
+ });
176
+
177
+ $mock->method('has')
178
+ ->willReturnCallback(function ($key) use ($services, $mock) {
179
+ if (!isset($services[$key])) {
180
+ return false;
181
+ }
182
+
183
+ return true;
184
+ });
185
+
186
+ return $mock;
187
+ }
188
+
189
+ protected function createServiceProvider(array $factories, array $extensions): ServiceProviderInterface
190
+ {
191
+ $provider = new class($factories, $extensions) implements ServiceProviderInterface {
192
+ /**
193
+ * @var array
194
+ */
195
+ protected $factories;
196
+ /**
197
+ * @var array
198
+ */
199
+ protected $extensions;
200
+
201
+ public function __construct(array $factories, array $extensions)
202
+ {
203
+ $this->factories = $factories;
204
+ $this->extensions = $extensions;
205
+ }
206
+
207
+ public function getFactories()
208
+ {
209
+ return $this->factories;
210
+ }
211
+
212
+ public function getExtensions()
213
+ {
214
+ return $this->extensions;
215
+ }
216
+ };
217
+
218
+ return $provider;
219
+ }
220
+
221
+ /**
222
+ * Creates an array.
223
+ *
224
+ * @param int $length The length of the array.
225
+ * @param callable $valueGenerator This generates the values. Called for each index.
226
+ * @param callable|null $keyGenerator This generates the keys. Called for each index.
227
+ * Default: a generator that returns the index. Useful for numeric arrays.
228
+ *
229
+ * @return array The array of specified length, with generated keys and values.
230
+ */
231
+ public function createArray(int $length, callable $valueGenerator, callable $keyGenerator = null)
232
+ {
233
+ $result = [];
234
+ $keyGenerator = $keyGenerator ?? function (int $index) {
235
+ return $index;
236
+ };
237
+
238
+ for ($i=0; $i<$length-1; $i++) {
239
+ $key = $keyGenerator($i);
240
+ $value = $valueGenerator($i);
241
+ $result[$key] = $value;
242
+ }
243
+
244
+ return $result;
245
+ }
246
+
247
+ /**
248
+ * Creates a proxy that allows public access to the object's protected members.
249
+ *
250
+ * @param object $object The object to proxy.
251
+ *
252
+ * @return Proxy the new proxy.
253
+ */
254
+ protected function proxy($object): Proxy
255
+ {
256
+ return new Proxy($object);
257
+ }
258
+ }
vendor/dhii/containers/tests/helpers/ContainerMock.php ADDED
@@ -0,0 +1,156 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Dhii\Container\TestHelpers;
4
+
5
+ use Dhii\Container\Exception\NotFoundException;
6
+ use PHPUnit\Framework\TestCase;
7
+ use Psr\Container\ContainerInterface;
8
+ use Psr\Container\NotFoundExceptionInterface;
9
+
10
+ /**
11
+ * Mock container implementation.
12
+ *
13
+ * @since [*next-version*]
14
+ */
15
+ class ContainerMock extends AbstractMockHelper implements ContainerInterface
16
+ {
17
+ /**
18
+ * Index of current expectation.
19
+ *
20
+ * @var int
21
+ */
22
+ protected $_expIdx = 0;
23
+
24
+ /**
25
+ * @inheritDoc
26
+ *
27
+ * @since [*next-version*]
28
+ */
29
+ public static function nameOfClassToMock() : string
30
+ {
31
+ return ContainerInterface::class;
32
+ }
33
+
34
+ /**
35
+ * @inheritDoc
36
+ *
37
+ * @since [*next-version*]
38
+ */
39
+ public function get($id)
40
+ {
41
+ return $this->mock->get($id);
42
+ }
43
+
44
+ /**
45
+ * @inheritDoc
46
+ *
47
+ * @since [*next-version*]
48
+ */
49
+ public function has($id)
50
+ {
51
+ return $this->mock->has($id);
52
+ }
53
+
54
+ /**
55
+ * Shorthand for expecting a service from the mock container.
56
+ *
57
+ * @since [*next-version*]
58
+ *
59
+ * @param string $key
60
+ * @param mixed $value
61
+ *
62
+ * @return static
63
+ */
64
+ public function expectHasService($key, $value)
65
+ {
66
+ $this->mock->method('get')
67
+ ->with($key)
68
+ ->willReturn($value);
69
+
70
+ $this->mock->method('has')
71
+ ->with($key)
72
+ ->willReturn(true);
73
+
74
+ return $this;
75
+ }
76
+
77
+ /**
78
+ * Shorthand for expecting a service to not exist in the mock container.
79
+ *
80
+ * @since [*next-version*]
81
+ *
82
+ * @param string $key
83
+ *
84
+ * @return static
85
+ */
86
+ public function expectNotHasService($key)
87
+ {
88
+ $this->mock->method('get')
89
+ ->with($key)
90
+ ->willThrowException(new NotFoundException("", 0, null, $this, $key));
91
+
92
+ $this->mock->method('has')
93
+ ->with($key)
94
+ ->willReturn(false);
95
+
96
+ return $this;
97
+ }
98
+
99
+ public function expectGet(array $expectations)
100
+ {
101
+ $keys = array_keys($expectations);
102
+ $values = array_values($expectations);
103
+
104
+ $args = array_map(function ($key) {
105
+ return [$key];
106
+ }, $keys);
107
+
108
+ $this->mock->method('get')
109
+ ->withConsecutive(...$args)
110
+ ->willReturnCallback(function ($arg) use ($keys, $values) {
111
+ static $idx = -1;
112
+ $idx++;
113
+
114
+ $key = $keys[$idx];
115
+ $val = $values[$idx];
116
+
117
+ if ($arg !== $key) {
118
+ TestCase::fail(
119
+ "Parameter 0 for invocation #${idx} ContainerInterface::get('{$arg}') does not match expected value '${key}'"
120
+ );
121
+
122
+ return null;
123
+ }
124
+
125
+ if ($val instanceof NotFoundExceptionInterface) {
126
+ throw new NotFoundException(
127
+ $val->getMessage(), $val->getCode(), $val->getPrevious(), $this, $arg
128
+ );
129
+ }
130
+
131
+ return $val;
132
+ });
133
+
134
+ $this->mock->method('has')
135
+ ->withConsecutive(...$args)
136
+ ->willReturnCallback(function ($arg) use ($keys, $values) {
137
+ static $idx = -1;
138
+ $idx++;
139
+
140
+ $key = $keys[$idx];
141
+ $val = $values[$idx];
142
+
143
+ if ($arg !== $key) {
144
+ TestCase::fail(
145
+ "Parameter 0 for invocation #${idx} ContainerInterface::has('{$arg}') does not match expected value '${key}'"
146
+ );
147
+
148
+ return null;
149
+ }
150
+
151
+ return !($val instanceof NotFoundExceptionInterface);
152
+ });
153
+
154
+ return $this;
155
+ }
156
+ }
vendor/dhii/containers/tests/helpers/InvocableMock.php ADDED
@@ -0,0 +1,99 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Dhii\Container\TestHelpers;
4
+
5
+ use PHPUnit\Framework\MockObject\Builder\InvocationMocker;
6
+ use PHPUnit\Framework\MockObject\Matcher\Invocation;
7
+ use PHPUnit\Framework\MockObject\Matcher\InvokedCount;
8
+ use PHPUnit\Framework\TestCase;
9
+
10
+ /**
11
+ * Mock invocable implementation.
12
+ *
13
+ * @since [*next-version*]
14
+ */
15
+ class InvocableMock extends AbstractMockHelper
16
+ {
17
+ /**
18
+ * @inheritDoc
19
+ *
20
+ * @since [*next-version*]
21
+ */
22
+ static function nameOfClassToMock() : string
23
+ {
24
+ return static::invocableInterface();
25
+ }
26
+
27
+ /**
28
+ * @inheritDoc
29
+ *
30
+ * @since [*next-version*]
31
+ *
32
+ * @param TestCase $testCase
33
+ * @param callable|null $function
34
+ *
35
+ * @return static
36
+ */
37
+ public static function create(TestCase $testCase, callable $function = null)
38
+ {
39
+ $instance = parent::create($testCase);
40
+
41
+ if ($function !== null) {
42
+ $instance->mock->method('__invoke')->willReturnCallback($function);
43
+ }
44
+
45
+ return $instance;
46
+ }
47
+
48
+ /**
49
+ * @since [*next-version*]
50
+ *
51
+ * @param mixed ...$args
52
+ *
53
+ * @return mixed
54
+ */
55
+ public function __invoke(...$args)
56
+ {
57
+ return $this->mock->__invoke(...$args);
58
+ }
59
+
60
+ /**
61
+ * Shorthand for expecting the invocable to be called.
62
+ *
63
+ * @since [*next-version*]
64
+ *
65
+ * @param Invocation|InvokedCount $matcher
66
+ *
67
+ * @return InvocationMocker
68
+ */
69
+ public function expectCalled($matcher) {
70
+ return $this->mock->expects($matcher)->method('__invoke');
71
+ }
72
+
73
+ /**
74
+ * Creates the invocable interface that is mocked by this class.
75
+ *
76
+ * @since [*next-version*]
77
+ *
78
+ * @return string
79
+ */
80
+ protected static function invocableInterface() {
81
+ static $className = null;
82
+
83
+ if (!$className) {
84
+ $className = uniqid('MockInvocable');
85
+ }
86
+
87
+ if (!interface_exists($className)) {
88
+ $class = <<<EOL
89
+ interface $className
90
+ {
91
+ public function __invoke();
92
+ }
93
+ EOL;
94
+ eval($class);
95
+ }
96
+
97
+ return $className;
98
+ }
99
+ }
vendor/dhii/containers/tests/helpers/ServiceProviderMock.php ADDED
@@ -0,0 +1,69 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Dhii\Container\TestHelpers;
4
+
5
+ use Interop\Container\ServiceProviderInterface;
6
+ use PHPUnit\Framework\TestCase;
7
+
8
+ /**
9
+ * Mock service provider implementation.
10
+ *
11
+ * @since [*next-version*]
12
+ */
13
+ class ServiceProviderMock extends AbstractMockHelper implements ServiceProviderInterface
14
+ {
15
+ /**
16
+ * @inheritDoc
17
+ *
18
+ * @since [*next-version*]
19
+ */
20
+ public static function nameOfClassToMock() : string
21
+ {
22
+ return ServiceProviderInterface::class;
23
+ }
24
+
25
+ /**
26
+ * @inheritDoc
27
+ *
28
+ * @since [*next-version*]
29
+ *
30
+ * @param array $factories
31
+ * @param array $extensions
32
+ *
33
+ * @return static
34
+ */
35
+ public static function create(TestCase $testCase, $factories = [], $extensions = [])
36
+ {
37
+ $instance = parent::create($testCase);
38
+
39
+ if ($factories !== null) {
40
+ $instance->mock->method('getFactories')->willReturn($factories);
41
+ }
42
+
43
+ if ($extensions !== null) {
44
+ $instance->mock->method('getExtensions')->willReturn($extensions);
45
+ }
46
+
47
+ return $instance;
48
+ }
49
+
50
+ /**
51
+ * @inheritDoc
52
+ *
53
+ * @since [*next-version*]
54
+ */
55
+ public function getFactories()
56
+ {
57
+ return $this->mock->getFactories();
58
+ }
59
+
60
+ /**
61
+ * @inheritDoc
62
+ *
63
+ * @since [*next-version*]
64
+ */
65
+ public function getExtensions()
66
+ {
67
+ return $this->mock->getExtensions();
68
+ }
69
+ }
vendor/dhii/containers/tests/system/MultipleAccessTypesWithMapsTest.php ADDED
@@ -0,0 +1,93 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Dhii\Container\SysTest;
4
+
5
+ use Psr\Container\ContainerInterface as PsrContainerInterface;
6
+ use Dhii\Container\DataStructureBasedFactory;
7
+ use Dhii\Container\DictionaryFactory;
8
+ use Dhii\Container\SegmentingContainer;
9
+ use PHPUnit\Framework\TestCase;
10
+
11
+ class MultipleAccessTypesWithMaps__ extends TestCase
12
+ {
13
+ const DEV_DB_HOST = 'localhost';
14
+ const STAGING_DB_HOST = '123.staging.myhost';
15
+
16
+ public function configDataProvider(): array
17
+ {
18
+ return [
19
+ [ // 1st set
20
+ [ // 1st param
21
+ 'dev' => [
22
+ 'db' => [
23
+ 'host' => self::DEV_DB_HOST,
24
+ 'user' => 'root',
25
+ 'password' => '',
26
+ 'database' => 'my_app',
27
+ ],
28
+ ],
29
+ ],
30
+ [ // 2nd param
31
+ 'staging/db/host' => self::STAGING_DB_HOST,
32
+ 'staging/db/user' => 'app123',
33
+ 'staging/db/password' => 'Ad#93rh39d!',
34
+ 'staging/db/database' => 'app123',
35
+ ],
36
+ ],
37
+ ];
38
+ }
39
+
40
+ /**
41
+ * Tests whether a structure where some keys are namespaced and some are hierarachical
42
+ * can be normalized into a hierarchy of containers.
43
+ *
44
+ * @dataProvider configDataProvider
45
+ */
46
+ public function testMixedKeyNamespacedToHierarchy(array $devData, $stagingData): PsrContainerInterface
47
+ {
48
+ {
49
+ $data = array_merge($devData, $stagingData);
50
+ $factory = new DataStructureBasedFactory(new DictionaryFactory());
51
+ $container = new SegmentingContainer($factory->createContainerFromArray($data), '/');
52
+ }
53
+
54
+ {
55
+ $this->assertEquals(self::STAGING_DB_HOST, $container->get('staging')->get('db')->get('host'));
56
+ $this->assertEquals(self::DEV_DB_HOST, $container->get('dev')->get('db')->get('host'));
57
+ }
58
+
59
+ return $container;
60
+ }
61
+
62
+ /**
63
+ * @dataProvider configDataProvider
64
+ */
65
+ public function testPreserveIterabilityInHierarchy(array $devData, array $stagingData)
66
+ {
67
+ {
68
+ $factory = new DataStructureBasedFactory(new DictionaryFactory());
69
+ $container = new SegmentingContainer($factory->createContainerFromArray($devData), '/');
70
+ }
71
+
72
+ {
73
+ $this->assertIsIterable($container->get('dev')->get('db'));
74
+ }
75
+ }
76
+
77
+ /**
78
+ * @dataProvider configDataProvider
79
+ */
80
+ public function testPreserveIterabilityInNamespaced(array $devData, array $stagingData)
81
+ {
82
+ {
83
+ $factory = new DataStructureBasedFactory(new DictionaryFactory());
84
+ $container = new SegmentingContainer($factory->createContainerFromArray($stagingData), '/');
85
+ }
86
+
87
+ {
88
+ $this->markTestIncomplete('This will fail, because the segmenting container is not iterable, ' .
89
+ 'and will return instances of itself for keys that are not found.');
90
+ $this->assertIsIterable($container->get('staging')->get('db'));
91
+ }
92
+ }
93
+ }
vendor/dhii/containers/tests/unit/CompositeCachingServiceProviderTest.php ADDED
@@ -0,0 +1,100 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Dhii\Container\UnitTest;
4
+
5
+ use Andrew\Proxy;
6
+ use Dhii\Container\CompositeCachingServiceProvider;
7
+ use Dhii\Container\TestHelpers\ContainerMock;
8
+ use Dhii\Container\TestHelpers\InvocableMock;
9
+ use Exception;
10
+ use PHPUnit\Framework\TestCase;
11
+
12
+ class CompositeCachingServiceProviderTest extends TestCase
13
+ {
14
+ /**
15
+ * Tests whether extensions get correctly merged.
16
+ *
17
+ * Extensions are merged correctly if new extensions are added "inside" old
18
+ * extensions, without overriding them, such that both the old and the
19
+ * new extensions get run, in that order, passing down the result of the old
20
+ * extension to the new.
21
+ *
22
+ * @throws Exception If problem testing.
23
+ */
24
+ public function testMergeExtensions()
25
+ {
26
+ {
27
+ $container = ContainerMock::create($this);
28
+ $prev1 = uniqid('prev1');
29
+ $prev2 = uniqid('prev2');
30
+ $prev3 = uniqid('prev3');
31
+ $prev4 = uniqid('prev3');
32
+ $func1 = InvocableMock::create($this, function () use ($prev1) {
33
+ return $prev1;
34
+ });
35
+ $func2 = InvocableMock::create($this, function () use ($prev2) {
36
+ return $prev2;
37
+ });
38
+ $func3 = InvocableMock::create($this, function () use ($prev3) {
39
+ return $prev3;
40
+ });
41
+ $func4 = InvocableMock::create($this, function () use ($prev4) {
42
+ return $prev4;
43
+ });
44
+
45
+ $defaults = [
46
+ 'one' => $func1,
47
+ 'two' => $func2,
48
+ ];
49
+
50
+ $extensions = [
51
+ 'two' => $func3,
52
+ 'three' => $func4,
53
+ ];
54
+
55
+ $subject = new CompositeCachingServiceProvider(['_mergeFactories']);
56
+ $_subject = new Proxy($subject);
57
+
58
+ $func1->expectCalled(static::once())->with($container, $prev1);
59
+ $func2->expectCalled(static::once())->with($container, $prev2);
60
+ $func3->expectCalled(static::once())->with($container, $prev2);
61
+ $func4->expectCalled(static::once())->with($container, $prev4);
62
+ }
63
+
64
+ {
65
+ $result = $_subject->mergeExtensions($defaults, $extensions);
66
+ }
67
+
68
+ {
69
+ // Checking structure of result
70
+ $this->assertCount(3, $result);
71
+ $this->assertArrayHasKey('one', $result);
72
+ $this->assertArrayHasKey('two', $result);
73
+ $this->assertArrayHasKey('three', $result);
74
+
75
+ // Checking first (simple) extension
76
+ $this->assertIsCallable($result['one']);
77
+ $this->assertEquals(
78
+ $prev1,
79
+ $result['one']($container, $prev1),
80
+ 'Simple extension must return passed value'
81
+ );
82
+
83
+ // Checking second (compound) extension
84
+ $this->assertIsCallable($result['two']);
85
+ $this->assertEquals(
86
+ $prev3,
87
+ $result['two']($container, $prev2),
88
+ 'Compound extension must return inner-most value'
89
+ );
90
+
91
+ // Checking third (simple) extension
92
+ $this->assertIsCallable($result['three']);
93
+ $this->assertEquals(
94
+ $prev4,
95
+ $result['three']($container, $prev4),
96
+ 'Simple extension must return passed value'
97
+ );
98
+ }
99
+ }
100
+ }
vendor/dhii/containers/tests/unit/ProxyContainerTest.php ADDED
@@ -0,0 +1,84 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Dhii\Container\UnitTest;
4
+
5
+ use Dhii\Container\ProxyContainer as TestSubject;
6
+ use Dhii\Container\TestHelpers\ComponentMockeryTrait;
7
+ use PHPUnit\Framework\MockObject\MockObject;
8
+ use PHPUnit\Framework\TestCase;
9
+ use Psr\Container\ContainerExceptionInterface;
10
+ use Psr\Container\NotFoundExceptionInterface;
11
+
12
+ class ProxyContainerTest extends TestCase
13
+ {
14
+ use ComponentMockeryTrait;
15
+
16
+ /**
17
+ * @return TestSubject&MockObject
18
+ */
19
+ protected function createInstance(): TestSubject
20
+ {
21
+ $mock = $this->getMockBuilder(TestSubject::class)
22
+ ->setMethods(null)
23
+ ->getMock();
24
+
25
+ return $mock;
26
+ }
27
+
28
+ /**
29
+ * Tests that calls and return values are being proxied correctly.
30
+ */
31
+ public function testProxy()
32
+ {
33
+ {
34
+ $nonExistingKey = uniqid('not-here');
35
+ $key = uniqid('key');
36
+ $value = uniqid('value');
37
+ $services = [
38
+ $key => $value,
39
+ ];
40
+ $container = $this->createContainer($services);
41
+ $subject = $this->createInstance();
42
+ }
43
+
44
+ {
45
+ $subject->setInnerContainer($container);
46
+ $this->assertTrue($subject->has($key));
47
+ $this->assertEquals($value, $subject->get($key));
48
+
49
+ $this->assertFalse($subject->has($nonExistingKey));
50
+ $this->expectException(NotFoundExceptionInterface::class);
51
+ $subject->get($nonExistingKey);
52
+ }
53
+ }
54
+
55
+ /**
56
+ * Tests that the subject reacts correctly when the inner container is missing.
57
+ */
58
+ public function testHasMissingContainer()
59
+ {
60
+ {
61
+ $subject = $this->createInstance();
62
+ }
63
+
64
+ {
65
+ $this->expectException(ContainerExceptionInterface::class);
66
+ $subject->has(uniqid('not-there'));
67
+ }
68
+ }
69
+
70
+ /**
71
+ * Tests that the subject reacts correctly when the inner container is missing.
72
+ */
73
+ public function testGetMissingContainer()
74
+ {
75
+ {
76
+ $subject = $this->createInstance();
77
+ }
78
+
79
+ {
80
+ $this->expectException(ContainerExceptionInterface::class);
81
+ $subject->get(uniqid('not-there'));
82
+ }
83
+ }
84
+ }
vendor/dhii/data-container-interface/CHANGELOG.md DELETED
@@ -1,38 +0,0 @@
1
- # Change log
2
- All notable changes to this project will be documented in this file.
3
-
4
- The format is based on [Keep a Changelog](http://keepachangelog.com/)
5
- and this project adheres to [Semantic Versioning](http://semver.org/).
6
-
7
- ## [[*next-version*]] - YYYY-MM-DD
8
-
9
- ## [0.2.1-alpha1] - 2019-05-10
10
- ### Added
11
- - `SetCapableContainerInterface`;
12
- - `DeleteCapableContainerInterface`.
13
- - `ClearCapableContainerInterface`.
14
-
15
- ## [0.2] - 2019-05-06
16
- Stable release. See alpha releases for changes.
17
-
18
- ## [0.2-alpha3] - 2018-04-26
19
- ### Added
20
- - `ContainerFactoryInterface`.
21
-
22
- ## [0.2-alpha2] - 2018-03-21
23
- ### Added
24
- - `ClearCapableInterface`.
25
-
26
- ## [0.2-alpha1] - 2018-03-21
27
- ### Added
28
- - `SetCapableInterface`.
29
- - `DeleteCapableInterface.`.
30
-
31
- ### Changed
32
- - Exceptions now extend Dhii `ThrowableInterface`.
33
-
34
- ### Fixed
35
- - Usage of Dhii container interface instead of the PSR one.
36
-
37
- ## [0.1] - 2017-08-12
38
- Initial version.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/dhii/data-container-interface/LICENSE DELETED
@@ -1,19 +0,0 @@
1
- Copyright (c) 2017 Dhii
2
-
3
- Permission is hereby granted, free of charge, to any person obtaining a copy
4
- of this software and associated documentation files (the "Software"), to deal
5
- in the Software without restriction, including without limitation the rights
6
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
- copies of the Software, and to permit persons to whom the Software is
8
- furnished to do so, subject to the following conditions:
9
-
10
- The above copyright notice and this permission notice shall be included in all
11
- copies or substantial portions of the Software.
12
-
13
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19
- SOFTWARE.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/dhii/data-container-interface/README.md DELETED
@@ -1,79 +0,0 @@
1
- # Dhii - Data - Container - Interface
2
-
3
- [![Build Status](https://travis-ci.org/Dhii/data-container-interface.svg?branch=master)](https://travis-ci.org/Dhii/data-container-interface)
4
- [![Code Climate](https://codeclimate.com/github/Dhii/data-container-interface/badges/gpa.svg)](https://codeclimate.com/github/Dhii/data-container-interface)
5
- [![Test Coverage](https://codeclimate.com/github/Dhii/data-container-interface/badges/coverage.svg)](https://codeclimate.com/github/Dhii/data-container-interface/coverage)
6
- [![Latest Stable Version](https://poser.pugx.org/dhii/data-container-interface/version)](https://packagist.org/packages/dhii/data-container-interface)
7
- [![This package complies with Dhii standards](https://img.shields.io/badge/Dhii-Compliant-green.svg?style=flat-square)][Dhii]
8
-
9
- Interfaces for working with data containers.
10
-
11
- ## Details
12
- This package introduces a couple of completely new
13
- interfaces for granularity, and extends the exceptions interfaces to make them
14
- more useful, while still sticking to the spirit of PSR-11.
15
-
16
- Interfaces in this package extend those from [`psr/container`], the [PSR-11]
17
- repository, where applicable. As such, the container itself, as well as the
18
- exceptions, are compatible with PSR-11, in the sense that it's possible to pass
19
- instances of the respective interfaces from this package where PSR-11 interfaces
20
- are expected.
21
-
22
- At the same time, the interfaces of this package aim to be compatible with those of
23
- [PSR-16]. This means that theoretically, implementations of these interfaces should
24
- be usable as a cache storage - albeit, in the current state of PSR-16, with some
25
- adaptation. In theory, this should allow all data objects to be accessible in
26
- the same way, regardless of what they are used for.
27
-
28
- This package also supports [`dhii/stringable-interface`]: anything that expects
29
- or returns a string key can also accept or return a [`StringableInterface`]
30
- respectively, in addition to a `string`. However, this is optional, and there
31
- is no dependency on that package; implementations are responsible for requiring
32
- `dhii/stringable-interface` themselves.
33
-
34
- :book: Please see [Wiki] for detailed explanation.
35
-
36
- ### Interfaces
37
-
38
- - [`HasCapableInterface`] - Allows checking for existence of data value by key.
39
- - [`ContainerInterface`] - Allows checking for and retrieval of data value by key.
40
- - [`ContainerAwareInterface`] - Allows retrieval of a container instance.
41
- - [`SetCapableInterface`] - Allows setting the value for a key.
42
- - [`SetCapableContainerInterface`] - A container that can have a value set for a key.
43
- - [`DeleteCapableInterface`] - Allows deleting a value by key.
44
- - [`DeleteCapableContainerInterface`] - A container that allows deleting a value by key.
45
- - [`ClearCapableInterface`] - Allows deleting all values.
46
- - [`ClearCapableContainerInterface`] - A container that allows deleting all values.
47
- - [`ContainerFactoryInterface`] - A factory that can create containers.
48
- - [`ContainerExceptionInterface`] - An exception that occurs in relation to a container,
49
- and is aware of that container.
50
- - [`NotFoundExceptionInterface`] - An exception that occurs when attempting to
51
- retrieve data for key that is not set, and is also container aware by extension.
52
-
53
- ## Installation
54
- `composer require dhii/data-container-interface:^0.2`
55
-
56
-
57
-
58
- [Dhii]: https://github.com/Dhii/dhii
59
- [Wiki]: https://github.com/Dhii/data-container-interface/wiki
60
- [PSR-11]: https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-11-container.md
61
- [PSR-16]: https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-16-simple-cache.md
62
-
63
- [`psr/container`]: https://github.com/php-fig/container
64
- [`dhii/stringable-interface`]: https://github.com/Dhii/stringable-interface
65
-
66
- [`HasCapableInterface`]: ./src/HasCapableInterface.php
67
- [`ContainerInterface`]: ./src/ContainerInterface.php
68
- [`ContainerAwareInterface`]: ./src/ContainerAwareInterface.php
69
- [`SetCapableInterface`]: ./src/SetCapableInterface.php
70
- [`SetCapableContainerInterface`]: ./src/SetCapableContainerInterface.php
71
- [`DeleteCapableInterface`]: ./src/DeleteCapableInterface.php
72
- [`DeleteCapableContainerInterface`]: ./src/DeleteCapableContainerInterface.php
73
- [`ClearCapableInterface`]: ./src/ClearCapableInterface.php
74
- [`ClearCapableContainerInterface`]: ./src/ClearCapableContainerInterface.php
75
- [`ContainerFactoryInterface`]: ./src/ContainerFactoryInterface.php
76
- [`ContainerExceptionInterface`]: ./src/Exception/ContainerExceptionInterface.php
77
- [`NotFoundExceptionInterface`]: ./src/Exception/NotFoundExceptionInterface.php
78
-
79
- [`StringableInterface`]: https://github.com/Dhii/stringable-interface/blob/master/src/StringableInterface.php
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/dhii/data-container-interface/composer.json DELETED
@@ -1,50 +0,0 @@
1
- {
2
- "name": "dhii/data-container-interface",
3
- "description": "Interfaces for working with data containers",
4
- "type": "library",
5
- "license": "MIT",
6
- "authors": [
7
- {
8
- "name": "Dhii Team",
9
- "email": "development@dhii.co"
10
- }
11
- ],
12
- "minimum-stability": "dev",
13
- "prefer-stable": true,
14
- "require": {
15
- "php": "^5.3 | ^7.0",
16
- "psr/container": "^1.0",
17
- "dhii/factory-interface": "^0.1-alpha1",
18
- "dhii/exception-interface": "^0.1 | ^0.2"
19
- },
20
- "require-dev": {
21
- "phpunit/phpunit": "^4.8",
22
- "ptrofimov/xpmock": "^1.1",
23
- "dhii/php-cs-fixer-config": "dev-php-5.3",
24
- "codeclimate/php-test-reporter": "<=0.3.2",
25
- "dhii/stringable-interface": "^0.1"
26
- },
27
- "suggest": {
28
- "dhii/stringable-interface": "To be able to pass Stringables as keys"
29
- },
30
- "autoload": {
31
- "psr-4": {
32
- "Dhii\\Data\\Container\\": "src"
33
- }
34
- },
35
- "autoload-dev": {
36
- "psr-4": {
37
- "Dhii\\Data\\Container\\UnitTest\\": "test/unit",
38
- "Dhii\\Data\\Container\\FuncTest\\": "test/functional"
39
- }
40
- },
41
- "scripts": {
42
- "test": "phpunit",
43
- "csfix": "php-cs-fixer fix -vvv"
44
- },
45
- "extra": {
46
- "branch-alias": {
47
- "dev-develop": "0.2.x-dev"
48
- }
49
- }
50
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/dhii/data-container-interface/src/ClearCapableContainerInterface.php DELETED
@@ -1,16 +0,0 @@
1
- <?php
2
-
3
- namespace Dhii\Data\Container;
4
-
5
- use Psr\Container\ContainerInterface as BaseContainerInterface;
6
-
7
- /**
8
- * A container that can have its members cleared
9
- *
10
- * @since [*next-version*]
11
- */
12
- interface ClearCapableContainerInterface extends
13
- BaseContainerInterface,
14
- ClearCapableInterface
15
- {
16
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/dhii/data-container-interface/src/ClearCapableInterface.php DELETED
@@ -1,22 +0,0 @@
1
- <?php
2
-
3
- namespace Dhii\Data\Container;
4
-
5
- use Psr\Container\ContainerExceptionInterface;
6
-
7
- /**
8
- * Exposes means of clearing the members of the container.
9
- *
10
- * @since 0.2
11
- */
12
- interface ClearCapableInterface
13
- {
14
- /**
15
- * Clears the members.
16
- *
17
- * @since 0.2
18
- *
19
- * @throws ContainerExceptionInterface If problem clearing.
20
- */
21
- public function clear();
22
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/dhii/data-container-interface/src/ContainerAwareInterface.php DELETED
@@ -1,22 +0,0 @@
1
- <?php
2
-
3
- namespace Dhii\Data\Container;
4
-
5
- use Psr\Container\ContainerInterface as BaseContainerInterface;
6
-
7
- /**
8
- * Something that can have a container retrieved.
9
- *
10
- * @since 0.1
11
- */
12
- interface ContainerAwareInterface
13
- {
14
- /**
15
- * Retrieves the container associated with this instance.
16
- *
17
- * @since 0.1
18
- *
19
- * @return BaseContainerInterface|null The container, if any.
20
- */
21
- public function getContainer();
22
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/dhii/data-container-interface/src/ContainerFactoryInterface.php DELETED
@@ -1,38 +0,0 @@
1
- <?php
2
-
3
- namespace Dhii\Data\Container;
4
-
5
- use Dhii\Factory\FactoryInterface;
6
- use Psr\Container\ContainerInterface as BaseContainerInterface;
7
-
8
- /**
9
- * Something that can create new container instances.
10
- *
11
- * @since 0.2
12
- */
13
- interface ContainerFactoryInterface extends FactoryInterface
14
- {
15
- /**
16
- * The key in the factory config for container data.
17
- *
18
- * @since 0.2
19
- */
20
- const K_DATA = 'data';
21
-
22
- /**
23
- * The key in the factory config for service definitions.
24
- *
25
- * @since 0.2
26
- * @deprecated
27
- */
28
- const K_CFG_DEFINITIONS = self::K_DATA;
29
-
30
- /**
31
- * {@inheritdoc}
32
- *
33
- * @since 0.2
34
- *
35
- * @return BaseContainerInterface The created container instance.
36
- */
37
- public function make($config = null);
38
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/dhii/data-container-interface/src/ContainerInterface.php DELETED
@@ -1,30 +0,0 @@
1
- <?php
2
-
3
- namespace Dhii\Data\Container;
4
-
5
- use Psr\Container\ContainerInterface as BaseContainerInterface;
6
- use Dhii\Util\String\StringableInterface as Stringable;
7
- use Dhii\Data\Container\Exception\NotFoundExceptionInterface;
8
- use Dhii\Data\Container\Exception\ContainerExceptionInterface;
9
-
10
- /**
11
- * Represents something that can have data retrieved by key.
12
- *
13
- * @since 0.1
14
- */
15
- interface ContainerInterface extends
16
- HasCapableInterface,
17
- BaseContainerInterface
18
- {
19
- /**
20
- * Retrieves something that corresponds to the key.
21
- *
22
- * @since 0.1
23
- *
24
- * @param string|Stringable $key The key to retrieve the data for.
25
- *
26
- * @throws NotFoundExceptionInterface If data for key is not found.
27
- * @throws ContainerExceptionInterface If a problem occurs while retrieving.
28
- */
29
- public function get($key);
30
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/dhii/data-container-interface/src/DataKeyAwareInterface.php DELETED
@@ -1,22 +0,0 @@
1
- <?php
2
-
3
- namespace Dhii\Data\Container;
4
-
5
- use Util\String\StringableInterface as Stringable;
6
-
7
- /**
8
- * Something that can have a data key retrieved from it.
9
- *
10
- * @since 0.2
11
- */
12
- interface DataKeyAwareInterface
13
- {
14
- /**
15
- * Retrieves the key that is associated with this instance.
16
- *
17
- * @since 0.2
18
- *
19
- * @return string|Stringable|null The key, if any.
20
- */
21
- public function getDataKey();
22
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/dhii/data-container-interface/src/DeleteCapableContainerInterface.php DELETED
@@ -1,28 +0,0 @@
1
- <?php
2
-
3
- namespace Dhii\Data\Container;
4
-
5
- use Dhii\Util\String\StringableInterface as Stringable;
6
- use Psr\Container\ContainerInterface as BaseContainerInterface;
7
- use Psr\Container\ContainerExceptionInterface;
8
-
9
- /**
10
- * A container that can have a member removed.
11
- *
12
- * @since [*next-version*]
13
- */
14
- interface DeleteCapableContainerInterface extends
15
- BaseContainerInterface,
16
- DeleteCapableInterface
17
- {
18
- /**
19
- * Removes a data member from the object by key.
20
- *
21
- * @since [*next-version*]
22
- *
23
- * @param string|int|float|bool|Stringable $key The key of the data member to delete.
24
- *
25
- * @throws ContainerExceptionInterface If data member could not be deleted.
26
- */
27
- public function delete($key);
28
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/dhii/data-container-interface/src/DeleteCapableInterface.php DELETED
@@ -1,25 +0,0 @@
1
- <?php
2
-
3
- namespace Dhii\Data\Container;
4
-
5
- use Dhii\Util\String\StringableInterface as Stringable;
6
- use Psr\Container\ContainerExceptionInterface;
7
-
8
- /**
9
- * Exposes means of deleting a data member.
10
- *
11
- * @since 0.2
12
- */
13
- interface DeleteCapableInterface
14
- {
15
- /**
16
- * Removes a data member from the object by key.
17
- *
18
- * @since 0.2
19
- *
20
- * @param string|int|float|bool|Stringable $key The key of the data member to delete.
21
- *
22
- * @throws ContainerExceptionInterface If data member could not be deleted.
23
- */
24
- public function delete($key);
25
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/dhii/data-container-interface/src/Exception/ContainerExceptionInterface.php DELETED
@@ -1,19 +0,0 @@
1
- <?php
2
-
3
- namespace Dhii\Data\Container\Exception;
4
-
5
- use Dhii\Data\Container\ContainerAwareInterface;
6
- use Psr\Container\ContainerExceptionInterface as BaseContainerExceptionInterface;
7
- use Dhii\Exception\ThrowableInterface;
8
-
9
- /**
10
- * An exception that occurs in relation to a container.
11
- *
12
- * @since 0.1
13
- */
14
- interface ContainerExceptionInterface extends
15
- ThrowableInterface,
16
- ContainerAwareInterface,
17
- BaseContainerExceptionInterface
18
- {
19
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/dhii/data-container-interface/src/Exception/NotFoundExceptionInterface.php DELETED
@@ -1,18 +0,0 @@
1
- <?php
2
-
3
- namespace Dhii\Data\Container\Exception;
4
-
5
- use Psr\Container\NotFoundExceptionInterface as BaseNotFoundExceptionInterface;
6
- use Dhii\Data\Container\DataKeyAwareInterface;
7
-
8
- /**
9
- * Represents an exception which occurs when data requested for a key is not found.
10
- *
11
- * @since 0.1
12
- */
13
- interface NotFoundExceptionInterface extends
14
- BaseNotFoundExceptionInterface,
15
- ContainerExceptionInterface,
16
- DataKeyAwareInterface
17
- {
18
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/dhii/data-container-interface/src/HasCapableInterface.php DELETED
@@ -1,27 +0,0 @@
1
- <?php
2
-
3
- namespace Dhii\Data\Container;
4
-
5
- use Dhii\Util\String\StringableInterface as Stringable;
6
- use Dhii\Data\Container\Exception\ContainerExceptionInterface;
7
-
8
- /**
9
- * Represents something that can have data checked for by key.
10
- *
11
- * @since 0.1
12
- */
13
- interface HasCapableInterface
14
- {
15
- /**
16
- * Checks whether this instance has data for a key.
17
- *
18
- * @since 0.1
19
- *
20
- * @param string|Stringable $key The key to check for.
21
- *
22
- * @throws ContainerExceptionInterface If a problem occurs while checking.
23
- *
24
- * @return bool True if data exists for the key; otherwise false.
25
- */
26
- public function has($key);
27
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/dhii/data-container-interface/src/SetCapableContainerInterface.php DELETED
@@ -1,14 +0,0 @@
1
- <?php
2
-
3
- namespace Dhii\Data\Container;
4
-
5
- use Psr\Container\ContainerInterface as BaseContainerInterface;
6
-
7
- /**
8
- * A container that can have values set.
9
- */
10
- interface SetCapableContainerInterface extends
11
- BaseContainerInterface,
12
- SetCapableInterface
13
- {
14
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/dhii/data-container-interface/src/SetCapableInterface.php DELETED
@@ -1,26 +0,0 @@
1
- <?php
2
-
3
- namespace Dhii\Data\Container;
4
-
5
- use Dhii\Util\String\StringableInterface as Stringable;
6
- use Psr\Container\ContainerExceptionInterface;
7
-
8
- /**
9
- * Exposes means of setting data on an object.
10
- *
11
- * @since 0.2
12
- */
13
- interface SetCapableInterface
14
- {
15
- /**
16
- * Sets the value of a data member with the specified key.
17
- *
18
- * @since 0.2
19
- *
20
- * @param string|int|float|bool|Stringable $key The key of the data member to set.
21
- * @param mixed $value The value to set.
22
- *
23
- * @throws ContainerExceptionInterface If the data could not be set.
24
- */
25
- public function set($key, $value);
26
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/dhii/data-container-interface/src/WritableContainerInterface.php DELETED
@@ -1,14 +0,0 @@
1
- <?php
2
-
3
- namespace Dhii\Data\Container;
4
-
5
- /**
6
- * Represents a container with complete read and write access to individual elements.
7
- *
8
- * @package Dhii\Data\Container
9
- */
10
- interface WritableContainerInterface extends
11
- SetCapableContainerInterface,
12
- DeleteCapableContainerInterface
13
- {
14
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/dhii/exception-interface/CHANGELOG.md DELETED
@@ -1,27 +0,0 @@
1
- # Change log
2
- All notable changes to this project will be documented in this file.
3
-
4
- The format is based on [Keep a Changelog](http://keepachangelog.com/)
5
- and this project adheres to [Semantic Versioning](http://semver.org/).
6
-
7
- ## [0.2] - 2018-08-29
8
- Stable release.
9
-
10
- ## [0.2-alpha3] - 2018-02-23
11
- ### Changed
12
- - `InternalExceptionInterface` is now required to expose an inner exception.
13
-
14
- ## [0.2-alpha2] - 2018-02-19
15
- ### Added
16
- - `InternalExceptionInterface`
17
-
18
- ## [0.2-alpha1] - 2018-02-19
19
- ### Added
20
- - `RuntimeExceptionInterface`.
21
-
22
- ### Changed
23
- - **BC Breaking**: The argument value of `InvalidArgumentExceptionInterface`
24
- now retrieved via `getSubject()`, as it extends the new `BadSubjectExceptionInterface`.
25
-
26
- ## [0.1] - 2017-09-01
27
- Initial version.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/dhii/exception-interface/LICENSE DELETED
@@ -1,19 +0,0 @@
1
- Copyright (c) 2017 Dhii
2
-
3
- Permission is hereby granted, free of charge, to any person obtaining a copy
4
- of this software and associated documentation files (the "Software"), to deal
5
- in the Software without restriction, including without limitation the rights
6
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
- copies of the Software, and to permit persons to whom the Software is
8
- furnished to do so, subject to the following conditions:
9
-
10
- The above copyright notice and this permission notice shall be included in all
11
- copies or substantial portions of the Software.
12
-
13
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19
- SOFTWARE.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/dhii/exception-interface/README.md DELETED
@@ -1,46 +0,0 @@
1
- # Dhii - Exception - Interface
2
-
3
- [![Build Status](https://travis-ci.org/Dhii/exception-interface.svg?branch=master)](https://travis-ci.org/Dhii/exception-interface)
4
- [![Code Climate](https://codeclimate.com/github/Dhii/exception-interface/badges/gpa.svg)](https://codeclimate.com/github/Dhii/exception-interface)
5
- [![Test Coverage](https://codeclimate.com/github/Dhii/exception-interface/badges/coverage.svg)](https://codeclimate.com/github/Dhii/exception-interface/coverage)
6
- [![Latest Stable Version](https://poser.pugx.org/dhii/exception-interface/version)](https://packagist.org/packages/dhii/exception-interface)
7
- [![This package complies with Dhii standards](https://img.shields.io/badge/Dhii-Compliant-green.svg?style=flat-square)][Dhii]
8
-
9
- Interfaces for most common exceptions.
10
-
11
- ## Details
12
- - [`ThrowableInterface`] - The base of all exception interfaces. Declares
13
- all the same methods as `Exception` in a compatible way, and additionally
14
- extends [`StringableInterface`].
15
- - [`BadSubjectExceptionInterface`] - Base interface for all exceptions that
16
- are related to some value being invalid, malformed, out of range, etc. Exposes
17
- that value via `getSubject()`.
18
- - [`InvalidArgumentExceptionInterface`] - Allows de-coupling from the vanilla
19
- [`InvalidArgumentException`], and makes it more useful besides signalling the
20
- problem type by exposing the argument via `BadSubjectExceptionInterface#getSubejct()`.
21
- - [`ArgumentCodeAwareInterface`] - Useful with `InvalidArgumentExceptionInterface`
22
- for providing information about the source of the problematic argument.
23
- - [`OutOfBoundsExceptionInterface`] - Complementing the native [`OutOfBoundsException`], it occurs when a key is
24
- addressed in a set that does not have it, like accessing a non-existing array key. Exposes the bad key.
25
- - [`OutOfRangeExceptionInterface`] - Complementing the native [`OutOfRangeException`], it occurs when a value is
26
- valid but illegal, i.e. is outside of the allowed range, like when an integer that represents a colour and must be
27
- 0-255 has the value of 256. Exposes the bad value.
28
- - [`RuntimeExceptionInterface`][RuntimeExceptionInterface] - A generic runtime problem.
29
- - [`InternalExceptionInterface`][InternalExceptionInterface] - A problem that occurs in relation to the inner workings
30
- of the unit, and is not caused by the consumer. Guarantees to expose an inner exception.
31
-
32
-
33
- [`ThrowableInterface`]: src/ThrowableInterface.php
34
- [`BadSubjectExceptionInterface`]: src/BadSubjectExceptionInterface.php
35
- [`InvalidArgumentExceptionInterface`]: src/InvalidArgumentExceptionInterface.php
36
- [`ArgumentCodeAwareInterface`]: src/ArgumentCodeAwareInterface.php
37
- [`OutOfBoundsExceptionInterface`]: src/OutOfBoundsExceptionInterface.php
38
- [`OutOfRangeExceptionInterface`]: src/OutOfRangeExceptionInterface.php
39
- [RuntimeExceptionInterface]: src/RuntimeExceptionInterface.php
40
- [InternalExceptionInterface]: src/InternalExceptionInterface.php
41
- [`StringableInterface`]: https://github.com/Dhii/stringable-interface/blob/master/src/StringableInterface.php
42
- [`InvalidArgumentException`]: http://php.net/manual/en/class.invalidargumentexception.php
43
- [`OutOfBoundsException`]: http://php.net/manual/en/class.outofboundsexception.php
44
- [`OutOfRangeException`]: http://php.net/manual/en/class.outofrangeexception.php
45
-
46
- [Dhii]: https://github.com/Dhii/dhii
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/dhii/exception-interface/composer.json DELETED
@@ -1,44 +0,0 @@
1
- {
2
- "name": "dhii/exception-interface",
3
- "description": "Interfaces for most common exceptions",
4
- "type": "library",
5
- "license": "MIT",
6
- "authors": [
7
- {
8
- "name": "Dhii Team",
9
- "email": "development@dhii.co"
10
- }
11
- ],
12
- "minimum-stability": "dev",
13
- "prefer-stable": true,
14
- "require": {
15
- "php": "^5.3 | ^7.0",
16
- "dhii/stringable-interface": "^0.1"
17
- },
18
- "require-dev": {
19
- "phpunit/phpunit": "^4.8",
20
- "ptrofimov/xpmock": "^1.1",
21
- "dhii/php-cs-fixer-config": "dev-php-5.3",
22
- "codeclimate/php-test-reporter": "<=0.3.2"
23
- },
24
- "autoload": {
25
- "psr-4": {
26
- "Dhii\\Exception\\": "src"
27
- }
28
- },
29
- "autoload-dev": {
30
- "psr-4": {
31
- "Dhii\\Exception\\UnitTest\\": "test/unit",
32
- "Dhii\\Exception\\FuncTest\\": "test/functional"
33
- }
34
- },
35
- "scripts": {
36
- "test": "phpunit",
37
- "csfix": "php-cs-fixer fix -vvv"
38
- },
39
- "extra": {
40
- "branch-alias": {
41
- "dev-develop": "0.2.x-dev"
42
- }
43
- }
44
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/dhii/exception-interface/phpmd.xml DELETED
@@ -1,25 +0,0 @@
1
- <?xml version="1.0"?>
2
-
3
- <ruleset name="Dhii Standard"
4
- xmlns="http://pmd.sf.net/ruleset/1.0.0"
5
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
6
- xsi:schemaLocation="http://pmd.sf.net/ruleset/1.0.0
7
- http://pmd.sf.net/ruleset_xml_schema.xsd"
8
- xsi:noNamespaceSchemaLocation="http://pmd.sf.net/ruleset_xml_schema.xsd">
9
- <description>A standard Dhii ruleset</description>
10
-
11
- <!-- Standard Rules of CodeClimate -->
12
- <rule ref="rulesets/cleancode.xml" />
13
- <rule ref="rulesets/codesize.xml" />
14
- <rule ref="rulesets/controversial.xml" />
15
- <rule ref="rulesets/design.xml" />
16
- <rule ref="rulesets/naming.xml" />
17
- <rule ref="rulesets/unusedcode.xml" />
18
-
19
-
20
- <rule ref="rulesets/controversial.xml/CamelCasePropertyName">
21
- <properties>
22
- <property name="allow-underscore" value="true" />
23
- </properties>
24
- </rule>
25
- </ruleset>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/dhii/exception-interface/src/ArgumentCodeAwareInterface.php DELETED
@@ -1,24 +0,0 @@
1
- <?php
2
-
3
- namespace Dhii\Exception;
4
-
5
- /**
6
- * Something that can have an argument code retrieved from it.
7
- *
8
- * Can be useful for argument-related exceptions that need to provide more
9
- * specific information about the argument.
10
- *
11
- * @since 0.1
12
- */
13
- interface ArgumentCodeAwareInterface
14
- {
15
- /**
16
- * Retrieves the argument code associated with this instance.
17
- *
18
- * @since 0.1
19
- *
20
- * @return string|int The argument code. Something that identifies an argument
21
- * in its scope.
22
- */
23
- public function getArgumentCode();
24
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/dhii/exception-interface/src/BadSubjectExceptionInterface.php DELETED
@@ -1,20 +0,0 @@
1
- <?php
2
-
3
- namespace Dhii\Exception;
4
-
5
- /**
6
- * An exception that occurs in relation to a wrong, invalid, or erroneous value.
7
- *
8
- * @since 0.2
9
- */
10
- interface BadSubjectExceptionInterface extends ThrowableInterface
11
- {
12
- /**
13
- * Retrieves the problematic subject.
14
- *
15
- * @since 0.2
16
- *
17
- * @return mixed|null The subject, if any.
18
- */
19
- public function getSubject();
20
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/dhii/exception-interface/src/InternalExceptionInterface.php DELETED
@@ -1,27 +0,0 @@
1
- <?php
2
-
3
- namespace Dhii\Exception;
4
-
5
- use Dhii\Exception\UnitTest\InternalExceptionInterfaceTest;
6
- use Exception as RootException;
7
-
8
- /**
9
- * Represents an exception that is not caused by consumer actions.
10
- *
11
- * If this exception is thrown, it means that the cause of the problem
12
- * is not related to any parameter passed to the unit that was invoked.
13
- *
14
- * Exceptions of this type guarantee an inner exceptions, so that consumers
15
- * can have a way of determining the cause of the problem.
16
- *
17
- * @since 0.2
18
- */
19
- interface InternalExceptionInterface extends ThrowableInterface
20
- {
21
- /**
22
- * @since 0.2
23
- *
24
- * @return RootException
25
- */
26
- public function getPrevious();
27
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/dhii/exception-interface/src/InvalidArgumentExceptionInterface.php DELETED
@@ -1,12 +0,0 @@
1
- <?php
2
-
3
- namespace Dhii\Exception;
4
-
5
- /**
6
- * Represents an exception that signals an invalid function argument.
7
- *
8
- * @since 0.1
9
- */
10
- interface InvalidArgumentExceptionInterface extends BadSubjectExceptionInterface
11
- {
12
- }
 
 
 
 
 
 
 
 
 
 
 
 
vendor/dhii/exception-interface/src/OutOfBoundsExceptionInterface.php DELETED
@@ -1,12 +0,0 @@
1
- <?php
2
-
3
- namespace Dhii\Exception;
4
-
5
- /**
6
- * Represents an exception that signals that a value is requested from a set that does not have the value.
7
- *
8
- * @since 0.2
9
- */
10
- interface OutOfBoundsExceptionInterface extends BadSubjectExceptionInterface
11
- {
12
- }
 
 
 
 
 
 
 
 
 
 
 
 
vendor/dhii/exception-interface/src/OutOfRangeExceptionInterface.php DELETED
@@ -1,12 +0,0 @@
1
- <?php
2
-
3
- namespace Dhii\Exception;
4
-
5
- /**
6
- * Represents an exception that signals that a value is not within required parameters.
7
- *
8
- * @since 0.2
9
- */
10
- interface OutOfRangeExceptionInterface extends BadSubjectExceptionInterface
11
- {
12
- }
 
 
 
 
 
 
 
 
 
 
 
 
vendor/dhii/exception-interface/src/RuntimeExceptionInterface.php DELETED
@@ -1,12 +0,0 @@
1
- <?php
2
-
3
- namespace Dhii\Exception;
4
-
5
- /**
6
- * Represents a generic runtime exception.
7
- *
8
- * @since 0.2
9
- */
10
- interface RuntimeExceptionInterface extends ThrowableInterface
11
- {
12
- }
 
 
 
 
 
 
 
 
 
 
 
 
vendor/dhii/exception-interface/src/ThrowableInterface.php DELETED
@@ -1,89 +0,0 @@
1
- <?php
2
-
3
- namespace Dhii\Exception;
4
-
5
- use Exception as RootException;
6
- use Dhii\Util\String\StringableInterface;
7
-
8
- /**
9
- * Formalizes the interface of exceptions and errors.
10
- *
11
- * Primarily, this is necessary to formally depend on exception methods before
12
- * PHP 7.0, which introduces the {@link http://php.net/manual/en/class.throwable.php Throwable}
13
- * interface.
14
- *
15
- * @since 0.1
16
- */
17
- interface ThrowableInterface extends StringableInterface
18
- {
19
- /**
20
- * Retrieves the message.
21
- *
22
- * @since 0.1
23
- *
24
- * @return string The message.
25
- */
26
- public function getMessage();
27
-
28
- /**
29
- * Retrieves the code.
30
- *
31
- * @since 0.1
32
- *
33
- * @return int The code.
34
- */
35
- public function getCode();
36
-
37
- /**
38
- * Retrieves the path to the file where this instance was created.
39
- *
40
- * @since 0.1
41
- *
42
- * @return string Path to the file.
43
- */
44
- public function getFile();
45
-
46
- /**
47
- * Retrieves the number of the line where the exception was created.
48
- *
49
- * @since 0.1
50
- *
51
- * @return int The line number.
52
- */
53
- public function getLine();
54
-
55
- /**
56
- * Retrieves the backtrace data.
57
- *
58
- * @since 0.1
59
- *
60
- * @return array[] Frames of the backtrace, in the same format as
61
- * returned by {@see debug_backtrace()}.
62
- */
63
- public function getTrace();
64
-
65
- /**
66
- * Retrieves the trace in human-readable string format.
67
- *
68
- * @since 0.1
69
- *
70
- * @return string The string representation of backtrace steps.
71
- */
72
- public function getTraceAsString();
73
-
74
- /**
75
- * Retrieves the previous, inner exception for chaining.
76
- *
77
- * @since 0.1
78
- *
79
- * @return RootException|null The inner exception, if any.
80
- */
81
- public function getPrevious();
82
-
83
- /**
84
- * Retrieves the human-readable representation of the error.
85
- *
86
- * @since 0.1
87
- */
88
- public function __toString();
89
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/dhii/factory-interface/CHANGELOG.md DELETED
@@ -1,19 +0,0 @@
1
- # Change log
2
- All notable changes to this project will be documented in this file.
3
-
4
- The format is based on [Keep a Changelog](http://keepachangelog.com/)
5
- and this project adheres to [Semantic Versioning](http://semver.org/).
6
-
7
- ## [0.1] - 2018-08-29
8
- A stable release
9
-
10
- ## [0.1-alpha3] - 2018-07-19
11
- ### Added
12
- - `DataObjectFactoryInterface`.
13
-
14
- ## [0.1-alpha2] - 2018-03-07
15
- ### Fixed
16
- - Now declares compatibility with `dhii/exception-interface:^0.1`.
17
-
18
- ## [0.1-alpha1] - 2018-03-06
19
- Initial version.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/dhii/factory-interface/LICENSE DELETED
@@ -1,21 +0,0 @@
1
- MIT License
2
-
3
- Copyright (c) YYYY Dhii
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/dhii/factory-interface/README.md DELETED
@@ -1,22 +0,0 @@
1
- # Dhii - Factory Interface
2
-
3
- [![Build Status](https://travis-ci.org/Dhii/factory-interface.svg?branch=develop)](https://travis-ci.org/Dhii/factory-interface)
4
- [![Code Climate](https://codeclimate.com/github/Dhii/factory-interface/badges/gpa.svg)](https://codeclimate.com/github/Dhii/factory-interface)
5
- [![Latest Stable Version](https://poser.pugx.org/dhii/factory-interface/version)](https://packagist.org/packages/dhii/factory-interface)
6
- [![This package complies with Dhii standards](https://img.shields.io/badge/Dhii-Compliant-green.svg?style=flat-square)][Dhii]
7
-
8
- Interfaces for working with factories.
9
-
10
- ## Interfaces
11
- - [`FactoryInterface`][FactoryInterface] - Creates things.
12
- - [`DataObjectFactoryInterface`][DataObjectFactoryInterface] - Creates data objects.
13
- - [`FactoryFactoryInterface`][FactoryFactoryInterface] - Creates factories. For example, could create a factory from
14
- a callback or an FQN.
15
- - [`FactoryAwareInterface`][FactoryAwareInterface] - Exposes a factory.
16
-
17
- [Dhii]: https://github.com/Dhii/dhii
18
-
19
- [FactoryInterface]: src/FactoryInterface.php
20
- [DataObjectFactoryInterface]: src/DataObjectFactoryInterface.php
21
- [FactoryFactoryInterface]: src/FactoryFactoryInterface.php
22
- [FactoryAwareInterface]: src/FactoryAwareInterface.php
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/dhii/factory-interface/composer.json DELETED
@@ -1,46 +0,0 @@
1
- {
2
- "name": "dhii/factory-interface",
3
- "description": "Interfaces for working with factories.",
4
- "type": "library",
5
- "license": "MIT",
6
- "authors": [
7
- {
8
- "name": "Dhii Team",
9
- "email": "development@dhii.co"
10
- }
11
- ],
12
- "minimum-stability": "dev",
13
- "prefer-stable": true,
14
- "require": {
15
- "php": "^5.3 | ^7.0",
16
- "dhii/exception-interface": "^0.1|^0.2"
17
- },
18
- "require-dev": {
19
- "psr/container": "^1.0",
20
- "phpunit/phpunit": "^4.8",
21
- "ptrofimov/xpmock": "^1.1",
22
- "dhii/php-cs-fixer-config": "dev-php-5.3",
23
- "codeclimate/php-test-reporter": "<=0.3.2",
24
- "dhii/stringable-interface": "^0.1"
25
- },
26
- "autoload": {
27
- "psr-4": {
28
- "Dhii\\Factory\\": "src"
29
- }
30
- },
31
- "autoload-dev": {
32
- "psr-4": {
33
- "Dhii\\Factory\\UnitTest\\": "test/unit",
34
- "Dhii\\Factory\\FuncTest\\": "test/functional"
35
- }
36
- },
37
- "scripts": {
38
- "test": "phpunit",
39
- "csfix": "php-cs-fixer fix -vvv"
40
- },
41
- "extra": {
42
- "branch-alias": {
43
- "dev-develop": "0.1.x-dev"
44
- }
45
- }
46
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/dhii/factory-interface/phpmd.xml DELETED
@@ -1,25 +0,0 @@
1
- <?xml version="1.0"?>
2
-
3
- <ruleset name="Dhii Standard"
4
- xmlns="http://pmd.sf.net/ruleset/1.0.0"
5
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
6
- xsi:schemaLocation="http://pmd.sf.net/ruleset/1.0.0
7
- http://pmd.sf.net/ruleset_xml_schema.xsd"
8
- xsi:noNamespaceSchemaLocation="http://pmd.sf.net/ruleset_xml_schema.xsd">
9
- <description>A standard Dhii ruleset</description>
10
-
11
- <!-- Standard Rules of CodeClimate -->
12
- <rule ref="rulesets/cleancode.xml" />
13
- <rule ref="rulesets/codesize.xml" />
14
- <rule ref="rulesets/controversial.xml" />
15
- <rule ref="rulesets/design.xml" />
16
- <rule ref="rulesets/naming.xml" />
17
- <rule ref="rulesets/unusedcode.xml" />
18
-
19
-
20
- <rule ref="rulesets/controversial.xml/CamelCasePropertyName">
21
- <properties>
22
- <property name="allow-underscore" value="true" />
23
- </properties>
24
- </rule>
25
- </ruleset>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/dhii/factory-interface/src/DataObjectFactoryInterface.php DELETED
@@ -1,20 +0,0 @@
1
- <?php
2
-
3
- namespace Dhii\Factory;
4
-
5
- /**
6
- * A factory that allows the creation of data objects.
7
- *
8
- * Primarily just defines the way of passing data for the object in the config.
9
- *
10
- * @since 0.1
11
- */
12
- interface DataObjectFactoryInterface extends FactoryInterface
13
- {
14
- /**
15
- * The config key that contains the data for the product.
16
- *
17
- * @since 0.1
18
- */
19
- const K_DATA = 'data';
20
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/dhii/factory-interface/src/Exception/CouldNotMakeExceptionInterface.php DELETED
@@ -1,23 +0,0 @@
1
- <?php
2
-
3
- namespace Dhii\Factory\Exception;
4
-
5
- use Psr\Container\ContainerInterface;
6
-
7
- /**
8
- * An exception thrown when a factory failed to create an instance.
9
- *
10
- * @since 0.1
11
- */
12
- interface CouldNotMakeExceptionInterface extends
13
- FactoryExceptionInterface
14
- {
15
- /**
16
- * Retrieves the configuration of the subject that failed.
17
- *
18
- * @since 0.1
19
- *
20
- * @return array|ContainerInterface
21
- */
22
- public function getSubjectConfig();
23
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/dhii/factory-interface/src/Exception/FactoryExceptionInterface.php DELETED
@@ -1,17 +0,0 @@
1
- <?php
2
-
3
- namespace Dhii\Factory\Exception;
4
-
5
- use Dhii\Exception\ThrowableInterface;
6
- use Dhii\Factory\FactoryAwareInterface;
7
-
8
- /**
9
- * An exception thrown by a factory when an error has occurred.
10
- *
11
- * @since 0.1
12
- */
13
- interface FactoryExceptionInterface extends
14
- ThrowableInterface,
15
- FactoryAwareInterface
16
- {
17
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/dhii/factory-interface/src/FactoryAwareInterface.php DELETED
@@ -1,20 +0,0 @@
1
- <?php
2
-
3
- namespace Dhii\Factory;
4
-
5
- /**
6
- * Something that can have a factory retrieved from it.
7
- *
8
- * @since 0.1
9
- */
10
- interface FactoryAwareInterface
11
- {
12
- /**
13
- * Retrieves the factory associate with this instance.
14
- *
15
- * @since 0.1
16
- *
17
- * @return FactoryInterface|null
18
- */
19
- public function getFactory();
20
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/dhii/factory-interface/src/FactoryFactoryInterface.php DELETED
@@ -1,20 +0,0 @@
1
- <?php
2
-
3
- namespace Dhii\Factory;
4
-
5
- /**
6
- * Something that creates factories.
7
- *
8
- * @since 0.1
9
- */
10
- interface FactoryFactoryInterface extends FactoryInterface
11
- {
12
- /**
13
- * {@inheritdoc}
14
- *
15
- * @since 0.1
16
- *
17
- * @return FactoryInterface The new factory.
18
- */
19
- public function make($config = null);
20
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/dhii/factory-interface/src/FactoryInterface.php DELETED
@@ -1,32 +0,0 @@
1
- <?php
2
-
3
- namespace Dhii\Factory;
4
-
5
- use ArrayAccess;
6
- use Dhii\Factory\Exception\FactoryExceptionInterface;
7
- use Dhii\Factory\Exception\CouldNotMakeExceptionInterface;
8
- use Psr\Container\ContainerInterface;
9
- use stdClass;
10
-
11
- /**
12
- * Something that can create things.
13
- *
14
- * @since 0.1
15
- */
16
- interface FactoryInterface
17
- {
18
- /**
19
- * Creates a new instance.
20
- *
21
- * @since 0.1
22
- *
23
- * @param array|ArrayAccess|ContainerInterface|stdClass|null $config A map of configuration, if any. Any container
24
- * that passes normalization by {@see Dhii\Data\Container\ContainerGetCapableTrait#_containerGet()}.
25
- *
26
- * @throws CouldNotMakeExceptionInterface If the factory failed to make the instance.
27
- * @throws FactoryExceptionInterface If an error related to the factory occurs.
28
- *
29
- * @return mixed The created things.
30
- */
31
- public function make($config = null);
32
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/dhii/stringable-interface/.php_cs DELETED
@@ -1,23 +0,0 @@
1
- <?php
2
- require_once __DIR__.DIRECTORY_SEPARATOR.'vendor/autoload.php';
3
- $config = Dhii\Configuration\PHPCSFixer\Config::create();
4
- $fixers = $config->getFixers();
5
- $toRemove = array();
6
- foreach ($toRemove as $_fixer) {
7
- if (($removeIndex = array_search($_fixer, $fixers)) === false) {
8
- continue;
9
- }
10
-
11
- unset($fixers[$removeIndex]);
12
- }
13
- $toAdd = array();
14
- foreach ($toAdd as $_fixer) {
15
- if (($removeIndex = array_search($_fixer, $fixers)) !== false) {
16
- continue;
17
- }
18
-
19
- $fixers[] = $_fixer;
20
- }
21
- $config->fixers($fixers);
22
- $config->getFinder()->in(__DIR__.DIRECTORY_SEPARATOR.'src');
23
- return $config;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/dhii/stringable-interface/CHANGELOG.md DELETED
@@ -1,12 +0,0 @@
1
- # Change log
2
- All notable changes to this project will be documented in this file.
3
-
4
- The format is based on [Keep a Changelog](http://keepachangelog.com/)
5
- and this project adheres to [Semantic Versioning](http://semver.org/).
6
-
7
- ## [0.1] - 2017-01-23
8
- Initial release.
9
-
10
- ### Added
11
- - Interop interfaces;
12
- - Interface tests;
 
 
 
 
 
 
 
 
 
 
 
 
vendor/dhii/stringable-interface/README.md DELETED
@@ -1,7 +0,0 @@
1
- # Stringable Interface
2
-
3
- [![Build Status](https://travis-ci.org/Dhii/stringable-interface.svg?branch=master)](https://travis-ci.org/Dhii/stringable-interface)
4
- [![Code Climate](https://codeclimate.com/github/Dhii/stringable-interface/badges/gpa.svg)](https://codeclimate.com/github/Dhii/stringable-interface)
5
- [![Test Coverage](https://codeclimate.com/github/Dhii/stringable-interface/badges/coverage.svg)](https://codeclimate.com/github/Dhii/stringable-interface/coverage)
6
-
7
- Increasing interoperability for objects that can be cast to string.
 
 
 
 
 
 
 
vendor/dhii/stringable-interface/composer.json DELETED
@@ -1,27 +0,0 @@
1
- {
2
- "name": "dhii/stringable-interface",
3
- "description": "Interoperability interface for objects that can be cast to string",
4
- "type": "library",
5
- "license": "MIT",
6
- "authors": [
7
- {
8
- "name": "Dhii Team",
9
- "email": "development@dhii.co"
10
- }
11
- ],
12
- "minimum-stability": "dev",
13
- "require": {
14
- "php": "^5.3 | ^7.0"
15
- },
16
- "require-dev": {
17
- "phpunit/phpunit": "^4.8",
18
- "ptrofimov/xpmock": "^1.1",
19
- "dhii/php-cs-fixer-config": "dev-php-5.3",
20
- "codeclimate/php-test-reporter": "<=0.3.2"
21
- },
22
- "autoload": {
23
- "psr-4": {
24
- "Dhii\\Util\\String\\": "src/"
25
- }
26
- }
27
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/dhii/stringable-interface/composer.lock DELETED
@@ -1,1751 +0,0 @@
1
- {
2
- "_readme": [
3
- "This file locks the dependencies of your project to a known state",
4
- "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
5
- "This file is @generated automatically"
6
- ],
7
- "hash": "ece8d88e9386c0e94028293445ab3d29",
8
- "content-hash": "3b139fa487dd838939b13134e0a77e9c",
9
- "packages": [],
10
- "packages-dev": [
11
- {
12
- "name": "dhii/php-cs-fixer-config",
13
- "version": "dev-php-5.3",
14
- "source": {
15
- "type": "git",
16
- "url": "https://github.com/Dhii/php-cs-fixer-config.git",
17
- "reference": "ee3cc6c906a1aa4dca2bcbfcfef684dbd1ebb8ca"
18
- },
19
- "dist": {
20
- "type": "zip",
21
- "url": "https://api.github.com/repos/Dhii/php-cs-fixer-config/zipball/ee3cc6c906a1aa4dca2bcbfcfef684dbd1ebb8ca",
22
- "reference": "ee3cc6c906a1aa4dca2bcbfcfef684dbd1ebb8ca",
23
- "shasum": ""
24
- },
25
- "require": {
26
- "friendsofphp/php-cs-fixer": ">=1.11 <1.12",
27
- "php": "^5.3 | ^7.0"
28
- },
29
- "require-dev": {
30
- "phpunit/phpunit": "^4.8"
31
- },
32
- "type": "library",
33
- "autoload": {
34
- "psr-4": {
35
- "Dhii\\Configuration\\PHPCSFixer\\": "src/"
36
- }
37
- },
38
- "notification-url": "https://packagist.org/downloads/",
39
- "license": [
40
- "MIT"
41
- ],
42
- "authors": [
43
- {
44
- "name": "Dhii Team",
45
- "email": "development@dhii.co"
46
- }
47
- ],
48
- "description": "A default PHP CS Fixer config implementation",
49
- "time": "2016-09-03 14:45:03"
50
- },
51
- {
52
- "name": "doctrine/instantiator",
53
- "version": "dev-master",
54
- "source": {
55
- "type": "git",
56
- "url": "https://github.com/doctrine/instantiator.git",
57
- "reference": "68099b02b60bbf3b088ff5cb67bf506770ef9cac"
58
- },
59
- "dist": {
60
- "type": "zip",
61
- "url": "https://api.github.com/repos/doctrine/instantiator/zipball/68099b02b60bbf3b088ff5cb67bf506770ef9cac",
62
- "reference": "68099b02b60bbf3b088ff5cb67bf506770ef9cac",
63
- "shasum": ""
64
- },
65
- "require": {
66
- "php": ">=5.3,<8.0-DEV"
67
- },
68
- "require-dev": {
69
- "athletic/athletic": "~0.1.8",
70
- "ext-pdo": "*",
71
- "ext-phar": "*",
72
- "phpunit/phpunit": "~4.0",
73
- "squizlabs/php_codesniffer": "~2.0"
74
- },
75
- "type": "library",
76
- "extra": {
77
- "branch-alias": {
78
- "dev-master": "1.0.x-dev"
79
- }
80
- },
81
- "autoload": {
82
- "psr-4": {
83
- "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/"
84
- }
85
- },
86
- "notification-url": "https://packagist.org/downloads/",
87
- "license": [
88
- "MIT"
89
- ],
90
- "authors": [
91
- {
92
- "name": "Marco Pivetta",
93
- "email": "ocramius@gmail.com",
94
- "homepage": "http://ocramius.github.com/"
95
- }
96
- ],
97
- "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors",
98
- "homepage": "https://github.com/doctrine/instantiator",
99
- "keywords": [
100
- "constructor",
101
- "instantiate"
102
- ],
103
- "time": "2017-01-23 09:23:06"
104
- },
105
- {
106
- "name": "friendsofphp/php-cs-fixer",
107
- "version": "1.11.x-dev",
108
- "source": {
109
- "type": "git",
110
- "url": "https://github.com/FriendsOfPHP/PHP-CS-Fixer.git",
111
- "reference": "cc112071b8dc3c4447c8e50e1779cc77041d5f23"
112
- },
113
- "dist": {
114
- "type": "zip",
115
- "url": "https://api.github.com/repos/FriendsOfPHP/PHP-CS-Fixer/zipball/cc112071b8dc3c4447c8e50e1779cc77041d5f23",
116
- "reference": "cc112071b8dc3c4447c8e50e1779cc77041d5f23",
117
- "shasum": ""
118
- },
119
- "require": {
120
- "ext-tokenizer": "*",
121
- "php": ">=5.3.6",
122
- "sebastian/diff": "~1.1",
123
- "symfony/console": "~2.3|~3.0",
124
- "symfony/event-dispatcher": "~2.1|~3.0",
125
- "symfony/filesystem": "~2.1|~3.0",
126
- "symfony/finder": "~2.1|~3.0",
127
- "symfony/process": "~2.3|~3.0",
128
- "symfony/stopwatch": "~2.5|~3.0"
129
- },
130
- "conflict": {
131
- "hhvm": "<3.9"
132
- },
133
- "require-dev": {
134
- "phpunit/phpunit": "^4.5|^5",
135
- "satooshi/php-coveralls": "^0.7.1"
136
- },
137
- "bin": [
138
- "php-cs-fixer"
139
- ],
140
- "type": "application",
141
- "autoload": {
142
- "psr-4": {
143
- "Symfony\\CS\\": "Symfony/CS/"
144
- }
145
- },
146
- "notification-url": "https://packagist.org/downloads/",
147
- "license": [
148
- "MIT"
149
- ],
150
- "authors": [
151
- {
152
- "name": "Dariusz Rumiński",
153
- "email": "dariusz.ruminski@gmail.com"
154
- },
155
- {
156
- "name": "Fabien Potencier",
157
- "email": "fabien@symfony.com"
158
- }
159
- ],
160
- "description": "A tool to automatically fix PHP code style",
161
- "time": "2016-07-09 20:42:11"
162
- },
163
- {
164
- "name": "phpdocumentor/reflection-common",
165
- "version": "dev-master",
166
- "source": {
167
- "type": "git",
168
- "url": "https://github.com/phpDocumentor/ReflectionCommon.git",
169
- "reference": "144c307535e82c8fdcaacbcfc1d6d8eeb896687c"
170
- },
171
- "dist": {
172
- "type": "zip",
173
- "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/144c307535e82c8fdcaacbcfc1d6d8eeb896687c",
174
- "reference": "144c307535e82c8fdcaacbcfc1d6d8eeb896687c",
175
- "shasum": ""
176
- },
177
- "require": {
178
- "php": ">=5.5"
179
- },
180
- "require-dev": {
181
- "phpunit/phpunit": "^4.6"
182
- },
183
- "type": "library",
184
- "extra": {
185
- "branch-alias": {
186
- "dev-master": "1.0.x-dev"
187
- }
188
- },
189
- "autoload": {
190
- "psr-4": {
191
- "phpDocumentor\\Reflection\\": [
192
- "src"
193
- ]
194
- }
195
- },
196
- "notification-url": "https://packagist.org/downloads/",
197
- "license": [
198
- "MIT"
199
- ],
200
- "authors": [
201
- {
202
- "name": "Jaap van Otterdijk",
203
- "email": "opensource@ijaap.nl"
204
- }
205
- ],
206
- "description": "Common reflection classes used by phpdocumentor to reflect the code structure",
207
- "homepage": "http://www.phpdoc.org",
208
- "keywords": [
209
- "FQSEN",
210
- "phpDocumentor",
211
- "phpdoc",
212
- "reflection",
213
- "static analysis"
214
- ],
215
- "time": "2015-12-27 11:43:31"
216
- },
217
- {
218
- "name": "phpdocumentor/reflection-docblock",
219
- "version": "3.1.1",
220
- "source": {
221
- "type": "git",
222
- "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git",
223
- "reference": "8331b5efe816ae05461b7ca1e721c01b46bafb3e"
224
- },
225
- "dist": {
226
- "type": "zip",
227
- "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/8331b5efe816ae05461b7ca1e721c01b46bafb3e",
228
- "reference": "8331b5efe816ae05461b7ca1e721c01b46bafb3e",
229
- "shasum": ""
230
- },
231
- "require": {
232
- "php": ">=5.5",
233
- "phpdocumentor/reflection-common": "^1.0@dev",
234
- "phpdocumentor/type-resolver": "^0.2.0",
235
- "webmozart/assert": "^1.0"
236
- },
237
- "require-dev": {
238
- "mockery/mockery": "^0.9.4",
239
- "phpunit/phpunit": "^4.4"
240
- },
241
- "type": "library",
242
- "autoload": {
243
- "psr-4": {
244
- "phpDocumentor\\Reflection\\": [
245
- "src/"
246
- ]
247
- }
248
- },
249
- "notification-url": "https://packagist.org/downloads/",
250
- "license": [
251
- "MIT"
252
- ],
253
- "authors": [
254
- {
255
- "name": "Mike van Riel",
256
- "email": "me@mikevanriel.com"
257
- }
258
- ],
259
- "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.",
260
- "time": "2016-09-30 07:12:33"
261
- },
262
- {
263
- "name": "phpdocumentor/type-resolver",
264
- "version": "0.2.1",
265
- "source": {
266
- "type": "git",
267
- "url": "https://github.com/phpDocumentor/TypeResolver.git",
268
- "reference": "e224fb2ea2fba6d3ad6fdaef91cd09a172155ccb"
269
- },
270
- "dist": {
271
- "type": "zip",
272
- "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/e224fb2ea2fba6d3ad6fdaef91cd09a172155ccb",
273
- "reference": "e224fb2ea2fba6d3ad6fdaef91cd09a172155ccb",
274
- "shasum": ""
275
- },
276
- "require": {
277
- "php": ">=5.5",
278
- "phpdocumentor/reflection-common": "^1.0"
279
- },
280
- "require-dev": {
281
- "mockery/mockery": "^0.9.4",
282
- "phpunit/phpunit": "^5.2||^4.8.24"
283
- },
284
- "type": "library",
285
- "extra": {
286
- "branch-alias": {
287
- "dev-master": "1.0.x-dev"
288
- }
289
- },
290
- "autoload": {
291
- "psr-4": {
292
- "phpDocumentor\\Reflection\\": [
293
- "src/"
294
- ]
295
- }
296
- },
297
- "notification-url": "https://packagist.org/downloads/",
298
- "license": [
299
- "MIT"
300
- ],
301
- "authors": [
302
- {
303
- "name": "Mike van Riel",
304
- "email": "me@mikevanriel.com"
305
- }
306
- ],
307
- "time": "2016-11-25 06:54:22"
308
- },
309
- {
310
- "name": "phpspec/prophecy",
311
- "version": "dev-master",
312
- "source": {
313
- "type": "git",
314
- "url": "https://github.com/phpspec/prophecy.git",
315
- "reference": "6c52c2722f8460122f96f86346600e1077ce22cb"
316
- },
317
- "dist": {
318
- "type": "zip",
319
- "url": "https://api.github.com/repos/phpspec/prophecy/zipball/6c52c2722f8460122f96f86346600e1077ce22cb",
320
- "reference": "6c52c2722f8460122f96f86346600e1077ce22cb",
321
- "shasum": ""
322
- },
323
- "require": {
324
- "doctrine/instantiator": "^1.0.2",
325
- "php": "^5.3|^7.0",
326
- "phpdocumentor/reflection-docblock": "^2.0|^3.0.2",
327
- "sebastian/comparator": "^1.1",
328
- "sebastian/recursion-context": "^1.0|^2.0"
329
- },
330
- "require-dev": {
331
- "phpspec/phpspec": "^2.0",
332
- "phpunit/phpunit": "^4.8 || ^5.6.5"
333
- },
334
- "type": "library",
335
- "extra": {
336
- "branch-alias": {
337
- "dev-master": "1.6.x-dev"
338
- }
339
- },
340
- "autoload": {
341
- "psr-0": {
342
- "Prophecy\\": "src/"
343
- }
344
- },
345
- "notification-url": "https://packagist.org/downloads/",
346
- "license": [
347
- "MIT"
348
- ],
349
- "authors": [
350
- {
351
- "name": "Konstantin Kudryashov",
352
- "email": "ever.zet@gmail.com",
353
- "homepage": "http://everzet.com"
354
- },
355
- {
356
- "name": "Marcello Duarte",
357
- "email": "marcello.duarte@gmail.com"
358
- }
359
- ],
360
- "description": "Highly opinionated mocking framework for PHP 5.3+",
361
- "homepage": "https://github.com/phpspec/prophecy",
362
- "keywords": [
363
- "Double",
364
- "Dummy",
365
- "fake",
366
- "mock",
367
- "spy",
368
- "stub"
369
- ],
370
- "time": "2016-11-21 14:58:47"
371
- },
372
- {
373
- "name": "phpunit/php-code-coverage",
374
- "version": "2.2.x-dev",
375
- "source": {
376
- "type": "git",
377
- "url": "https://github.com/sebastianbergmann/php-code-coverage.git",
378
- "reference": "eabf68b476ac7d0f73793aada060f1c1a9bf8979"
379
- },
380
- "dist": {
381
- "type": "zip",
382
- "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/eabf68b476ac7d0f73793aada060f1c1a9bf8979",
383
- "reference": "eabf68b476ac7d0f73793aada060f1c1a9bf8979",
384
- "shasum": ""
385
- },
386
- "require": {
387
- "php": ">=5.3.3",
388
- "phpunit/php-file-iterator": "~1.3",
389
- "phpunit/php-text-template": "~1.2",
390
- "phpunit/php-token-stream": "~1.3",
391
- "sebastian/environment": "^1.3.2",
392
- "sebastian/version": "~1.0"
393
- },
394
- "require-dev": {
395
- "ext-xdebug": ">=2.1.4",
396
- "phpunit/phpunit": "~4"
397
- },
398
- "suggest": {
399
- "ext-dom": "*",
400
- "ext-xdebug": ">=2.2.1",
401
- "ext-xmlwriter": "*"
402
- },
403
- "type": "library",
404
- "extra": {
405
- "branch-alias": {
406
- "dev-master": "2.2.x-dev"
407
- }
408
- },
409
- "autoload": {
410
- "classmap": [
411
- "src/"
412
- ]
413
- },
414
- "notification-url": "https://packagist.org/downloads/",
415
- "license": [
416
- "BSD-3-Clause"
417
- ],
418
- "authors": [
419
- {
420
- "name": "Sebastian Bergmann",
421
- "email": "sb@sebastian-bergmann.de",
422
- "role": "lead"
423
- }
424
- ],
425
- "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.",
426
- "homepage": "https://github.com/sebastianbergmann/php-code-coverage",
427
- "keywords": [
428
- "coverage",
429
- "testing",
430
- "xunit"
431
- ],
432
- "time": "2015-10-06 15:47:00"
433
- },
434
- {
435
- "name": "phpunit/php-file-iterator",
436
- "version": "dev-master",
437
- "source": {
438
- "type": "git",
439
- "url": "https://github.com/sebastianbergmann/php-file-iterator.git",
440
- "reference": "3cc8f69b3028d0f96a9078e6295d86e9bf019be5"
441
- },
442
- "dist": {
443
- "type": "zip",
444
- "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/3cc8f69b3028d0f96a9078e6295d86e9bf019be5",
445
- "reference": "3cc8f69b3028d0f96a9078e6295d86e9bf019be5",
446
- "shasum": ""
447
- },
448
- "require": {
449
- "php": ">=5.3.3"
450
- },
451
- "type": "library",
452
- "extra": {
453
- "branch-alias": {
454
- "dev-master": "1.4.x-dev"
455
- }
456
- },
457
- "autoload": {
458
- "classmap": [
459
- "src/"
460
- ]
461
- },
462
- "notification-url": "https://packagist.org/downloads/",
463
- "license": [
464
- "BSD-3-Clause"
465
- ],
466
- "authors": [
467
- {
468
- "name": "Sebastian Bergmann",
469
- "email": "sb@sebastian-bergmann.de",
470
- "role": "lead"
471
- }
472
- ],
473
- "description": "FilterIterator implementation that filters files based on a list of suffixes.",
474
- "homepage": "https://github.com/sebastianbergmann/php-file-iterator/",
475
- "keywords": [
476
- "filesystem",
477
- "iterator"
478
- ],
479
- "time": "2016-10-03 07:40:28"
480
- },
481
- {
482
- "name": "phpunit/php-text-template",
483
- "version": "1.2.1",
484
- "source": {
485
- "type": "git",
486
- "url": "https://github.com/sebastianbergmann/php-text-template.git",
487
- "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686"
488
- },
489
- "dist": {
490
- "type": "zip",
491
- "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/31f8b717e51d9a2afca6c9f046f5d69fc27c8686",
492
- "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686",
493
- "shasum": ""
494
- },
495
- "require": {
496
- "php": ">=5.3.3"
497
- },
498
- "type": "library",
499
- "autoload": {
500
- "classmap": [
501
- "src/"
502
- ]
503
- },
504
- "notification-url": "https://packagist.org/downloads/",
505
- "license": [
506
- "BSD-3-Clause"
507
- ],
508
- "authors": [
509
- {
510
- "name": "Sebastian Bergmann",
511
- "email": "sebastian@phpunit.de",
512
- "role": "lead"
513
- }
514
- ],
515
- "description": "Simple template engine.",
516
- "homepage": "https://github.com/sebastianbergmann/php-text-template/",
517
- "keywords": [
518
- "template"
519
- ],
520
- "time": "2015-06-21 13:50:34"
521
- },
522
- {
523
- "name": "phpunit/php-timer",
524
- "version": "1.0.8",
525
- "source": {
526
- "type": "git",
527
- "url": "https://github.com/sebastianbergmann/php-timer.git",
528
- "reference": "38e9124049cf1a164f1e4537caf19c99bf1eb260"
529
- },
530
- "dist": {
531
- "type": "zip",
532
- "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/38e9124049cf1a164f1e4537caf19c99bf1eb260",
533
- "reference": "38e9124049cf1a164f1e4537caf19c99bf1eb260",
534
- "shasum": ""
535
- },
536
- "require": {
537
- "php": ">=5.3.3"
538
- },
539
- "require-dev": {
540
- "phpunit/phpunit": "~4|~5"
541
- },
542
- "type": "library",
543
- "autoload": {
544
- "classmap": [
545
- "src/"
546
- ]
547
- },
548
- "notification-url": "https://packagist.org/downloads/",
549
- "license": [
550
- "BSD-3-Clause"
551
- ],
552
- "authors": [
553
- {
554
- "name": "Sebastian Bergmann",
555
- "email": "sb@sebastian-bergmann.de",
556
- "role": "lead"
557
- }
558
- ],
559
- "description": "Utility class for timing",
560
- "homepage": "https://github.com/sebastianbergmann/php-timer/",
561
- "keywords": [
562
- "timer"
563
- ],
564
- "time": "2016-05-12 18:03:57"
565
- },
566
- {
567
- "name": "phpunit/php-token-stream",
568
- "version": "dev-master",
569
- "source": {
570
- "type": "git",
571
- "url": "https://github.com/sebastianbergmann/php-token-stream.git",
572
- "reference": "3b402f65a4cc90abf6e1104e388b896ce209631b"
573
- },
574
- "dist": {
575
- "type": "zip",
576
- "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/3b402f65a4cc90abf6e1104e388b896ce209631b",
577
- "reference": "3b402f65a4cc90abf6e1104e388b896ce209631b",
578
- "shasum": ""
579
- },
580
- "require": {
581
- "ext-tokenizer": "*",
582
- "php": ">=5.3.3"
583
- },
584
- "require-dev": {
585
- "phpunit/phpunit": "~4.2"
586
- },
587
- "type": "library",
588
- "extra": {
589
- "branch-alias": {
590
- "dev-master": "1.4-dev"
591
- }
592
- },
593
- "autoload": {
594
- "classmap": [
595
- "src/"
596
- ]
597
- },
598
- "notification-url": "https://packagist.org/downloads/",
599
- "license": [
600
- "BSD-3-Clause"
601
- ],
602
- "authors": [
603
- {
604
- "name": "Sebastian Bergmann",
605
- "email": "sebastian@phpunit.de"
606
- }
607
- ],
608
- "description": "Wrapper around PHP's tokenizer extension.",
609
- "homepage": "https://github.com/sebastianbergmann/php-token-stream/",
610
- "keywords": [
611
- "tokenizer"
612
- ],
613
- "time": "2016-11-15 14:06:22"
614
- },
615
- {
616
- "name": "phpunit/phpunit",
617
- "version": "4.8.x-dev",
618
- "source": {
619
- "type": "git",
620
- "url": "https://github.com/sebastianbergmann/phpunit.git",
621
- "reference": "50c123bc69f3950a5b754082392584f33a967628"
622
- },
623
- "dist": {
624
- "type": "zip",
625
- "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/50c123bc69f3950a5b754082392584f33a967628",
626
- "reference": "50c123bc69f3950a5b754082392584f33a967628",
627
- "shasum": ""
628
- },
629
- "require": {
630
- "ext-dom": "*",
631
- "ext-json": "*",
632
- "ext-pcre": "*",
633
- "ext-reflection": "*",
634
- "ext-spl": "*",
635
- "php": ">=5.3.3",
636
- "phpspec/prophecy": "^1.3.1",
637
- "phpunit/php-code-coverage": "~2.1",
638
- "phpunit/php-file-iterator": "~1.4",
639
- "phpunit/php-text-template": "~1.2",
640
- "phpunit/php-timer": "^1.0.6",
641
- "phpunit/phpunit-mock-objects": "~2.3",
642
- "sebastian/comparator": "~1.2.2",
643
- "sebastian/diff": "~1.2",
644
- "sebastian/environment": "~1.3",
645
- "sebastian/exporter": "~1.2",
646
- "sebastian/global-state": "~1.0",
647
- "sebastian/version": "~1.0",
648
- "symfony/yaml": "~2.1|~3.0"
649
- },
650
- "suggest": {
651
- "phpunit/php-invoker": "~1.1"
652
- },
653
- "bin": [
654
- "phpunit"
655
- ],
656
- "type": "library",
657
- "extra": {
658
- "branch-alias": {
659
- "dev-master": "4.8.x-dev"
660
- }
661
- },
662
- "autoload": {
663
- "classmap": [
664
- "src/"
665
- ]
666
- },
667
- "notification-url": "https://packagist.org/downloads/",
668
- "license": [
669
- "BSD-3-Clause"
670
- ],
671
- "authors": [
672
- {
673
- "name": "Sebastian Bergmann",
674
- "email": "sebastian@phpunit.de",
675
- "role": "lead"
676
- }
677
- ],
678
- "description": "The PHP Unit Testing framework.",
679
- "homepage": "https://phpunit.de/",
680
- "keywords": [
681
- "phpunit",
682
- "testing",
683
- "xunit"
684
- ],
685
- "time": "2017-01-22 17:14:06"
686
- },
687
- {
688
- "name": "phpunit/phpunit-mock-objects",
689
- "version": "2.3.x-dev",
690
- "source": {
691
- "type": "git",
692
- "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git",
693
- "reference": "ac8e7a3db35738d56ee9a76e78a4e03d97628983"
694
- },
695
- "dist": {
696
- "type": "zip",
697
- "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/ac8e7a3db35738d56ee9a76e78a4e03d97628983",
698
- "reference": "ac8e7a3db35738d56ee9a76e78a4e03d97628983",
699
- "shasum": ""
700
- },
701
- "require": {
702
- "doctrine/instantiator": "^1.0.2",
703
- "php": ">=5.3.3",
704
- "phpunit/php-text-template": "~1.2",
705
- "sebastian/exporter": "~1.2"
706
- },
707
- "require-dev": {
708
- "phpunit/phpunit": "~4.4"
709
- },
710
- "suggest": {
711
- "ext-soap": "*"
712
- },
713
- "type": "library",
714
- "extra": {
715
- "branch-alias": {
716
- "dev-master": "2.3.x-dev"
717
- }
718
- },
719
- "autoload": {
720
- "classmap": [
721
- "src/"
722
- ]
723
- },
724
- "notification-url": "https://packagist.org/downloads/",
725
- "license": [
726
- "BSD-3-Clause"
727
- ],
728
- "authors": [
729
- {
730
- "name": "Sebastian Bergmann",
731
- "email": "sb@sebastian-bergmann.de",
732
- "role": "lead"
733
- }
734
- ],
735
- "description": "Mock Object library for PHPUnit",
736
- "homepage": "https://github.com/sebastianbergmann/phpunit-mock-objects/",
737
- "keywords": [
738
- "mock",
739
- "xunit"
740
- ],
741
- "time": "2015-10-02 06:51:40"
742
- },
743
- {
744
- "name": "psr/log",
745
- "version": "dev-master",
746
- "source": {
747
- "type": "git",
748
- "url": "https://github.com/php-fig/log.git",
749
- "reference": "4ebe3a8bf773a19edfe0a84b6585ba3d401b724d"
750
- },
751
- "dist": {
752
- "type": "zip",
753
- "url": "https://api.github.com/repos/php-fig/log/zipball/4ebe3a8bf773a19edfe0a84b6585ba3d401b724d",
754
- "reference": "4ebe3a8bf773a19edfe0a84b6585ba3d401b724d",
755
- "shasum": ""
756
- },
757
- "require": {
758
- "php": ">=5.3.0"
759
- },
760
- "type": "library",
761
- "extra": {
762
- "branch-alias": {
763
- "dev-master": "1.0.x-dev"
764
- }
765
- },
766
- "autoload": {
767
- "psr-4": {
768
- "Psr\\Log\\": "Psr/Log/"
769
- }
770
- },
771
- "notification-url": "https://packagist.org/downloads/",
772
- "license": [
773
- "MIT"
774
- ],
775
- "authors": [
776
- {
777
- "name": "PHP-FIG",
778
- "homepage": "http://www.php-fig.org/"
779
- }
780
- ],
781
- "description": "Common interface for logging libraries",
782
- "homepage": "https://github.com/php-fig/log",
783
- "keywords": [
784
- "log",
785
- "psr",
786
- "psr-3"
787
- ],
788
- "time": "2016-10-10 12:19:37"
789
- },
790
- {
791
- "name": "ptrofimov/xpmock",
792
- "version": "1.1.5",
793
- "source": {
794
- "type": "git",
795
- "url": "https://github.com/ptrofimov/xpmock.git",
796
- "reference": "5b95ace33624b66bf4e854071b8856722fde515e"
797
- },
798
- "dist": {
799
- "type": "zip",
800
- "url": "https://api.github.com/repos/ptrofimov/xpmock/zipball/5b95ace33624b66bf4e854071b8856722fde515e",
801
- "reference": "5b95ace33624b66bf4e854071b8856722fde515e",
802
- "shasum": ""
803
- },
804
- "require": {
805
- "php": ">=5.3.0"
806
- },
807
- "require-dev": {
808
- "phpunit/phpunit": "3.7.*"
809
- },
810
- "type": "library",
811
- "autoload": {
812
- "psr-0": {
813
- "Xpmock": "src"
814
- }
815
- },
816
- "notification-url": "https://packagist.org/downloads/",
817
- "license": [
818
- "MIT"
819
- ],
820
- "description": "PHPUnit: simple syntax to create mock-objects",
821
- "time": "2014-01-02 16:42:27"
822
- },
823
- {
824
- "name": "sebastian/comparator",
825
- "version": "dev-master",
826
- "source": {
827
- "type": "git",
828
- "url": "https://github.com/sebastianbergmann/comparator.git",
829
- "reference": "2f09d5a251c4a92d1a80518c2166b5d0d742bc63"
830
- },
831
- "dist": {
832
- "type": "zip",
833
- "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/2f09d5a251c4a92d1a80518c2166b5d0d742bc63",
834
- "reference": "2f09d5a251c4a92d1a80518c2166b5d0d742bc63",
835
- "shasum": ""
836
- },
837
- "require": {
838
- "php": "^5.3.3 || ^7.0",
839
- "sebastian/diff": "^1.2",
840
- "sebastian/exporter": "^1.2 || ^2.0"
841
- },
842
- "require-dev": {
843
- "phpunit/phpunit": "^4.8"
844
- },
845
- "type": "library",
846
- "extra": {
847
- "branch-alias": {
848
- "dev-master": "1.2.x-dev"
849
- }
850
- },
851
- "autoload": {
852
- "classmap": [
853
- "src/"
854
- ]
855
- },
856
- "notification-url": "https://packagist.org/downloads/",
857
- "license": [
858
- "BSD-3-Clause"
859
- ],
860
- "authors": [
861
- {
862
- "name": "Jeff Welch",
863
- "email": "whatthejeff@gmail.com"
864
- },
865
- {
866
- "name": "Volker Dusch",
867
- "email": "github@wallbash.com"
868
- },
869
- {
870
- "name": "Bernhard Schussek",
871
- "email": "bschussek@2bepublished.at"
872
- },
873
- {
874
- "name": "Sebastian Bergmann",
875
- "email": "sebastian@phpunit.de"
876
- }
877
- ],
878
- "description": "Provides the functionality to compare PHP values for equality",
879
- "homepage": "http://www.github.com/sebastianbergmann/comparator",
880
- "keywords": [
881
- "comparator",
882
- "compare",
883
- "equality"
884
- ],
885
- "time": "2016-12-10 08:07:52"
886
- },
887
- {
888
- "name": "sebastian/diff",
889
- "version": "dev-master",
890
- "source": {
891
- "type": "git",
892
- "url": "https://github.com/sebastianbergmann/diff.git",
893
- "reference": "d0814318784b7756fb932116acd19ee3b0cbe67a"
894
- },
895
- "dist": {
896
- "type": "zip",
897
- "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/d0814318784b7756fb932116acd19ee3b0cbe67a",
898
- "reference": "d0814318784b7756fb932116acd19ee3b0cbe67a",
899
- "shasum": ""
900
- },
901
- "require": {
902
- "php": ">=5.3.3"
903
- },
904
- "require-dev": {
905
- "phpunit/phpunit": "~4.8"
906
- },
907
- "type": "library",
908
- "extra": {
909
- "branch-alias": {
910
- "dev-master": "1.4-dev"
911
- }
912
- },
913
- "autoload": {
914
- "classmap": [
915
- "src/"
916
- ]
917
- },
918
- "notification-url": "https://packagist.org/downloads/",
919
- "license": [
920
- "BSD-3-Clause"
921
- ],
922
- "authors": [
923
- {
924
- "name": "Kore Nordmann",
925
- "email": "mail@kore-nordmann.de"
926
- },
927
- {
928
- "name": "Sebastian Bergmann",
929
- "email": "sebastian@phpunit.de"
930
- }
931
- ],
932
- "description": "Diff implementation",
933
- "homepage": "https://github.com/sebastianbergmann/diff",
934
- "keywords": [
935
- "diff"
936
- ],
937
- "time": "2016-10-03 07:45:03"
938
- },
939
- {
940
- "name": "sebastian/environment",
941
- "version": "1.3.x-dev",
942
- "source": {
943
- "type": "git",
944
- "url": "https://github.com/sebastianbergmann/environment.git",
945
- "reference": "be2c607e43ce4c89ecd60e75c6a85c126e754aea"
946
- },
947
- "dist": {
948
- "type": "zip",
949
- "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/be2c607e43ce4c89ecd60e75c6a85c126e754aea",
950
- "reference": "be2c607e43ce4c89ecd60e75c6a85c126e754aea",
951
- "shasum": ""
952
- },
953
- "require": {
954
- "php": "^5.3.3 || ^7.0"
955
- },
956
- "require-dev": {
957
- "phpunit/phpunit": "^4.8 || ^5.0"
958
- },
959
- "type": "library",
960
- "extra": {
961
- "branch-alias": {
962
- "dev-master": "1.3.x-dev"
963
- }
964
- },
965
- "autoload": {
966
- "classmap": [
967
- "src/"
968
- ]
969
- },
970
- "notification-url": "https://packagist.org/downloads/",
971
- "license": [
972
- "BSD-3-Clause"
973
- ],
974
- "authors": [
975
- {
976
- "name": "Sebastian Bergmann",
977
- "email": "sebastian@phpunit.de"
978
- }
979
- ],
980
- "description": "Provides functionality to handle HHVM/PHP environments",
981
- "homepage": "http://www.github.com/sebastianbergmann/environment",
982
- "keywords": [
983
- "Xdebug",
984
- "environment",
985
- "hhvm"
986
- ],
987
- "time": "2016-08-18 05:49:44"
988
- },
989
- {
990
- "name": "sebastian/exporter",
991
- "version": "1.2.x-dev",
992
- "source": {
993
- "type": "git",
994
- "url": "https://github.com/sebastianbergmann/exporter.git",
995
- "reference": "7dfcd2418aacbdb5e123fb23ac735acfdd6c588d"
996
- },
997
- "dist": {
998
- "type": "zip",
999
- "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/7dfcd2418aacbdb5e123fb23ac735acfdd6c588d",
1000
- "reference": "7dfcd2418aacbdb5e123fb23ac735acfdd6c588d",
1001
- "shasum": ""
1002
- },
1003
- "require": {
1004
- "php": ">=5.3.3",
1005
- "sebastian/recursion-context": "~1.0"
1006
- },
1007
- "require-dev": {
1008
- "ext-mbstring": "*",
1009
- "phpunit/phpunit": "~4.4"
1010
- },
1011
- "type": "library",
1012
- "extra": {
1013
- "branch-alias": {
1014
- "dev-master": "1.3.x-dev"
1015
- }
1016
- },
1017
- "autoload": {
1018
- "classmap": [
1019
- "src/"
1020
- ]
1021
- },
1022
- "notification-url": "https://packagist.org/downloads/",
1023
- "license": [
1024
- "BSD-3-Clause"
1025
- ],
1026
- "authors": [
1027
- {
1028
- "name": "Jeff Welch",
1029
- "email": "whatthejeff@gmail.com"
1030
- },
1031
- {
1032
- "name": "Volker Dusch",
1033
- "email": "github@wallbash.com"
1034
- },
1035
- {
1036
- "name": "Bernhard Schussek",
1037
- "email": "bschussek@2bepublished.at"
1038
- },
1039
- {
1040
- "name": "Sebastian Bergmann",
1041
- "email": "sebastian@phpunit.de"
1042
- },
1043
- {
1044
- "name": "Adam Harvey",
1045
- "email": "aharvey@php.net"
1046
- }
1047
- ],
1048
- "description": "Provides the functionality to export PHP variables for visualization",
1049
- "homepage": "http://www.github.com/sebastianbergmann/exporter",
1050
- "keywords": [
1051
- "export",
1052
- "exporter"
1053
- ],
1054
- "time": "2016-10-03 07:44:30"
1055
- },
1056
- {
1057
- "name": "sebastian/global-state",
1058
- "version": "1.1.x-dev",
1059
- "source": {
1060
- "type": "git",
1061
- "url": "https://github.com/sebastianbergmann/global-state.git",
1062
- "reference": "5a2b9ba59e8cf82fd1fdd7efb7d7846fd69ac36d"
1063
- },
1064
- "dist": {
1065
- "type": "zip",
1066
- "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/5a2b9ba59e8cf82fd1fdd7efb7d7846fd69ac36d",
1067
- "reference": "5a2b9ba59e8cf82fd1fdd7efb7d7846fd69ac36d",
1068
- "shasum": ""
1069
- },
1070
- "require": {
1071
- "php": ">=5.3.3"
1072
- },
1073
- "require-dev": {
1074
- "phpunit/phpunit": "~4.2|~5.0"
1075
- },
1076
- "suggest": {
1077
- "ext-uopz": "*"
1078
- },
1079
- "type": "library",
1080
- "extra": {
1081
- "branch-alias": {
1082
- "dev-master": "1.0-dev"
1083
- }
1084
- },
1085
- "autoload": {
1086
- "classmap": [
1087
- "src/"
1088
- ]
1089
- },
1090
- "notification-url": "https://packagist.org/downloads/",
1091
- "license": [
1092
- "BSD-3-Clause"
1093
- ],
1094
- "authors": [
1095
- {
1096
- "name": "Sebastian Bergmann",
1097
- "email": "sebastian@phpunit.de"
1098
- }
1099
- ],
1100
- "description": "Snapshotting of global state",
1101
- "homepage": "http://www.github.com/sebastianbergmann/global-state",
1102
- "keywords": [
1103
- "global state"
1104
- ],
1105
- "time": "2016-10-03 07:46:22"
1106
- },
1107
- {
1108
- "name": "sebastian/recursion-context",
1109
- "version": "1.0.x-dev",
1110
- "source": {
1111
- "type": "git",
1112
- "url": "https://github.com/sebastianbergmann/recursion-context.git",
1113
- "reference": "b19cc3298482a335a95f3016d2f8a6950f0fbcd7"
1114
- },
1115
- "dist": {
1116
- "type": "zip",
1117
- "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/b19cc3298482a335a95f3016d2f8a6950f0fbcd7",
1118
- "reference": "b19cc3298482a335a95f3016d2f8a6950f0fbcd7",
1119
- "shasum": ""
1120
- },
1121
- "require": {
1122
- "php": ">=5.3.3"
1123
- },
1124
- "require-dev": {
1125
- "phpunit/phpunit": "~4.4"
1126
- },
1127
- "type": "library",
1128
- "extra": {
1129
- "branch-alias": {
1130
- "dev-master": "1.0.x-dev"
1131
- }
1132
- },
1133
- "autoload": {
1134
- "classmap": [
1135
- "src/"
1136
- ]
1137
- },
1138
- "notification-url": "https://packagist.org/downloads/",
1139
- "license": [
1140
- "BSD-3-Clause"
1141
- ],
1142
- "authors": [
1143
- {
1144
- "name": "Jeff Welch",
1145
- "email": "whatthejeff@gmail.com"
1146
- },
1147
- {
1148
- "name": "Sebastian Bergmann",
1149
- "email": "sebastian@phpunit.de"
1150
- },
1151
- {
1152
- "name": "Adam Harvey",
1153
- "email": "aharvey@php.net"
1154
- }
1155
- ],
1156
- "description": "Provides functionality to recursively process PHP variables",
1157
- "homepage": "http://www.github.com/sebastianbergmann/recursion-context",
1158
- "time": "2016-10-03 07:41:43"
1159
- },
1160
- {
1161
- "name": "sebastian/version",
1162
- "version": "1.0.6",
1163
- "source": {
1164
- "type": "git",
1165
- "url": "https://github.com/sebastianbergmann/version.git",
1166
- "reference": "58b3a85e7999757d6ad81c787a1fbf5ff6c628c6"
1167
- },
1168
- "dist": {
1169
- "type": "zip",
1170
- "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/58b3a85e7999757d6ad81c787a1fbf5ff6c628c6",
1171
- "reference": "58b3a85e7999757d6ad81c787a1fbf5ff6c628c6",
1172
- "shasum": ""
1173
- },
1174
- "type": "library",
1175
- "autoload": {
1176
- "classmap": [
1177
- "src/"
1178
- ]
1179
- },
1180
- "notification-url": "https://packagist.org/downloads/",
1181
- "license": [
1182
- "BSD-3-Clause"
1183
- ],
1184
- "authors": [
1185
- {
1186
- "name": "Sebastian Bergmann",
1187
- "email": "sebastian@phpunit.de",
1188
- "role": "lead"
1189
- }
1190
- ],
1191
- "description": "Library that helps with managing the version number of Git-hosted PHP projects",
1192
- "homepage": "https://github.com/sebastianbergmann/version",
1193
- "time": "2015-06-21 13:59:46"
1194
- },
1195
- {
1196
- "name": "symfony/console",
1197
- "version": "dev-master",
1198
- "source": {
1199
- "type": "git",
1200
- "url": "https://github.com/symfony/console.git",
1201
- "reference": "4272e242823935c74c4090aa9b60bcf0d42f2a2e"
1202
- },
1203
- "dist": {
1204
- "type": "zip",
1205
- "url": "https://api.github.com/repos/symfony/console/zipball/4272e242823935c74c4090aa9b60bcf0d42f2a2e",
1206
- "reference": "4272e242823935c74c4090aa9b60bcf0d42f2a2e",
1207
- "shasum": ""
1208
- },
1209
- "require": {
1210
- "php": ">=5.5.9",
1211
- "symfony/debug": "~2.8|~3.0",
1212
- "symfony/polyfill-mbstring": "~1.0"
1213
- },
1214
- "require-dev": {
1215
- "psr/log": "~1.0",
1216
- "symfony/dependency-injection": "~2.8|~3.0",
1217
- "symfony/event-dispatcher": "~2.8|~3.0",
1218
- "symfony/filesystem": "~2.8|~3.0",
1219
- "symfony/http-kernel": "~2.8|~3.0",
1220
- "symfony/process": "~2.8|~3.0"
1221
- },
1222
- "suggest": {
1223
- "psr/log": "For using the console logger",
1224
- "symfony/event-dispatcher": "",
1225
- "symfony/filesystem": "",
1226
- "symfony/process": ""
1227
- },
1228
- "type": "library",
1229
- "extra": {
1230
- "branch-alias": {
1231
- "dev-master": "3.3-dev"
1232
- }
1233
- },
1234
- "autoload": {
1235
- "psr-4": {
1236
- "Symfony\\Component\\Console\\": ""
1237
- },
1238
- "exclude-from-classmap": [
1239
- "/Tests/"
1240
- ]
1241
- },
1242
- "notification-url": "https://packagist.org/downloads/",
1243
- "license": [
1244
- "MIT"
1245
- ],
1246
- "authors": [
1247
- {
1248
- "name": "Fabien Potencier",
1249
- "email": "fabien@symfony.com"
1250
- },
1251
- {
1252
- "name": "Symfony Community",
1253
- "homepage": "https://symfony.com/contributors"
1254
- }
1255
- ],
1256
- "description": "Symfony Console Component",
1257
- "homepage": "https://symfony.com",
1258
- "time": "2017-01-21 17:19:16"
1259
- },
1260
- {
1261
- "name": "symfony/debug",
1262
- "version": "dev-master",
1263
- "source": {
1264
- "type": "git",
1265
- "url": "https://github.com/symfony/debug.git",
1266
- "reference": "8dfba97c33692aef9b0f85d9b38a73972bfd7b77"
1267
- },
1268
- "dist": {
1269
- "type": "zip",
1270
- "url": "https://api.github.com/repos/symfony/debug/zipball/8dfba97c33692aef9b0f85d9b38a73972bfd7b77",
1271
- "reference": "8dfba97c33692aef9b0f85d9b38a73972bfd7b77",
1272
- "shasum": ""
1273
- },
1274
- "require": {
1275
- "php": ">=5.5.9",
1276
- "psr/log": "~1.0"
1277
- },
1278
- "conflict": {
1279
- "symfony/http-kernel": ">=2.3,<2.3.24|~2.4.0|>=2.5,<2.5.9|>=2.6,<2.6.2"
1280
- },
1281
- "require-dev": {
1282
- "symfony/http-kernel": "~2.8|~3.0"
1283
- },
1284
- "type": "library",
1285
- "extra": {
1286
- "branch-alias": {
1287
- "dev-master": "3.3-dev"
1288
- }
1289
- },
1290
- "autoload": {
1291
- "psr-4": {
1292
- "Symfony\\Component\\Debug\\": ""
1293
- },
1294
- "exclude-from-classmap": [
1295
- "/Tests/"
1296
- ]
1297
- },
1298
- "notification-url": "https://packagist.org/downloads/",
1299
- "license": [
1300
- "MIT"
1301
- ],
1302
- "authors": [
1303
- {
1304
- "name": "Fabien Potencier",
1305
- "email": "fabien@symfony.com"
1306
- },
1307
- {
1308
- "name": "Symfony Community",
1309
- "homepage": "https://symfony.com/contributors"
1310
- }
1311
- ],
1312
- "description": "Symfony Debug Component",
1313
- "homepage": "https://symfony.com",
1314
- "time": "2017-01-23 08:28:52"
1315
- },
1316
- {
1317
- "name": "symfony/event-dispatcher",
1318
- "version": "dev-master",
1319
- "source": {
1320
- "type": "git",
1321
- "url": "https://github.com/symfony/event-dispatcher.git",
1322
- "reference": "26e38eefa5b9333fa94e845541f5f025a98fbe2d"
1323
- },
1324
- "dist": {
1325
- "type": "zip",
1326
- "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/26e38eefa5b9333fa94e845541f5f025a98fbe2d",
1327
- "reference": "26e38eefa5b9333fa94e845541f5f025a98fbe2d",
1328
- "shasum": ""
1329
- },
1330
- "require": {
1331
- "php": ">=5.5.9"
1332
- },
1333
- "conflict": {
1334
- "symfony/dependency-injection": "<3.3"
1335
- },
1336
- "require-dev": {
1337
- "psr/log": "~1.0",
1338
- "symfony/config": "~2.8|~3.0",
1339
- "symfony/dependency-injection": "~3.3",
1340
- "symfony/expression-language": "~2.8|~3.0",
1341
- "symfony/stopwatch": "~2.8|~3.0"
1342
- },
1343
- "suggest": {
1344
- "symfony/dependency-injection": "",
1345
- "symfony/http-kernel": ""
1346
- },
1347
- "type": "library",
1348
- "extra": {
1349
- "branch-alias": {
1350
- "dev-master": "3.3-dev"
1351
- }
1352
- },
1353
- "autoload": {
1354
- "psr-4": {
1355
- "Symfony\\Component\\EventDispatcher\\": ""
1356
- },
1357
- "exclude-from-classmap": [
1358
- "/Tests/"
1359
- ]
1360
- },
1361
- "notification-url": "https://packagist.org/downloads/",
1362
- "license": [
1363
- "MIT"
1364
- ],
1365
- "authors": [
1366
- {
1367
- "name": "Fabien Potencier",
1368
- "email": "fabien@symfony.com"
1369
- },
1370
- {
1371
- "name": "Symfony Community",
1372
- "homepage": "https://symfony.com/contributors"
1373
- }
1374
- ],
1375
- "description": "Symfony EventDispatcher Component",
1376
- "homepage": "https://symfony.com",
1377
- "time": "2017-01-07 15:57:09"
1378
- },
1379
- {
1380
- "name": "symfony/filesystem",
1381
- "version": "dev-master",
1382
- "source": {
1383
- "type": "git",
1384
- "url": "https://github.com/symfony/filesystem.git",
1385
- "reference": "b2de62936fea037d501159f52b7b6172cc962282"
1386
- },
1387
- "dist": {
1388
- "type": "zip",
1389
- "url": "https://api.github.com/repos/symfony/filesystem/zipball/b2de62936fea037d501159f52b7b6172cc962282",
1390
- "reference": "b2de62936fea037d501159f52b7b6172cc962282",
1391
- "shasum": ""
1392
- },
1393
- "require": {
1394
- "php": ">=5.5.9"
1395
- },
1396
- "type": "library",
1397
- "extra": {
1398
- "branch-alias": {
1399
- "dev-master": "3.3-dev"
1400
- }
1401
- },
1402
- "autoload": {
1403
- "psr-4": {
1404
- "Symfony\\Component\\Filesystem\\": ""
1405
- },
1406
- "exclude-from-classmap": [
1407
- "/Tests/"
1408
- ]
1409
- },
1410
- "notification-url": "https://packagist.org/downloads/",
1411
- "license": [
1412
- "MIT"
1413
- ],
1414
- "authors": [
1415
- {
1416
- "name": "Fabien Potencier",
1417
- "email": "fabien@symfony.com"
1418
- },
1419
- {
1420
- "name": "Symfony Community",
1421
- "homepage": "https://symfony.com/contributors"
1422
- }
1423
- ],
1424
- "description": "Symfony Filesystem Component",
1425
- "homepage": "https://symfony.com",
1426
- "time": "2017-01-08 21:15:04"
1427
- },
1428
- {
1429
- "name": "symfony/finder",
1430
- "version": "dev-master",
1431
- "source": {
1432
- "type": "git",
1433
- "url": "https://github.com/symfony/finder.git",
1434
- "reference": "791ac099b1687c0bd82f7230ec0d8fc8550c81dc"
1435
- },
1436
- "dist": {
1437
- "type": "zip",
1438
- "url": "https://api.github.com/repos/symfony/finder/zipball/791ac099b1687c0bd82f7230ec0d8fc8550c81dc",
1439
- "reference": "791ac099b1687c0bd82f7230ec0d8fc8550c81dc",
1440
- "shasum": ""
1441
- },
1442
- "require": {
1443
- "php": ">=5.5.9"
1444
- },
1445
- "type": "library",
1446
- "extra": {
1447
- "branch-alias": {
1448
- "dev-master": "3.3-dev"
1449
- }
1450
- },
1451
- "autoload": {
1452
- "psr-4": {
1453
- "Symfony\\Component\\Finder\\": ""
1454
- },
1455
- "exclude-from-classmap": [
1456
- "/Tests/"
1457
- ]
1458
- },
1459
- "notification-url": "https://packagist.org/downloads/",
1460
- "license": [
1461
- "MIT"
1462
- ],
1463
- "authors": [
1464
- {
1465
- "name": "Fabien Potencier",
1466
- "email": "fabien@symfony.com"
1467
- },
1468
- {
1469
- "name": "Symfony Community",
1470
- "homepage": "https://symfony.com/contributors"
1471
- }
1472
- ],
1473
- "description": "Symfony Finder Component",
1474
- "homepage": "https://symfony.com",
1475
- "time": "2017-01-02 20:33:09"
1476
- },
1477
- {
1478
- "name": "symfony/polyfill-mbstring",
1479
- "version": "dev-master",
1480
- "source": {
1481
- "type": "git",
1482
- "url": "https://github.com/symfony/polyfill-mbstring.git",
1483
- "reference": "e79d363049d1c2128f133a2667e4f4190904f7f4"
1484
- },
1485
- "dist": {
1486
- "type": "zip",
1487
- "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/e79d363049d1c2128f133a2667e4f4190904f7f4",
1488
- "reference": "e79d363049d1c2128f133a2667e4f4190904f7f4",
1489
- "shasum": ""
1490
- },
1491
- "require": {
1492
- "php": ">=5.3.3"
1493
- },
1494
- "suggest": {
1495
- "ext-mbstring": "For best performance"
1496
- },
1497
- "type": "library",
1498
- "extra": {
1499
- "branch-alias": {
1500
- "dev-master": "1.3-dev"
1501
- }
1502
- },
1503
- "autoload": {
1504
- "psr-4": {
1505
- "Symfony\\Polyfill\\Mbstring\\": ""
1506
- },
1507
- "files": [
1508
- "bootstrap.php"
1509
- ]
1510
- },
1511
- "notification-url": "https://packagist.org/downloads/",
1512
- "license": [
1513
- "MIT"
1514
- ],
1515
- "authors": [
1516
- {
1517
- "name": "Nicolas Grekas",
1518
- "email": "p@tchwork.com"
1519
- },
1520
- {
1521
- "name": "Symfony Community",
1522
- "homepage": "https://symfony.com/contributors"
1523
- }
1524
- ],
1525
- "description": "Symfony polyfill for the Mbstring extension",
1526
- "homepage": "https://symfony.com",
1527
- "keywords": [
1528
- "compatibility",
1529
- "mbstring",
1530
- "polyfill",
1531
- "portable",
1532
- "shim"
1533
- ],
1534
- "time": "2016-11-14 01:06:16"
1535
- },
1536
- {
1537
- "name": "symfony/process",
1538
- "version": "dev-master",
1539
- "source": {
1540
- "type": "git",
1541
- "url": "https://github.com/symfony/process.git",
1542
- "reference": "31e5a3078c061925cc8d91b4d55f1ba4c895efc7"
1543
- },
1544
- "dist": {
1545
- "type": "zip",
1546
- "url": "https://api.github.com/repos/symfony/process/zipball/31e5a3078c061925cc8d91b4d55f1ba4c895efc7",
1547
- "reference": "31e5a3078c061925cc8d91b4d55f1ba4c895efc7",
1548
- "shasum": ""
1549
- },
1550
- "require": {
1551
- "php": ">=5.5.9"
1552
- },
1553
- "type": "library",
1554
- "extra": {
1555
- "branch-alias": {
1556
- "dev-master": "3.3-dev"
1557
- }
1558
- },
1559
- "autoload": {
1560
- "psr-4": {
1561
- "Symfony\\Component\\Process\\": ""
1562
- },
1563
- "exclude-from-classmap": [
1564
- "/Tests/"
1565
- ]
1566
- },
1567
- "notification-url": "https://packagist.org/downloads/",
1568
- "license": [
1569
- "MIT"
1570
- ],
1571
- "authors": [
1572
- {
1573
- "name": "Fabien Potencier",
1574
- "email": "fabien@symfony.com"
1575
- },
1576
- {
1577
- "name": "Symfony Community",
1578
- "homepage": "https://symfony.com/contributors"
1579
- }
1580
- ],
1581
- "description": "Symfony Process Component",
1582
- "homepage": "https://symfony.com",
1583
- "time": "2017-01-21 17:19:16"
1584
- },
1585
- {
1586
- "name": "symfony/stopwatch",
1587
- "version": "dev-master",
1588
- "source": {
1589
- "type": "git",
1590
- "url": "https://github.com/symfony/stopwatch.git",
1591
- "reference": "edfe3407825f9657fd38a05171eb5b8df8563146"
1592
- },
1593
- "dist": {
1594
- "type": "zip",
1595
- "url": "https://api.github.com/repos/symfony/stopwatch/zipball/edfe3407825f9657fd38a05171eb5b8df8563146",
1596
- "reference": "edfe3407825f9657fd38a05171eb5b8df8563146",
1597
- "shasum": ""
1598
- },
1599
- "require": {
1600
- "php": ">=5.5.9"
1601
- },
1602
- "type": "library",
1603
- "extra": {
1604
- "branch-alias": {
1605
- "dev-master": "3.3-dev"
1606
- }
1607
- },
1608
- "autoload": {
1609
- "psr-4": {
1610
- "Symfony\\Component\\Stopwatch\\": ""
1611
- },
1612
- "exclude-from-classmap": [
1613
- "/Tests/"
1614
- ]
1615
- },
1616
- "notification-url": "https://packagist.org/downloads/",
1617
- "license": [
1618
- "MIT"
1619
- ],
1620
-