@@ -21,8 +21,16 @@ abstract protected function getDisplayName();
2121
2222 /** @return string */
2323 abstract protected function getDashboardDomain ();
24+
25+ /** @return string */
26+ abstract protected function getSystemKey ();
27+
28+ private $ curl ;
29+
2430 const SYNC_URL = 'https://%s/webshops/sync_url ' ;
2531
32+ const CONSENT_URL = 'https://%s/api/2.0/order_permissions.json?%s ' ;
33+
2634 public function __construct () {
2735 $ this ->name = $ this ->getName ();
2836 $ this ->tab = 'pricing_promotion ' ;
@@ -96,38 +104,16 @@ private function sendSyncUrl(): void {
96104 'api_key ' => Configuration::get ($ this ->getConfigName ('API_KEY ' )),
97105 'url ' => Context::getContext ()->link ->getModuleLink ($ this ->getName (), 'sync ' ),
98106 ];
99- try {
100- $ this ->doSendSyncUrl ($ url , $ data );
101- } catch (\Exception $ e ) {
102- PrestaShopLogger::addLog (sprintf ('Sending sync URL to Dashboard failed with error %s ' , $ e ->getMessage ()));
103- }
104- }
105-
106- /**
107- * @throws \Exception
108- */
109- private function doSendSyncUrl (string $ url , array $ data ): void {
110- $ curl = curl_init ();
111107 $ options = [
112- CURLOPT_RETURNTRANSFER => true ,
113- CURLOPT_FAILONERROR => true ,
114- CURLOPT_FOLLOWLOCATION => true ,
115- CURLOPT_POST => true ,
116108 CURLOPT_POSTFIELDS => json_encode ($ data ),
117109 CURLOPT_HTTPHEADER => ['Content-Type:application/json ' ],
118- CURLOPT_URL => $ url ,
119110 CURLOPT_TIMEOUT => 10 ,
120111 ];
121- if (!curl_setopt_array ($ curl , $ options )) {
122- throw new \Exception ('Could not set cURL options ' );
123- }
124-
125- $ response = curl_exec ($ curl );
126- if ($ response === false ) {
127- throw new \Exception (sprintf ('(%s) %s ' , curl_errno ($ curl ), curl_error ($ curl )));
112+ try {
113+ $ this ->request ($ url , 'POST ' , $ options );
114+ } catch (\Exception $ e ) {
115+ PrestaShopLogger::addLog (sprintf ('Sending sync URL to Dashboard failed with error %s ' , $ e ->getMessage ()));
128116 }
129-
130- curl_close ($ curl );
131117 }
132118
133119 private function execSQL ($ query ) {
@@ -156,7 +142,7 @@ public function uninstall() {
156142 return parent ::uninstall ();
157143 }
158144
159- public function hookHeader ($ params ) {
145+ public function hookDisplayHeader ($ params ) {
160146 if (!Configuration::get ($ this ->getConfigName ('JAVASCRIPT ' ))) {
161147 return "<!-- {$ this ->getDisplayName ()}: JS disabled --> \n" ;
162148 }
@@ -175,7 +161,27 @@ public function hookHeader($params) {
175161 ]);
176162 }
177163
178- public function hookFooter ($ params ) {
164+
165+ public function hookDisplayOrderConfirmation ($ params ) {
166+ $ order = $ params ['order ' ];
167+ $ customer = new \Customer ((int ) $ order ->id_customer );
168+ $ ps_shop_id = $ order ->id_shop ;
169+ $ webshop_id = Configuration::get ($ this ->getConfigName ('SHOP_ID ' ), null , null , $ ps_shop_id );
170+
171+ return $ this ->render ('consent_data ' , [
172+ 'system_key ' => $ this ->getSystemKey (),
173+ 'consent_flow_enabled ' => (int ) Configuration::get ($ this ->getConfigName ('INVITE ' ), null , null , $ ps_shop_id ) == 3 ,
174+ 'consent_data ' => json_encode ([
175+ 'webshopId ' => $ webshop_id ,
176+ 'orderNumber ' => $ order ->id ,
177+ 'email ' => $ customer ->email ,
178+ 'firstName ' => $ customer ->firstname ,
179+ 'inviteDelay ' => (int ) Configuration::get ($ this ->getConfigName ('INVITE_DELAY ' ), null , null , $ ps_shop_id ),
180+ ]),
181+ ]);
182+ }
183+
184+ public function hookDisplayFooter ($ params ) {
179185 if (!Configuration::get ($ this ->getConfigName ('RICH_SNIPPET ' ))
180186 || !($ shop_id = Configuration::get ($ this ->getConfigName ('SHOP_ID ' )))
181187 || !ctype_digit ($ shop_id )
@@ -215,7 +221,7 @@ private function getRichSnippet($shop_id) {
215221 $ data = json_decode ($ json , true );
216222 } else {
217223 try {
218- $ json = $ this ->request ($ url , [
224+ $ json = $ this ->request ($ url , ' GET ' , [
219225 CURLOPT_CONNECTTIMEOUT => 2 ,
220226 CURLOPT_TIMEOUT => 4 ,
221227 ]);
@@ -354,22 +360,26 @@ private function sendInvites($ps_shop_id) {
354360 }
355361
356362 foreach ($ orders as $ order ) {
363+ if (
364+ Configuration::get ($ this ->getConfigName ('INVITE ' ), null , null , $ ps_shop_id ) == 3
365+ && !$ this ->hasConsent ($ order ['id_order ' ], $ ps_shop_id )
366+ ) {
367+ $ this ->markInviteAsSent ($ order ['id_order ' ]);
368+ PrestaShopLogger::addLog (
369+ sprintf ('Invitation was not created for order (%s) as customer did not consent ' , $ order ['id_order ' ]),
370+ );
371+ return ;
372+ }
373+
357374 $ invoice_address = $ this ->getOrderAddress ($ db , $ order ['id_address_invoice ' ])[0 ];
358375 $ delivery_address = $ this ->getOrderAddress ($ db , $ order ['id_address_delivery ' ])[0 ];
359- $ phones = array_unique (array_filter ([
360- $ invoice_address ['phone ' ],
361- $ invoice_address ['phone_mobile ' ],
362- $ delivery_address ['phone ' ],
363- $ delivery_address ['phone_mobile ' ],
364- ]));
365376
366377 $ post = [
367378 'email ' => $ order ['email ' ],
368379 'order ' => $ order ['id_order ' ],
369380 'delay ' => $ invite_delay ,
370381 'language ' => str_replace ('- ' , '_ ' , $ order ['language_code ' ]),
371382 'customer_name ' => $ order ['firstname ' ] . ' ' . $ order ['lastname ' ],
372- 'phone_numbers ' => $ phones ,
373383 'order_total ' => $ order ['total_paid ' ],
374384 'client ' => 'prestashop ' ,
375385 'platform_version ' => _PS_VERSION_ ,
@@ -412,8 +422,9 @@ private function sendInvites($ps_shop_id) {
412422 'code ' => $ api_key ,
413423 ]);
414424
415- $ response = $ this ->request ($ url , [
416- CURLOPT_POSTFIELDS => $ post ,
425+ $ response = $ this ->request ($ url , 'POST ' , [
426+ CURLOPT_POSTFIELDS => http_build_query ($ post ),
427+ CURLOPT_TIMEOUT => 10 ,
417428 ]);
418429
419430 $ data = json_decode ($ response , true );
@@ -426,7 +437,7 @@ private function sendInvites($ps_shop_id) {
426437 throw new RuntimeException ($ data ['message ' ]);
427438 }
428439
429- $ db -> execute ( " UPDATE ` { $ this ->getTableName ( ' orders ' )} ` SET { $ this -> getPluginColumnName ( ' invite_sent ' )} = 1 WHERE id_order = " . ( int ) $ order ['id_order ' ]);
440+ $ this ->markInviteAsSent ( $ order ['id_order ' ]);
430441
431442 PrestaShopLogger::addLog (sprintf (
432443 '%s: Requested invitation for order %s ' ,
@@ -469,7 +480,7 @@ private function getProductImage($product): string {
469480 return str_replace ('http:// ' , Tools::getShopProtocol (), $ context ->link ->getImageLink ($ product ->link_rewrite , $ img ['id_image ' ], 'home_default ' ));
470481 }
471482
472- public function hookBackofficeTop () {
483+ public function hookDisplayBackOfficeTop () {
473484 foreach (Shop::getCompleteListOfShopsID () as $ shop ) {
474485 $ this ->sendInvites ($ shop );
475486 }
@@ -497,9 +508,7 @@ public function getContent() {
497508 Configuration::updateValue ($ this ->getConfigName ('SHOP_ID ' ), trim ($ shop_id ));
498509 Configuration::updateValue ($ this ->getConfigName ('API_KEY ' ), trim ($ api_key ));
499510 Configuration::updateValue ($ this ->getConfigName ('SYNC_PROD_REVIEWS ' ), (bool ) Tools::getValue ('sync_prod_reviews ' ));
500- if (Configuration::get ($ this ->getConfigName ('SYNC_PROD_REVIEWS ' ))) {
501- $ this ->sendSyncUrl ();
502- }
511+ $ this ->sendSyncUrl ();
503512
504513 Configuration::updateValue (
505514 $ this ->getConfigName ('INVITE ' ),
@@ -533,9 +542,10 @@ public function getContent() {
533542 !!Tools::getValue ('limit_order_data ' )
534543 );
535544
536- $ this ->registerHook ('header ' );
537- $ this ->registerHook ('footer ' );
538- $ this ->registerHook ('backOfficeTop ' );
545+ $ this ->registerHook ('displayHeader ' );
546+ $ this ->registerHook ('displayFooter ' );
547+ $ this ->registerHook ('displayOrderConfirmation ' );
548+ $ this ->registerHook ('displayBackOfficeTop ' );
539549
540550 if (sizeof ($ errors ) == 0 ) {
541551 $ success = true ;
@@ -612,30 +622,22 @@ private function getPluginTableName($name) {
612622 return $ this ->getTableName ($ this ->getName () . '_ ' . $ name );
613623 }
614624
615- /**
616- * @param string $url
617- * @param array $options
618- * @return string
619- */
620- private function request ($ url , $ options = []) {
621- $ ch = curl_init ($ url );
622- if (!$ ch ) {
623- throw new RuntimeException ('curl_init failed ' );
624- }
625- $ options += [
625+ private function request (string $ url , string $ method , array $ options = []): string {
626+ $ default_options = [
627+ CURLOPT_URL => $ url ,
626628 CURLOPT_FAILONERROR => true ,
627629 CURLOPT_RETURNTRANSFER => true ,
628630 CURLOPT_FOLLOWLOCATION => true ,
631+ CURLOPT_CUSTOMREQUEST => $ method ,
629632 ];
630- if (!curl_setopt_array ($ ch , $ options )) {
631- throw new RuntimeException ('curl_setopt_array failed ' );
632- }
633+ $ ch = $ this ->getCurl ($ default_options + $ options );
634+
633635 $ response = curl_exec ($ ch );
634636 if ($ response === false ) {
635637 throw new RuntimeException (sprintf (
636638 'curl: (%s) %s ' ,
637639 curl_errno ($ ch ),
638- curl_error ($ ch )
640+ curl_error ($ ch ),
639641 ));
640642 }
641643 return $ response ;
@@ -649,4 +651,53 @@ private function render($__template, array $__scope) {
649651 return ob_get_clean ();
650652 })();
651653 }
654+
655+ private function getCurl (array $ options ) {
656+ if (!$ this ->curl ) {
657+ $ this ->curl = curl_init ();
658+ } else {
659+ curl_reset ($ this ->curl );
660+ }
661+
662+ if (!curl_setopt_array ($ this ->curl , $ options )) {
663+ throw new RuntimeException ('curl_setopt_array failed ' );
664+ }
665+
666+ if (!$ this ->curl ) {
667+ throw new RuntimeException ('curl_init failed ' );
668+ }
669+
670+ return $ this ->curl ;
671+ }
672+
673+ private function hasConsent (int $ order_id , int $ ps_shop_id ): bool {
674+ $ url = sprintf (
675+ self ::CONSENT_URL ,
676+ $ this ->getDashboardDomain (),
677+ http_build_query ([
678+ 'id ' => Configuration::get ($ this ->getConfigName ('SHOP_ID ' ), null , null , $ ps_shop_id ),
679+ 'code ' => Configuration::get ($ this ->getConfigName ('API_KEY ' ), null , null , $ ps_shop_id ),
680+ 'orderNumber ' => $ order_id ,
681+ ]),
682+ );
683+
684+ try {
685+ $ response_data = json_decode ($ this ->request ($ url , 'GET ' ), true );
686+ } catch (\Exception $ e ) {
687+ $ message = sprintf (
688+ 'Checking consent for order %s failed: %s ' ,
689+ $ order_id ,
690+ $ e ->getMessage (),
691+ );
692+ PrestaShopLogger::addLog ($ message );
693+ return false ;
694+ }
695+
696+ return $ response_data ['has_consent ' ] ?? false ;
697+ }
698+
699+ private function markInviteAsSent (int $ order_id ): void {
700+ $ db = Db::getInstance ();
701+ $ db ->execute ("UPDATE ` {$ this ->getTableName ('orders ' )}` SET {$ this ->getPluginColumnName ('invite_sent ' )} = 1 WHERE id_order = " . $ order_id );
702+ }
652703}
0 commit comments